【问题标题】:how to capture connection event in my webSocket server with Spring 4?如何使用 Spring 4 在我的 webSocket 服务器中捕获连接事件?
【发布时间】:2014-03-13 22:48:30
【问题描述】:

我用 spring 4、STOMP 和 sock.js 做了一个简单的 web socket 通信,遵循这个 https://github.com/rstoyanchev/spring-websocket-portfolio 和这个 http://assets.spring.io/wp/WebSocketBlogPost.html

好吧,我想知道是否可以捕获连接事件,例如新客户端连接到我的服务器或客户端断开连接时,这在 Spring 4.0.0 中是否可能?

【问题讨论】:

    标签: java spring spring-mvc websocket


    【解决方案1】:

    虽然最初的问题是关于 Spring 4 - Sergi 很好地回答了。这是在 Spring 5 或 Spring Boot 2(在后台使用 Spring 5)中执行此操作的一种方法。需要实现ApplicationListener:

    @Component
    public class WebSocketEventListener implements ApplicationListener<SessionConnectEvent> {
        Logger logger = LoggerFactory.getLogger(WebSocketEventListener.class);
    
        @Override
        public void onApplicationEvent(SessionConnectEvent event) {
            logger.error("SessionConnectEvent = " + event);
        }
    }
    

    【讨论】:

      【解决方案2】:

      这可以通过连接握手拦截器 (HttpSessionHandshakeInterceptor) 完成,引用 documentation:

      自定义初始 HTTP WebSocket 握手的最简单方法 请求是通过一个 HandshakeInterceptor,它暴露了“之前”和 “在”握手方法之后。

      【讨论】:

      • 谢谢!!实际上我使用的是 WebSocketMessageBrokerConfigurer,但是使用它可以工作:registry.addEndpoint("/api/v1/ws/pushService").withSockJS().setInterceptors(wsSessionInterceptor);
      【解决方案3】:

      Spring WebSocket 在从客户端接收到消息时发布事件,如果您使用的是 STOMP,这些是发布的事件:

      检测连接和断开连接的最简单方法是为上述事件实现事件侦听器。

      public class WebSocketEventListener {
      
          @EventListener
          private void handleSessionConnected(SessionConnectEvent event) {
              ...
          }
      
          @EventListener
          private void handleSessionDisconnect(SessionDisconnectEvent event) {
              ...
          }
      }
      

      这是一个跟踪连接用户的示例实现:https://github.com/salmar/spring-websocket-chat/blob/master/src/main/java/com/sergialmar/wschat/event/PresenceEventListener.java

      【讨论】:

      • 你在哪里存储 sessionId?
      【解决方案4】:

      据我了解,DISCONNECT 事件的问题在本主题中没有得到解决。握手拦截只给你连接信息而不是断开连接。

      我已经通过入站通道的拦截器实现了这一点:

      <websocket:message-broker>
          ...
          <websocket:client-inbound-channel>
              <websocket:interceptors>
                  <bean class="com......MyChannelInterception"></bean>
              </websocket:interceptors>
          </websocket:client-inbound-channel>
      </websocket:message-broker>
      

      ...和班级...

      import java.security.Principal;
      
      import org.apache.log4j.LogManager;
      import org.apache.log4j.Logger;
      import org.springframework.messaging.Message;
      import org.springframework.messaging.MessageChannel;
      import org.springframework.messaging.MessageHeaders;
      import org.springframework.messaging.simp.SimpMessageType;
      import org.springframework.messaging.support.ChannelInterceptorAdapter;
      
      public class MyChannelInterception extends ChannelInterceptorAdapter {
      
      private static final Logger LOGGER = LogManager.getLogger(WrcChannelInterception.class);
      
      @Override
      public Message<?> preSend(Message<?> message, MessageChannel channel) {
      
          MessageHeaders headers = message.getHeaders();
          SimpMessageType type = (SimpMessageType) headers.get("simpMessageType");
          String simpSessionId = (String) headers.get("simpSessionId");
      
          if (type == SimpMessageType.CONNECT) {
              Principal principal = (Principal) headers.get("simpUser");
              LOGGER.debug("WsSession " + simpSessionId + " is connected for user " + principal.getName());
          } else if (type == SimpMessageType.DISCONNECT) {
              LOGGER.debug("WsSession " + simpSessionId + " is disconnected");
          }
          return message;
      }
      }
      

      请注意,Principal 在 CONNECT 上可用,但在 DISCONNECT 上不可用,但是您有甜蜜的 Session ID

      【讨论】:

      • 如何通过 sessionID 获取 Principal?
      • @disorderdev 在 Connect 上,您可以在数据库中存储 sessionId 和 Principal 之间的链接,在断开连接时,通过 Session ID 检索 Principal
      猜你喜欢
      • 2015-03-05
      • 2014-02-26
      • 1970-01-01
      • 1970-01-01
      • 2016-12-25
      • 2012-11-17
      • 1970-01-01
      • 2021-09-11
      • 2012-07-31
      相关资源
      最近更新 更多