8

JavaScript Websocketの実装があり、サーバーへの複数の呼び出しに1つのWebsocket接続を使用するが、コールバックイベントハンドラーが異なるシングルトンモデルを使用したいと考えています。実装は正常に機能していますが、メッセージが間違ったコールバックハンドラーに送信されるという奇妙な動作に気づきました。ここにいくつかのコードがあります:

Connection.jsファイル

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ファイル

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

サードパーティのSignal.jsファイル

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

利用方法

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

ここで問題が発生しているのは、同じWebSocketを介して複数のリクエストが行われ、メッセージが返される場合です。これは非同期であるため、リクエストをイベントコールバックに関連付ける方法がありません。私のソリューションでは、ハンドラーのオプションを参照用に使用していますが、WebSocketリクエストの実行にかかる時間によっては、間違ったコールバックハンドラーが呼び出され、プロセスが失敗します。呼び出し間で変更される可能性のあるWebSocketインスタンスからプロパティにアクセスしているため、失敗していると思います。

evtパラメーターと一緒に参照または追加のパラメーターを渡す方法はありますか?多分これをどうにかして包む?

4

1 に答える 1

9

呼び出し間で変更される可能性のあるWebSocketインスタンスからプロパティにアクセスしているため、失敗していると思います。

はい。

これは非同期であるため、リクエストをイベントコールバックに関連付ける方法がありません。

callbackいいえ。直接使用して呼び出す代わりに、コールバック関数のクロージャを作成できます。

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

しかし、それでも、onmessageコールバックハンドラーが変更されています。つまり、イベントは、それに値しないハンドラーに送信される可能性があります。非同期システムを使用している場合は、データがどのプロセスに属しているかを示す情報をサーバーの応答に追加する必要があります。1つのユニバーサルメッセージハンドラーがそれを解決し、適切なコールバックを呼び出すことができます。

于 2012-06-20T20:18:20.950 に答える