Singleton Websockets object with various callback handlers

I have a JavaScript implementation of Websockets where I would like to use a singleton model that uses a single Websocket connection for multiple calls to the server, but with different callback event handlers. I have an implementation that works just fine, but noticed some weird behaviors with messages aimed at the wrong callback handler. Here is the code:

Connection.js File

var connection = function(){ var _socket = null; return { socket : function(){ if (_socket == null){ _socket = new WebSocket("ws://localhost:8081/index.ashx"); _socket.onclose = function(evt){alert('Closed');} _socket.extraParameter = null; } return _socket; }, send : function(data, callback){ var localSocket = connection.socket(); localSocket.extraParameter = new Date().toString(); localSocket.onmessage = callback; localSocket.originalDataSent = data; localSocket.send(data); } } }(); 

App.js File

 var App = function(){ return { cpuUtilization : function(evt){ var localSocket = this; var dateTimeOfRequest = localSocket.extraParameter; var originalDataSent = localSocket.originalDataSent var jsonData = $.parseJSON(evt.data); if ($.parseJSON(originalDataSent).type == "cpu"){ $("#dateTimeContainer").html(); $("#cpuContainer").html(jsonData.value); } } } }(); 

Third-Party Signal.js File

 var Signal = function(){ return { handlerProcess : function(evt){ // Does some third party stuff... } } }(); 

Using

 connection.send("{type:'process'}", Signal.handlerProcess); connection.send("{type:'cpu'}", App.cpuUtilization); connection.send("{type:'memory'}", Signal.handlerMemory); connection.send("{type:'harddrive'}", Signal.handlerHardDrive); 

Now that I think I see that the problem is that several requests are being executed through the same websocket, and the message is being returned. Since this is asynchronous, I cannot associate the request with an event callback. My solution uses the parameters in the handler for reference, but depending on the time it takes to complete the webcam request, the wrong callback handler is called and the process crashes. I think it fails because I am accessing the properties from the websocket instance, which can change between calls.

Is there a way to pass a link or additional parameters along with the evt parameter? Maybe wrap it up somehow?

+7
source share
1 answer

I think this is unsuccessful because I am accessing the properties from the websocket instance, which may vary between calls.

Yes.

Since this is asynchronous, I have no way to associate the request with an event callback.

Not. You can create a callback function closure instead of a call using callback directly:

 ... send: function(data, callback){ var localSocket = connection.socket(); var extraParameter = new Date().toString(); localSocket.onmessage = function(evt) { callback(evt.data, /* original- */ data, extraParameter); }; localSocket.send(data); } 

But still you have a changing onmessage callback handler. This means that an event can be dispatched to a handler that does not deserve it. Having an asynchronous system, you will need to add some of the information to the server’s response, which indicates which process the data belongs to. Then one universal message handler can resolve this and call the correct callback.

+7
source

All Articles