2012-06-20 16 views
7

Ho un'implementazione di Websockets JavaScript in cui vorrei utilizzare un modello singleton che utilizza una connessione Websocket per più chiamate al server ma con diversi gestori di eventi di callback. Ho l'implementazione che funziona bene, ma ho notato alcuni comportamenti strani con i messaggi indirizzati al gestore di callback sbagliato. Ecco il codice:Singleton Websockets oggetto con diversi gestori di callback

Connection.js il 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 del 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); 
      } 
     } 
    } 
}(); 

Terzi Signal.js

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

utilizzo

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

Ora dove penso di essere, il problema si verifica quando più richieste vengono fatte attraverso lo stesso websocket e il messaggio ritorna. Poiché questo è asincrono, non ho modo di legare la richiesta al callback dell'evento. La mia soluzione utilizza le opzioni nel gestore per riferimento, ma in base al tempo richiesto per l'esecuzione della richiesta Websocket, viene chiamato il gestore di callback errato e il processo non riesce. Penso che stia fallendo perché sto accedendo alle proprietà dall'istanza websocket che potrebbe cambiare tra le chiamate.

C'è un modo per passare un riferimento o parametri aggiuntivi insieme al parametro evt? Forse avvolgendo questo in qualche modo?

risposta

7

Penso che non funzioni perché sto accedendo alle proprietà dall'istanza websocket che potrebbe cambiare tra le chiamate.

Sì.

Poiché questo è asincrono, non ho modo di legare la richiesta al callback dell'evento.

No. È possibile creare una chiusura per la funzione di callback invece di chiamare usando callback direttamente:

... 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); 
} 

Ma ancora, si dispone di un gestore di callback onmessage cambiando. Ciò significa che un evento può essere inviato a un gestore che non lo merita. Avendo un sistema asincrono, sarà necessario aggiungere un'informazione alla risposta del server che indica a quale processo appartengono i dati. L'unico gestore di messaggi universale potrebbe risolvere ciò e chiamare il callback corretto.

+0

Grazie. Stavo solo dando per scontato che fosse così. Dovrò inventare un processo diverso. Penso che l'aggiunta di alcune informazioni alla risposta del server possa fare il lavoro con alcune modifiche minori sul codice client. Spero solo che ci fossero proprietà aggiuntive per l'evento onmessage che potrei usare per memorizzare alcuni dati temporanei. Grazie ancora e buona giornata – WalkSolutions