4

ページ ナビゲーションが発生する直前に Socket.io がメッセージを受信するという問題があります。通常、メッセージがナビゲーションによってトリガーされたサーバー側のアクションの直接の結果である場合です。

私が今見ているものは次のようになります:

  1. Socket.io 接続
  2. ユーザーがページ ナビゲーションをトリガーします (フォームの送信、更新など)。
  3. サーバー側のロジックが socket.io サーバーにリクエストを送信すると、まだ接続されているクライアントにイベントがすぐにディスパッチされます。
  4. クライアントはリクエストを受信して​​確認し (socket.io に組み込まれたメッセージの確認があると確信しています。間違っている場合は修正してください)、ユーザーに通知を表示しますが、その後 ...
  5. 元のページで socket.io 接続が閉じます
  6. 新しいページがロードされて表示されます
  7. Socket.io は新しい接続を開きますが、最後のメッセージが受信されて確認されたため、新しいメッセージはありません。

ナビゲーションが発生する前に Socket.io が接続を閉じることを期待するのは合理的ではないと思うので、これ自体は実際にはバグではありません。ただし、これを処理する最善の方法が何であるかはよくわかりません。現在、クライアントごとに一度に 1 つの接続を開いたままにし、新しい接続が接続されるともう 1 つの接続を閉じます。ただし、この場合は発生しません。これは、2 番目の接続が接続される前に最初の接続が閉じられているためです。すべてのクライアントのリストを保持することもできますが、それでも最初の接続でメッセージが受信されるため、この問題は解決しません。

ユーザーがメッセージの通知を常に確認できるようにする、この問題の解決策を誰かが提案できますか?

4

2 に答える 2

4

Socket.io は、独自のセッション ID で論理接続を追跡します。クライアントが接続したときにコンソールを見ると、ID が表示されます。

info  - handshake authorized Q9syoIK47JI7dACYpxiA

理解しておくべき重要なことは、これらの ID はページごとであり、HTTP セッションとは完全に分離されているということです。Socket.io クライアント ライブラリは、そのセッション ID を JavaScript 変数に保持するだけです。したがって、ナビゲーションの際、ID は明らかに失われます。

そのため、ナビゲーション時に次のことが起こります。

  1. ユーザーは sio session に接続されたページにいます1
  2. 新しいページへのナビゲーションを開始します。window.onbeforeunloadで、Socket.ioは同期 XHR 要求を開始して、サーバーに切断中であることを伝えます。成功した場合、セッション ( 1) はすぐに終了します。そうしないと、セッションは最終的にタイムアウトになります。
  3. 新しいページが読み込まれます。Socket.io サーバーに接続し、新しいセッション ID が割り当てられます2
  4. クライアントが session に接続されているため、 session に送信したもの1は明らかに配信されません2

Socket.io の基本機能では、ページ間を移動するユーザーと新しいユーザーを区別することはできません。いずれの場合も、ユーザーは新しい Socket.io セッションに接続します。

アプリがどのように機能するか、または何を達成しようとしているのかを正確に把握していなければ、問題を解決するための決定的な推奨事項を提示することは困難です。

おそらく、できるようにする必要があるのは、Socket.io セッションをユーザーのHTTP セッションに関連付けることです。通知をユーザーのセッションのキューに保存し、表示されたら削除できます。これには 2 つの方法があります。

  • ページ全体の読み込みを行っているため、キューに入れられた通知をページ自体と一緒に直接送信できます。正常にレンダリングされたら、キューを削除します。
  • 新しい Socket.io 接続で、未読通知をソケット経由で送信します。 コールバック関数を提供します。これは、 Socket.io.emitが提供する配信の確認です。配信が確認されたら、ユーザーの HTTP セッションから通知キューを削除できます。
于 2012-08-24T22:52:21.460 に答える
-1

最も簡単な解決策: onbeforeunloadイベントを使用して socket.io を切断します。

ブラウザーがリクエストを発行する前に (少なくとも Chrome で) このイベントが発生することを HTTP デバッガーで確認しました。

window.onbeforeunload = function() {
    socket.disconnect();
};

複数のブラウザーでこれをテストしていないため、完全な解決策ではない可能性がありますが、今のところ問題は解決しているようです。

于 2012-08-27T22:52:39.003 に答える