3

サーブレットの世界では、cookie や HttpSession のようなものがあり、リクエストを正しいデータにルーティングするために安静なサービスに誰がアクセスしたかを特定できます。クライアント接続を識別する Cookie であるかのように Sec-WebSocket-Key を使用することは良い考えですか?

具体的には、socko scala ライブラリ (netty ベースの akka Web サーバー) を使用して、socko -examplesのデモ アプリから始まる Websocket サーバーを実装しています。Socko は netty Channel をラップし、netty WebSocketFrame をアプリケーション コードに渡しています。次に、以前にエンド ユーザーのデータ (ショッピング バスケットなど) に関連付けたクライアント接続の「何らかの ID」に基づいて、着信データのフレームをディスパッチしたいと思います。これを行うために、元の websocket ハンドシェイクから http ヘッダーを掘り出すことによって、アプリケーションに入るオブジェクトの最上位のプロパティであるかのように、Sec-WebSocket-Key http ヘッダーを公開する拡張メソッドを作成しました。

package org.mashupbots.socko.examples.websocket

// pimp my library pattern to add extension method
object ChatWebSocketExtensions {
  import org.mashupbots.socko.events.WebSocketFrameEvent

  class WebSocketFrameEventWithSecWebSocketKey(wsFrame: WebSocketFrameEvent) {
    def secWebSocketKey: String = { 
      wsFrame.initialHttpRequest.headers.get("Sec-WebSocket-Key").getOrElse("null") 
    }
  }
  implicit def webSocketFrameEventWithSecWebSocketKey(wsFrame: WebSocketFrameEvent) = new WebSocketFrameEventWithSecWebSocketKey(wsFrame)

  import org.mashupbots.socko.events.WebSocketHandshakeEvent;

  class WebSocketHandshakeEventWithSecWebSocketKey(event: WebSocketHandshakeEvent) {
    def secWebSocketKey: String = {
      val option = Option(event.nettyHttpRequest.getHeader("Sec-WebSocket-Key"))
      return option.getOrElse("null");

    }
  }
  implicit def webSocketHandshakeEventWithSecWebSocketKey(event: WebSocketHandshakeEvent) = new WebSocketHandshakeEventWithSecWebSocketKey(event)

}

これは、Sec-WebSocket-Key ヘッダーを取得し、ファースト クラスのプロパティであるかのようにアクセスするために、アプリ コードが低レベルのオブジェクトを掘り下げる必要がないようにするための構文糖衣にすぎません。

  val routes = Routes({
    case WebSocketHandshake(wsHandshake) => wsHandshake match {
      case GET(PathSegments("websocket" :: roomNumber :: Nil)) => {
        log.info("Handsake to join room " + roomNumber)
        wsHandshake.authorize(onComplete = Some((event: WebSocketHandshakeEvent) => {
          val identity = event.secWebSocketKey;
          log.info("Authorised connection:" + identity);
          // do something with this identified user connection
        }))
      }
    }

    case WebSocketFrame(wsFrame) => {
      // Once handshaking has taken place, we can now process frames sent from the client
      val identity = wsFrame.secWebSocketKey;
      log.info("chat from:" + identity);
      // do something with this identified data frame
    }

  })

私の質問は、これが良い方法なのか、それともユーザー接続を識別するためのより良い方法があるのか​​ということです.

4

1 に答える 1

6

「Sec-WebSocket-Key」は接続を識別します。

ただし、「セッション」を識別するために「Sec-WebSocket-Key」を使用することが良いアイデアであるかどうかはよくわかりません。

これは、'Sec-WebSocket-Key' が、接続が切断され、クライアントが新しい接続を確立する必要があるシナリオに対応していないためです。新しい「Sec-WebSocket-Key」が発行される場合があります。ユーザーは自分のセッションを失います。

HTTP では、セッションは通常、URL 内の Cookie または ID に関連付けられます。どちらも HTTP 接続とは無関係です。このようにして、複数の HTTP 接続を 1 つのユーザー セッションに使用できます。

Web ソケットの「セッション」にも同様のものを使用することをお勧めします。

ハンドシェイクとログインの成功の一環として、サーバーからクライアントにセッション ID を送信してもらいます。クライアントは、リクエストごとにセッション ID をサーバーに送り返す必要があります。

このようにして、https://github.com/joewalnes/reconnecting-websocketのような JavaScript を使用して、アプリケーション コードにネットワークの復元力を提供できます。

お役に立てれば。

于 2013-09-24T22:30:42.447 に答える