springboot实现websocket功能

1.引入pom依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

2.websocket配置类

/**
 * websocket配置
 * @Date: 2020-08-22
 */
@Configuration
/**
 * @EnableWebSocketMessageBroker
 * 开启使用 STOMP 协议来传输基于代理的消息,Broker是代理
 */
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry)
    {
        /**
         * //注册一个STOMP的endpoint,并指定使用SockJS协议
         * setErrorHandler: 设置一个错误处理的 Handler, 以便捕捉错误信息
         * addEndpoint: 切入点, 客户端在 new SockJs 的时候用到
         * setAllowedOrigins:设置为「*」表示接收 http 和 https 的请求
         * withSockJS: 使用 SockJS
         */
        registry.setErrorHandler(this.webSocketHandler())
                .addEndpoint("/endpointNiu") //websocket连接入口
                .setAllowedOrigins("*") //解决跨域问题
                .withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry)
    {
        /**
         *  参数是多个 destinationPrefixes, 服务端发送消息的 destination 要有这些前缀    广播式应配置一个/aiKnowledge
         */
        registry.enableSimpleBroker("/broadcast","/user");
        /**
         *  设置点对点时, destination 的前缀, 如客户端订阅  点对点使用的订阅前缀(客户端订阅路径上会体现出来),不设置的话,默认也是/user/
         */
        registry.setUserDestinationPrefix("/user");
    }

    /**
     * WebSocket Error 处理
     *
     * @return WebSocket Error 处理器
     */
    @Bean
    public StompSubProtocolErrorHandler webSocketHandler() {
        return new WebSocketErrorHandler();
    }

    /**
     * ServerEndpointExporter 作用
     *
     * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
     *
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

3.连接websocket监听类

@Component
public class WebSocketConnectListener implements ApplicationListener<SessionConnectEvent> {

    @Override
    public void onApplicationEvent(SessionConnectEvent sessionConnectEvent) {
        StompHeaderAccessor accessor = StompHeaderAccessor.wrap(sessionConnectEvent.getMessage());
        String sessionId = accessor.getSessionId();
        SessionUtils.addSession(sessionId);
        System.out.println("sessionId: {} 已连接"+ sessionId);
    }

}

4.断开websocket监听类

@Component
public class WebSocketDisconnectListener implements ApplicationListener<SessionDisconnectEvent> {

    @Override
    public void onApplicationEvent(SessionDisconnectEvent event) {
        StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage());
        String sessionId = sha.getSessionId();
        SessionUtils.removeSession(sessionId);
        System.out.println("sessionId: {} 已断开"+ sessionId);
    }

}

5.错误处理类

public class WebSocketErrorHandler extends StompSubProtocolErrorHandler  {

    public WebSocketErrorHandler()
    {
        super();
    }

    @Override
    public Message<byte[]> handleClientMessageProcessingError(Message<byte[]> clientMessage, Throwable ex) {
        return super.handleClientMessageProcessingError(clientMessage, ex);
    }

    @Override
    public Message<byte[]> handleErrorMessageToClient(Message<byte[]> errorMessage) {
        return super.handleErrorMessageToClient(errorMessage);
    }

    @Override
    protected Message<byte[]> handleInternal(StompHeaderAccessor errorHeaderAccessor, byte[] errorPayload, Throwable cause, StompHeaderAccessor clientHeaderAccessor) {
        return super.handleInternal(errorHeaderAccessor, errorPayload, cause, clientHeaderAccessor);
    }
}

6.对外调用接口实现类 (业务问题这里只需实现点对点模式发送消息)

@Service
public class WebSocketServiceImpl implements WebSocketService {

    @Autowired
    private HandleMessage handleMessage;

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    /**
     * 给某个用户主动推送消息 (点对点推送消息)
     * @param userName  推送消息的用户名
     * */
    @Override
    public void sendMessageStatus(String userName) {
        UserBean user = UserHolder.getUser();
        Boolean off = handleMessage.getMessageByUser(user.getId());
        messagingTemplate.convertAndSendToUser(userName, "/aiKnowledge/pointMessage", off);
    }

}

7.前端vue代码块

//websocket method
    initWebSocket() {
      this.connection();
      let self = this;
      // 断开重连机制,尝试发送消息,捕获异常发生时重连
      this.timer = setInterval(() => {
        try {
          self.stompClient.send("test");
        } catch (err) {
          console.log("断线了: " + err);
          self.connection();
        }
      }, 60000);
    },
    connection() {
      // 建立连接对象
      this.socket = new SockJS('http://localhost:9091/endpointNiu');//连接服务端提供的通信接口,连接以后才可以订阅广播消息和个人消息
      // 获取STOMP子协议的客户端对象
      this.stompClient = Stomp.over(this.socket);
      //获取token
      const token = getToken();
      // 定义客户端的认证信息,按需求配置  param 
      var headers = {
        token: token,
      };
      // 向服务器发起websocket连接
      if(this.user != null){
        const userEmail = this.user.username;
        this.stompClient.connect(headers,(frame) => {
          this.stompClient.subscribe('/user/'+userEmail+'/aiKnowledge/pointMessage', (msgStatus) => { // 订阅服务端提供的某个topic
            // msg存放的是服务端发送给我们的信息
            if(msgStatus.body == "false"){
              this.hasMessageNoRead = false ;
            }else{
              this.hasMessageNoRead = true ;
            }
            
          });
        }, (err) => {
          // 连接发生错误时的处理函数
          console.log(err);
        });
      }
      

    },
    // 断开连接
    disconnect() {
      if (this.stompClient != null) {
        this.stompClient.disconnect();
      }
    }
  }

调用方式:在vue 的methods属性中加入方法,使用initWebSocket()方法连接websocket,一般是在computed中调用this.initWebSocket()。

作者前端很烂,vue半问半写出来的,如果不对的地方,忍着, 请查阅其他博客资料

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值