web-dev-qa-db-ja.com

接続を閉じた後にwebsocketに再接続する方法

このコード(たとえば)でwebsocket接続を構築します:

var socket = new WebSocket("ws://94.12.176.177:8080");

そして、私はこれとの接続を閉じます:

socket.close();

しかし、どうすれば接続を再確立できますか?

私はいくつかの研究を行い、いくつかの方法を試しました。この質問は私を助けることができませんでした: Socket.ioは切断時に再接続しますか? これは私が探しているものに近い唯一の結果です。

これを行う理由は、ユーザーが一時的にWebにデータを送信するのを停止し、一定期間後に再送信することを許可するためです。再接続しないと、ユーザーは再送信するためにページを更新する必要があります。これにより、一部のデータが失われる可能性があります。ありがとうございました。

40
ket

再接続するには、ソケットを再作成する必要があります。それに関する唯一の問題は、ハンドラを再アタッチする必要があることです。

しかし、実際には、websocketはオープンのままになるように設計されています。

より良い方法は、サーバーが接続を閉じるにすることです。このようにして、websocketはoncloseイベントを発生させますが、接続を試行し続けます。サーバーが再びリッスンすると、接続が自動的に再確立されます。

14
Jivings

サーバーが接続を閉じると、クライアントは再接続を試みません。おそらくいくつかのJSフレームワークでは、この答えの時点で、質問は単純なVanilla JSとタグ付けされていました。

受け入れられ、支持された答えが明らかに間違っているので、私は少しイライラしています。正しい解決策を見つけるのに時間がかかりました。

ここにあります: WebSocketでサーバーが再起動するときのクライアントの再接続

64
SzG

このページで最適なソリューションを見つけました:sam-low.com

元の接続が閉じられたら、新しいイベントリスナーを使用して新しいWebSocketオブジェクトを作成する必要があります

_function startWebsocket() {
  var ws = new WebSocket('ws://localhost:8080')

  ws.onmessage = function(e){
    console.log('websocket message event:', e)
  }

  ws.onclose = function(){
    // connection closed, discard old websocket and create a new one in 5s
    ws = null
    setTimeout(startWebsocket, 5000)
  }
}

startWebsocket();
_

再接続に問題がある場合、新しいWebSocketオブジェクトはまだ別の終了イベントを受け取ります。つまり、onclose()は技術的に開かれていなくても実行されます。そのため、5秒の遅延は賢明です-これがないと、おそらく何かを壊す可能性のある速度で数千のWebソケット接続を作成して破壊することになります。

5
Pol

完璧な実装:

var socket;

const socketMessageListener = (event) => {
  console.log(event.data);
};

const socketOpenListener = (event) => {
  console.log('Connected');
  socket.send('hello');
};

const socketCloseListener = (event) => {
  if (socket) {
    console.error('Disconnected.');
  }
  socket = new WebSocket('ws://localhost:8080');
  socket.addEventListener('open', socketOpenListener);
  socket.addEventListener('message', socketMessageListener);
  socket.addEventListener('close', socketCloseListener);
};

socketCloseListener();

テストするには:

setTimeout(()=>{
  socket.close();
},5000);

編集:指数バックオフの実装に注意してください(トップコメントでリンクされたスレッドで: https://stackoverflow.com/a/37038217/880542 )、上記のコードではなく、非常に非常に重要です。

もう一度編集してください:backからprimusを確認してください: https://www.npmjs.com/package/back 、柔軟なセクシーな実装です。

3
xemasiv