How to connect client and server with socket? - sockets

How do I actually run this client/server project on ActionScript 3? I'm using flashbuilder. I'm not sure if I'm even doing the right thing, i made a new as mobile project and put in the code for my client which is this:
public class client extends Sprite
{
private var socket:Socket;
private var IP:String = "127.0.0.1";
public function client()
{
super();
socket = new Socket();
socket.addEventListener(Event.CONNECT, onConnected);
socket.connect(IP, 5555);
}
protected function onConnected(event:Event):void
{
socket.writeUTFBytes("communication between Sockets (Client socket and server socket)");
socket.flush();
}
}
and then I made a new class within the package that has the client class (as above) in it and put in this as the server class:
public class NewSocketServerTest extends Sprite
{
private var serverSocket:ServerSocket = new ServerSocket();
private var clientSocket:Socket;
private var txt:TextField;
public function NewSocketServerTest()
{
createUI();
serverSocket.bind(5555);
serverSocket.addEventListener(ServerSocketConnectEvent.CONNECT, onConnected);
serverSocket.listen();
}
protected function onConnected(event:ServerSocketConnectEvent):void
{
txt.appendText("This is a demonstration of \n" );
clientSocket = event.socket;
clientSocket.addEventListener(ProgressEvent.SOCKET_DATA, onDataHandler);
}
protected function onDataHandler(event:ProgressEvent):void
{
var str:String = clientSocket.readUTFBytes(clientSocket.bytesAvailable);
txt.appendText(str);
}
private function createUI():void
{
txt = new TextField();
txt.width=400;
txt.height=400;
txt.appendText("Hello! \n");
addChild(txt);
}
}
When I try run this in an emulator it's just a white screen and I'm not sure what I'm doing wrong.

Try specifying the serverSocket hostname.
serverSocket.bind(5555,"127.0.0.1");

Related

UDP Client - how to close after BeginReceive

I need to receive small UDP packets from within my ERP system (Dynamics Nav). I created a class with some code from the internet (first time I use code for UDP), added a COM interface and use the resulting DLL within Nav. It worked right away, but I realized that the udp.Close() function did not really close the thing, and I couldn´t instantiate the class a second time.
After looking at many topics about udp.BeginReceive() at stackoverflow and on other sites, I understand the reason for that. There needs to be a final udp.EndReceive call before closing the upd object.
Since the class is running in the background its using a callback function defined by udp.BeginReceive. The callback function then gets the data by calling udp.EndReceive and finally stores it to a string. Nav can retrieve that string whenever it wants that data trough a simple property.
public string GetMessage { get { return(message); } }
public void Start()
{
udp = new UdpClient(PORT_NUMBER);
StartListening();
}
public void Stop()
{
udp.Close();
}
private void StartListening()
{
ar_ = udp.BeginReceive(Receive, new object());
}
private void Receive(IAsyncResult ar)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, PORT_NUMBER);
byte[] bytes = udp.EndReceive(ar, ref ip);
message = Encoding.ASCII.GetString(bytes);
StartListening();
}
Everthing is fine, except ...
Nav calls Start() which issues StartListening(), which defines the callback function. After receiving the data through udp.EndReceive it calls StartListening() again - this part is working fine.
As soon, as Nav calls the Stop() function however, the trouble starts, and I understand that this is, bacause there is no final call to EndReceive and thus an open session.
One may say, why don´t do an EndReceive() within the Stop() function before udp.Close()? Well, because I couldn´t find the correct parameters for that call.
Actually I do have a working class. I don´t try to close the session within the Stop() function but instead set a bool variable. The next time the callback function is issued, depending on that bool it doesn´t do a StartListening() but a upd.CLose() instead. And finally, to make sure there will be data to issue the callback function, I call my Send() function sending some single character.
While the following code is working perfectly, I know it´s kind of crazy:
public string GetMessage { get { return(message); } }
public void Start()
{
active = true;
udp = new UdpClient(PORT_NUMBER);
StartListening();
}
public void Stop()
{
active = false; // force callback function to close session
Send("x"); // issue callback function ... crazy
//udp.Close();
}
private void StartListening()
{
ar_ = udp.BeginReceive(Receive, new object());
}
private void Receive(IAsyncResult ar)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, PORT_NUMBER);
byte[] bytes = udp.EndReceive(ar, ref ip);
message = Encoding.ASCII.GetString(bytes);
if (active) StartListening(); else udp.Close();
}
Does anyone have a hint how to issue EndReceive() within my Stop() function before calling udp.Close()?
Thanks in advance
Michael
I recently found a solution just by using a Thread() instead of the async receive - works perfectly so far:
public class Bos_UDP
{
private UdpClient udp;
const int PORT_NUMBER = 15000;
private String message = "";
public Thread receiveThread;
public string GetMessage { get { return(message); } }
public void Start()
{
udp = new UdpClient(PORT_NUMBER);
receiveThread = new Thread(ThreadReceive);
receiveThread.Start();
}
public void Stop()
{
receiveThread.Abort(new object());
udp.Close();
}
public void ThreadReceive()
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, PORT_NUMBER);
while (true)
{
var data = udp.Receive(ref ip);
message = Encoding.Default.GetString(data);
}
}
public void Send(string message)
{
UdpClient client = new UdpClient();
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("255.255.255.255"), PORT_NUMBER);
byte[] bytes = Encoding.ASCII.GetBytes(message);
client.Send(bytes, bytes.Length, ip);
client.Close();
}
}

Xamarin - Socket IO issue

I have to make a chat for a Xamarin Forms (PCL) application. I'm using the NuGet package SocketIoClientDotNet for socket.
At first I could not connect at all. After many researches on internet I found this open issue on Github, so I downgraded the library but also all the dependencies:
EngineIOClient.Net V0.9.22
SocketIOClientDotNet V0.9.13
WebSocket4Net V0.14.1.0
It was better, the connection seemed to work but I encountered a new issue: the connection is very instable and it's difficult for me to test anything cause of that. One time it can connect multiple times, one time it not connect at all, it's very annoying...
My code is very simple:
Common Code:
ISocketIO interface:
public interface ISocketIO
{
void Connect(string url);
void On(string eventString, Action<object> action);
}
MsgService class:
readonly string EVENT_CONNECT = "connect";
public MsgService(ISocketIO socket)
{
Socket = socket;
if (Socket != null)
{
Socket.On(EVENT_CONNECT, () =>
{
(code here...)
});
}
}
public void Connect()
{
if (Socket != null)
{
Socket.Connect("chat_url_here");
}
}
App class:
public partial class App : Application
{
public static MsgService MsgService;
public App(ISocketIO socket)
{
InitializeComponent();
Language = Language.FRENCH;
MsgService = new MsgService(socket);
MsgService.Connect();
MainPage = new NavigationPage(new MainPage());
}
...
}
iOS code (same for Android):
Class SocketIO
[assembly: Xamarin.Forms.Dependency(typeof(SocketIO))]
namespace MeetYou.iOS
{
public class SocketIO : ISocketIO
{
Socket _socket;
public void Connect(string url)
{
IO.Options opt = new IO.Options
{
Path = "path_here"
};
_socket = IO.Socket(url, opt);
_socket.Connect();
}
}
}
AppDelegate:
[Register("AppDelegate")]
public class AppDelegate : Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication uiApplication, NSDictionary launchOptions)
{
Xamarin.Forms.Forms.Init();
LoadApplication(new App(new SocketIO()));
return base.FinishedLaunching(uiApplication, launchOptions);
}
}
Maybe I'm doing something wrong of maybe it exists an other plugin I could use instead this one.
Have you tried running this without this line?
_socket.Connect();
I managed to make my example work in my application only using the
_socket = IO.Socket("wss://" + HostUrl + "/");

Disconnect client from IHubContext<THub>

I can call InvokeAsync from server code using the IHubContext interface, but sometimes I want to force these clients to disconnect.
So, is there any way to disconnect clients from server code that references the IHubContext interface?
Step 1:
using Microsoft.AspNetCore.Connections.Features;
using System.Collections.Generic;
using Microsoft.AspNetCore.SignalR;
public class ErrorService
{
readonly HashSet<string> PendingConnections = new HashSet<string>();
readonly object PendingConnectionsLock = new object();
public void KickClient(string ConnectionId)
{
//TODO: log
if (!PendingConnections.Contains(ConnectionId))
{
lock (PendingConnectionsLock)
{
PendingConnections.Add(ConnectionId);
}
}
}
public void InitConnectionMonitoring(HubCallerContext Context)
{
var feature = Context.Features.Get<IConnectionHeartbeatFeature>();
feature.OnHeartbeat(state =>
{
if (PendingConnections.Contains(Context.ConnectionId))
{
Context.Abort();
lock (PendingConnectionsLock)
{
PendingConnections.Remove(Context.ConnectionId);
}
}
}, Context.ConnectionId);
}
}
Step 2:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddSingleton<ErrorService>();
...
}
Step 3:
[Authorize(Policy = "Client")]
public class ClientHub : Hub
{
ErrorService errorService;
public ClientHub(ErrorService errorService)
{
this.errorService = errorService;
}
public async override Task OnConnectedAsync()
{
errorService.InitConnectionMonitoring(Context);
await base.OnConnectedAsync();
}
....
Disconnecting without Abort() method:
public class TestService
{
public TestService(..., ErrorService errorService)
{
string ConnectionId = ...;
errorService.KickClient(ConnectionId);
In alpha 2 there is the Abort() on HubConnectionContext you could use to terminate a connection. I don't see, however, an easy way to access it from outside the hub.
Because you control the clients you could just invoke a client method and tell the client to disconnect. The advantage is that the client disconnect gracefully. The disadvantage is that it requires sending the message to the client instead of disconnecting the client solely on the server side.

Testing code in a custom NancyFx Bootstrapper

I have a custom Nancy Bootstrapper which uses StructureMapNancyBootstrapper but the issue is the same regardless of container.
public class CustomNancyBootstrapper : StructureMapNancyBootstrapper
{
protected override void RequestStartup(IContainer container, IPipelines pipelines, NancyContext context)
{
var auth = container.GetInstance<ICustomAuth>();
auth.Authenticate(context);
}
}
I want to write a test to assert that Authenticate is called with the context... something like this...
[Test]
public void RequestStartup_Calls_CustomAuth_Authenticate_WithContext()
{
// set up
var mockAuthentication = new Mock<ICustomAuth>();
var mockContainer = new Mock<IContainer>();
var mockPipelines = new Mock<IPipelines>();
var context = new NancyContext();
mockContainer.Setup(x => x.GetInstance<ICustomAuth>()).Returns(mockAuthentication.Object);
// exercise
_bootstrapper.RequestStartup(_mockContainer.Object, _mockPipelines.Object, context);
// verify
mockAuthentication.Verify(x => x.Authenticate(context), Times.Once);
}
The problem is that I can't call RequestStartup because it's protected as defined in NancyBootstrapperBase.
protected virtual void RequestStartup(TContainer container, IPipelines pipelines, NancyContext context);
Is there a "proper"/"offical" Nancy way to do this without creating another derived class and exposing the methods as that just seems like a hack?
Thanks
I guess you can "fake" the request by using Browser from Nancy.Testing:
var browser = new Browser(new CustomNancyBootstrapper());
var response = browser.Get("/whatever");
There is a good set of articles about testing NancyFx application:
http://www.marcusoft.net/2013/01/NancyTesting1.html
Turns out Nancy offers a IRequetStartup interface so you can take the code out of the custom bootstrapper and do something like this...
public class MyRequestStart : IRequestStartup
{
private readonly ICustomAuth _customAuthentication;
public MyRequestStart(ICustomAuth customAuthentication)
{
if (customAuthentication == null)
{
throw new ArgumentNullException(nameof(customAuthentication));
}
_customAuthentication = customAuthentication;
}
public void Initialize(IPipelines pipelines, NancyContext context)
{
_customAuthentication.Authenticate(context);
}
}
and the test is easy and concise
[Test]
public void When_Initialize_Calls_CustomAuth_Authenticate_WithContext()
{
// set up
var mockAuth = new Mock<ICustomAuth>();
var requestStartup = new MyRequestStart(mockAuth.Object);
var mockPipeline = new Mock<IPipelines>();
var context = new NancyContext();
// exercise
requestStartup.Initialize(mockPipeline.Object, context);
// verify
mockAuth.Verify(x => x.Authenticate(context), Times.Once);
}
https://github.com/NancyFx/Nancy/wiki/The-Application-Before%2C-After-and-OnError-pipelines#implementing-interfaces

Processing within Eclipse: initializing a Client

I am working on a Processing program within Eclipse and I am having issues initializing the Client object. I have properly imported both core.jar and net.jar from the Processing package into my class from these locations:
C:\Program Files\eclipse\processing-2.0.2\core\library
C:\Program Files\eclipse\processing-2.0.2\modes\java\libraries\net\library\net.jar
public class Client extends PApplet {
private static final long serialVersionUID = 0L;
// Declare a client
Client client;
public void setup() {
size(400, 200);
// create the client
client = new Client(this, "127.0.0.1", 8888);
}
}
The line Eclipse is complaining about (client = new Client(this, "127.0.0.1", 8888) shows an error: the constructor Client(Client, String, int) is undefined.
Per the Client API, there is a constructor that takes those arguments: http://processing.org/reference/libraries/net/Client.html.
I have also tried client = new Client(this, 8888); and Eclipse is still complaining about an error. Can anyone help guide me on how to resolve this? Thanks.
Your class is called Client so the new Client in your code is trying to create an instance of your class. What you actually want is an instance of processing.net.Client. It would be best to use a different name for you class:
import processing.net.Client;
public class MyApplet extends PApplet {
private static final long serialVersionUID = 0L;
// Declare a client
Client client;
public void setup() {
size(400, 200);
// create the client
client = new Client(this, "127.0.0.1", 8888);
}
}
I have changed the class name to MyApplet.