2

xhr を唯一のトランスポートとして使用する socket.io 接続があります。ブラウザーでアプリをロードすると (chrome と ff でテスト済み)、ソケットが接続され、ページから移動するまですべてが正常に機能します。ブラウザをリロードすると、「disconnect」イベントがクライアントから送信されていることがわかりますが、サーバーの切断イベントは非常に長い間発生しません (おそらくクライアントのハートビートがタイムアウトしたとき)。クライアントが切断されたときにサーバーでいくつかのクリーンアップ作業を行うため、これは問題です。クライアントがリロードすると、切断が発生する前に複数の接続イベントが発生します。ウィンドウの「beforeunload」イベントでもクライアントから手動で切断メッセージを発行しようとしましたが、役に立ちませんでした。何か案は?

socket.io サーバーをデバッグしたところ、Manager.prototype.onClientDisconnect が「クローズ タイムアウト」の理由でのみヒットしていることを確認できました。

4

1 に答える 1

3

さらにデバッグを行った後、socket.io Manager オブジェクトに次の構成があることに気付きました。

blacklist : ['disconnect']

これにより、namespace.js からのこのブランチはイベントを処理しません。

case 'event':
  // check if the emitted event is not blacklisted
  if (-~manager.get('blacklist').indexOf(packet.name)) {
    this.log.debug('ignoring blacklisted event `' + packet.name + '`');
  } else {
    var params = [packet.name].concat(packet.args);

    if (dataAck) {
      params.push(ack);
    }

    socket.$emit.apply(socket, params);
}

この変更は、このプル リクエストhttps://github.com/LearnBoost/socket.io/pull/569で詳しく説明されています。誰でもランダムなセッション ID を使用して HTTP リクエストを送信し、他のユーザーをサーバーから切断しようとする可能性があるため、これが XHR に適している理由を理解しています。

代わりに、新しい接続ごとにサーバー内の既存のセッション ID を確認し、接続ロジックを続行する前に切断ロジックを実行するようにします。

于 2012-05-24T19:37:39.937 に答える