This project is read-only.

Synchronous call

May 25, 2012 at 12:25 AM

Am I able to create a synchronous call to the socket.io server using emit or some mechanism so that I forcibly wait for the result from a specific send to generate a response from the server?

 

Coordinator
May 25, 2012 at 3:02 AM

Indirectly, you could, but there are no specific methods available for synchronous messages or blocking callbacks.  I wouldn't recommend going down that path, and suggest you really think about why you'd want to block for a specific event to occur as opposed to a simple event or callback pattern.

There are callbacks available for any given message, its a great technique to get feedback from the sever when it has processed the message request:

public void CallbackExample()
{
	Console.WriteLine("Emit [socket].[messageAck] - should recv callback [root].[messageAck]");
	socket.Emit("messageAck", new { hello = "mama" }, null,
		(callback) =>
		{
			var jsonMsg = callback as JsonEncodedEventMessage; // callback will be of type JsonEncodedEventMessage, cast for intellisense
			Console.WriteLine(string.Format("callback [root].[messageAck]: {0} \r\n", jsonMsg.Args));
		});
}

If you do try to go down the path of a blocking call - ensure you are not blocking the same thread socketio4net.client is running on, or you will never receive the message your waiting for!  

May 30, 2012 at 4:00 AM

Thanks for the info, a callback will work much better than what I was trying to do, but I'm having trouble getting the callback to fire.

I emit a generic "message" type from the socket.io server when the "message" emit is received from the code below, and my socket.on("message", fn( code fires correctly on the result of that socket.io emit, but the callback does not fire.  Am I doing something stupid?:

            _socket.Emit("message",
             new CommMessage
             {
                 Target = "All",
                 Function = action,
                 Params = parameters,
                 AppDomain = _uniqueId,
                 SynchId = id
             }, "",
            (callback) =>
            {
                var jsonMsg = callback as JsonEncodedEventMessage; // callback will be of type JsonEncodedEventMessage, cast for intellisense

                value.SynchId = jsonMsg.Args[0].SynchId;
                value.Function = jsonMsg.Args[0].Function;
                value.Params = jsonMsg.Args[0].Params;

            });

 

Coordinator
May 30, 2012 at 4:32 AM

Can you also paste the node/socket.io side with your socket.on("message"... code, I'd like to see how your are invoking the callback itself.

May 30, 2012 at 6:28 AM

Sure, in nodejs I have the follow code that emits.  You'll have to fill in the gaps a little, I have a series of callback pointers referenced by function name that called based on the message from the server.  In this case it's whatever is in action from the previous post.

 

sio.sockets.on 'connection', ((socket) ->
	###
	When a message is received, call the requested method
	passing in the socket and data from the etp server making the request
	###
	debuglog('Connection established');
	
	socket.on 'message', ((data) ->
		Callbacks.Call sio, data.Function, socket, data
	)

	socket.on 'disconnect', (() ->
		debuglog('Disconnecting app domain[' + socket.AppDomain + ']')
  )
)

// This is the Callbacks object Call method from the above piece

	Call: (sio, methodName, socket, data) ->
		method = @delegates[methodName]
		debuglog count + ', Call:' + methodName
		if method != undefined
			method.call(this, sio, socket, data)
		else
			Callbacks.prototype.PassMethodToAllSocketsExceptSelf.call(this, sio, socket, data)

// This is the method being called in my test code from delegates[]
	GetConnectedAppDomains: (sio, socket, data) ->
		clients = sio.sockets.clients()
		servers={}
		_.each(clients, (s, i) ->
			servers[s.AppDomain] = { Version: s.Version, URI: s.URI }
		)
		debuglog servers
		socket.emit 'message', {Function:data.Function, Params:servers, SynchId: data.SynchId}

 

Coordinator
May 30, 2012 at 1:20 PM
Edited May 30, 2012 at 1:21 PM

It seems to me your missing the callback function parameter in your socket.on 'message' handler.  Your taking in 'data' as the only parameter passed from the event call.  You can see more info from the socket.io documentation page at getting-acknowledgements

I'm only vaguely familiar with coffeescript, but I think it should look more like:

 

socket.on "message", (data, callback) ->
  callback "return me"

 

Where 'callback' represents the callback function your trying to invoke back on the client.


Take a closer look at the sample from my demos - and see if this helps...

C# Client Code:

 

public void CallbackExample()
{
	Console.WriteLine("Emit [socket].[messageAck] - should recv callback [root].[messageAck]");
	socket.Emit("messageAck", new { hello = "mama" }, null,
		(callback) =>
		{
			var jsonMsg = callback as JsonEncodedEventMessage; // callback will be of type JsonEncodedEventMessage, cast for intellisense
			Console.WriteLine(string.Format("callback [root].[messageAck]: {0} \r\n", jsonMsg.Args));
		});
}

 

 

nodejs / socket.io Server Code:

 

socket.on('messageAck', function (data, fn) {
	console.log('[root].[messageAck]: {0}'.format(JSON.stringify(data)));

	if (fn != 'undefined') {
		console.log('  sending ack message \r\n');
		fn('hello son, {0}'.format(data.hello)); // return payload
	}
	else {
		console.log(' ** expecting return function to call, but was missing?');
	}
});

 

 

(or in coffeescript):

 

socket.on "messageAck", (data, fn) ->
  console.log "[root].[messageAck]: {0}".format(JSON.stringify(data))
  unless fn is "undefined"
    console.log "  sending ack message \r\n"
    fn "hello son, {0}".format(data.hello)
  else
    console.log " ** expecting return function to call, but was missing?"

 

Jun 7, 2012 at 1:18 AM

Yes, you were absolutely right.  I did not understand the structure of the parameters passed in via the socket.on interface, and assumed the callback would be part of the data payload.

I am now able to receive the call from the server (via a very similar method to the one you have defined above.  I am finding, however, that occasionally, under circumstances unknown to me, the message is sent from the c# code, with a callback, as defined in CallbackExample, and the server receives the message, and makes the callback call, but the call is never received in the c# client.  Examining the output in debug mode in this situation no receive message is received by the underlying socket infrastructure, either.

Any thoughts, and thank you for your assistance?

 

Coordinator
Jun 13, 2012 at 2:04 PM

We need to find out if the data is physically being sent, or if the client is not picking up the data receive event itself?  Do you have similar client code in javascript you can run in a browser - and does it exhibit the same behavior?