1

次の動作を実現したいと思います。Websocket 経由でメッセージを送信する関数をトリガーするボタンがクライアント側にあるとします。この関数が初めて呼び出されると、WebSocket インスタンスが作成され、その後の呼び出しで使用されます。

WebSocket インスタンスの作成はノンブロッキングです。コンストラクターはすぐに WebSocket オブジェクトを返し、バックグラウンドでハンドシェイクを開始します。接続が成功すると、onopen コールバックがトリガーされます。

2 番目の呼び出しが着信し、websocket がまだハンドシェイクを実行している場合 (たとえば、ユーザーがボタンをダブルクリックした場合) に問題が発生します。Websocket がハンドシェイクを完了すると、すべてのメッセージがキューに入れられて送信される必要があります。

次のコードでは、jQuery とカスタム イベントを使用して、ハンドシェイク中に受信したすべてのメッセージを収集します。

var ws = null;

function sendMessage(message) {
    if (!ws) {
        ws = new WebSocket("ws://example.com");
        ws.onopen = function() {
            $(document).trigger('handshakeComplete');
        }
    }
    if (ws.readyState == WebSocket.CONNECTING) { // *
            $(document).bind('handshakeComplete', message, function(event) {
                ws.send(event.data);
            });
    } else if (ws.readyState == WebSocket.OPEN) {
        // use the persistent connection
        ws.send(message);
    }
}

スター付きの行の条件が true として評価される可能性があり、その瞬間に Websocket が OPEN 状態に移行すると、onopen コールバックが実行され、その後でのみ現在のメッセージがキューに追加され、handshakeComplete イベントを待機します。これにより、メッセージが失われます。

私はこれを避けたいと思います。アイデア、コメント、または提案をいただければ幸いです。

4

1 に答える 1

0

テスト(== CONNECTING)とbind()が発生するまでの間に、handshakecompleteが起動し、handshakecompleteのメッセージが送信されないのではないかと心配していると思います。

理論的には、存在するものがすべてJSである場合、現在のコードが終了するまでイベントは発生しないため、これは間違っています。ただし、実際には、イベントはバックグラウンドの別のスレッドで生成され、安定した状態に達した後にフォアグラウンドで実行されるだけです。

答えは、ハンドシェイクイベントハンドラーにメッセージを埋め込まないことです。メッセージをキュー/配列に追加し、onopenハンドラーで配列を処理することをお勧めします。onopenイベントは、実行中に発生(キューに入れられる)する可能性がありますが、安定した状態(すべてのメッセージがキュー/配列にある)に達するまで実行されません。

于 2012-05-01T18:43:03.583 に答える