2013-08-14 2 views
2

서블릿 세계에는 요청한 정보를 올바른 데이터로 라우팅하기 위해 내게 안성맞춤 인 서비스를 누리고있는 사람을 식별 할 수있는 쿠키와 HttpSession과 같은 것이 있습니다. Sec-WebSocket-Key를 클라이언트 연결을 식별하는 쿠키 인 것처럼 사용하는 것이 좋습니다.Secs-WebSocket-Key를 사용하여 websocket 클라이언트 연결을 식별하는 것이 좋습니다.

구체적으로 말하면 데크 응용 프로그램 (socko-examples)에서 시작하는 websocket 서버를 구현하기 위해 socko scala 라이브러리 (netty 기반 akka 웹 서버)를 사용하고 있습니다. Socko는 netty Channel을 래핑하고 WebSocketFrame을 애플리케이션 코드에 전달합니다. 그런 다음 이전에 최종 사용자 데이터 (예 : 쇼핑 바구니)에 연결된 클라이언트 연결에 대한 "일부 ID"를 기반으로 들어오는 데이터 프레임을 발송하려고합니다. 이렇게하려면 Secs-WebSocket-Key http 헤더를 원래 websocket 핸드 셰이크의 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) 

} 

그게 일부 문법 설탕 응용 프로그램 코드는 초 - 웹 소켓 - 키 헤더를 얻고 그것은 1 급 호텔 것처럼 그냥 액세스 할 낮은 수준의 객체에 주위 파고 갈 필요가 없습니다 않도록 :

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 
    } 

    }) 

제 질문은 이것이 좋은 관행인지 또는 사용자 연결을 식별하는 더 나은 방법이 있습니까?

+0

나는 코드가 아니라 문언을 읽었다. 나는 비슷한 해결책을 찾고있다. 궁금하네요, 세션 관리 Tomcat 등 HTTP 헤더를 통해 바로 이루어집니다? 어쩌면 그게 활용 될 수 있을까요? –

+0

아직 socko에 대한 포럼이 없습니다. https://github.com/mashupbots/socko/issues/62의 문제 추적기에서이 질문을 지적하고 있습니다. – simbo1905

답변

4

'Sec-WebSocket-Key'는 연결을 식별합니다.

그러나 'Sec-WebSocket-Key'를 사용하면 "세션"을 식별하는 데 좋은 아이디어인지 확실하지 않습니다.

이것은 'Sec-WebSocket-Key'가 연결이 끊어지고 클라이언트가 새 연결을 설정해야하는 시나리오를 수용하지 않기 때문입니다. 새로운 'Sec-WebSocket-Key'가 발행 될 수 있습니다. 사용자는 자신의 세션을 잃어 버릴 것입니다.

HTTP의 경우 세션은 일반적으로 HTTP 연결과 독립적 인 URL의 쿠키 또는 ID와 연결됩니다. 이 방법으로 단일 사용자 세션에 대해 여러 개의 HTTP 연결을 사용할 수 있습니다.

웹 소켓 "세션"에 대해 비슷한 것을 사용하는 것이 좋습니다.

손을 흔들어 성공한 ​​로그인의 한 부분으로 서버가 클라이언트에게 세션 ID를 보내도록하십시오. 클라이언트는 각 요청과 함께 세션 ID를 서버로 다시 보내야합니다.

이렇게하면 https://github.com/joewalnes/reconnecting-websocket과 같은 javascript를 사용하여 응용 프로그램 코드에 네트워크 복원성을 제공 할 수 있습니다.

희망이 도움이됩니다.

관련 문제