2017-09-21 2 views
0

세션 당 websocket의 서버 측 닫기 이벤트를 처리 할 수있는 방법이 있습니까? 이것은 내가 현재 그것을 구현하는 방법입니다Websocket 서버 : 세션 당 닫기 이벤트 처리

@ServerEndpoint("/ws") 
public class WebsocketServerEndpoint { 
    @OnOpen 
    public void onOpen(Session session) { 
     System.out.println("Websocket opened"); 
     CustomWebsocketHandler handler = new CustomWebsocketHandler(session); // see below 
     // ... 
    } 

    @OnClose 
    public void onClose(Session session, CloseReason reason) { 
     System.out.println("Websocket closed. Reason: " + reason); 
    } 
} 

하지만 사용자 지정 개체 내에서 새로운 Session 인스턴스를 마무리하고자합니다. 메시지의 경우 처리기를 addMessageHandler을 통해 특정 세션에 직접 추가 할 수 있습니다. 하지만 특정 세션?에 onClose 이벤트에 대한 처리기를 추가 할 수있는 방법 내가 가진

class CustomWebsocketHandler { 
    public CustomWebsocketHandler(Session session) { 
     session.addMessageHandler((MessageHandler.Whole<String>) this::handleMessage); 
     // How to hook up close event to handleClose()? 
    } 

    private void handleMessage(String message) { /* ... */ } 

    private void handleClose() { /* ... */ } 
} 

하나의 아이디어는 모든 WebsocketServerEndpoint에서 세션 각각의 CustomWebsocketHandler 인스턴스를 추적하고, 모든 닫기 - 그들을 통해 이동했다 이벤트, 전달 이벤트. 그러나 이것은 매우 복잡하고 쉬운 오류 느낌 :

webSocketContainer.connectToServer(endpointInstance, websocketURI); 

합니까 : 각 연결은 ClientEndpoint -annotated 클래스의 자체 인스턴스를 사용할 수 있기 때문에,이 쉬운 사물의 클라이언트 측에서

@ServerEndpoint("/ws") 
public class WebsocketServerEndpoint { 
    private List<Pair<Session, CustomWebsocketHandler>> sessions = new ArrayList<>(); 

    @OnOpen 
    public void onOpen(Session session) { 
     // ... 
     sessions.add(Pair.of(session, handler)); // not hashable I suppose 
    } 

    @OnClose 
    public void onClose(Session session, CloseReason reason) { 
     // ... 
     for (Iterator<Pair<Session, CustomWebsocketHandler>> it = sessions.iterator(); it.hasNext();) { 
      Pair<Session, CustomWebsocketHandler> pair = it.next(); 
      if (pair.getLeft() == session) { 
       pair.getRight().handleClose(); 
       it.remove(); 
       break; 
      } 
     } 
    } 
} 

을 서버 쪽에서 비슷한 것이 있거나 서버 당 onClose (그리고 역시 onError) 이벤트를 세션별로 처리하는 것이 깔끔하게 가능합니까?

답변

0

기본값으로 새 클라이언트에 대해 ServerEndpoint 노예 링 된 클래스의 새 인스턴스가 만들어집니다. 이 동작은 ServerEndpointConfig.Configurator#getEndpointInstance 방법에 의해 제어되는이 방법의

플랫폼의 디폴트 구현함으로써 클라이언트 당 하나 개의 엔드 포인트 인스턴스, 기본 배포 기수가 있다는 것을 보장 호출 당 새로운 엔드 포인트 인스턴스를 반환합니다. 그것은 또한보다 쉽게 ​​할 수있는이 시점에서

@ServerEndpoint("/ws") 
public class WebsocketServerEndpoint { 
    private CustomWebsocketHandler handler; 

    @OnOpen 
    public void onOpen(Session session) { 
     handler = new CustomWebsocketHandler(session); 
    } 

    @OnClose 
    public void onClose(Session session, CloseReason reason) { 
     handler.handleClose(); 
    } 
} 

:

이것은 수동으로 연관 사용자 정의 연결 인스턴스가 세션을하지 않고도 WebsocketServerEndpoint 클래스 자체에 저장 세션 별 상태로 안전 것을 의미한다 주석 처리 된 클래스 WebsocketServerEndpoint이 필요합니다. CustomWebsocketHandler 자체는 동일한 의미를 갖기 때문에 연결 당 인스턴스 하나와 websocket 이벤트를 처리합니다.