2011-07-22 8 views
1

以下の動作を達成したいと思います。 Websocket経由でメッセージを送信する関数を起動するボタンがクライアント側にあるとします。この関数が初めて呼び出されると、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); 
    } 
} 

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

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

+0

接続をネゴシエートしている間、または常に同じメッセージ(同じボタンを2回クリックして)を送信しないようにしたいですか? –

+0

私は何のメッセージも送信しないようにしようとしていません。メッセージが、ボタンがクリックされたときのタイムスタンプであるとします。上記のコードスニペットでは、すべてのメッセージが送信されることを保証するものではありません。 – fmoga

+0

私はあなたの問題をよく理解していません。メッセージはいつ破棄されますか?あなたのコードリストの下であなたの段落をちょっと言い直してください。 – pimvdb

答えて

0

あなたは、テスト(== CONNECTING)とbind()の間でハンドシェイクコンプリートが発生し、ハンドシェイク完了のメッセージが送信されないことを心配していると思います。

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

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

関連する問題