工作随笔:WebSocket实时消息推送

最近在项目中,使用到了WebSocket来实时推送服务器的数据到客户端,今天来记录总结一下。

想要使用WebSocket来实时推送数据,首先需要服务器与客户端直接建立连接,也就是握手(HTTP协议)

  每5秒钟发生一个心跳
@Scheduled(cron = "0/5 * * * * ? ") public void sendHeart() { MessageWebSocket.broadcast(new WebSocketMessage(WebSocketMessage.CMD_HEART, "SUCCESS")); }

 后端重要的代码:

ServerEndpoint("/ws/{userId}")
@Component
@Slf4j
public class MessageWebSocket {

  /**
   * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象.
   */
  private static Map<String, MessageWebSocket> mapUserId = new ConcurrentHashMap<>();
  /**
   * 与某个客户端的连接会话,需要通过它来给客户端发送数据.
   */
  private Session session;
  /**
   * 接收userId.
   */
  private String userId = "";

  /**
   * . 连接建立成功调用的方法
   */
  @OnOpen
  public void onOpen(Session session, @PathParam("userId") String userId) {
    this.session = session;
    this.userId = userId;
    mapUserId.put(userId, this);
    log.info("用户连接:" + userId);
    try {
      send(JSON.toJSONString(new WebSocketMessage(WebSocketMessage.CMD_CONN, "SUCCESS")));
    } catch (IOException e) {
      e.printStackTrace();
      log.error("用户:" + userId + ",网络异常!!!!!!");
    }
  }

  /**
   * . 连接关闭调用的方法
   */
  @OnClose
  public void onClose() {
    mapUserId.remove(userId);
  }

  /**
   * . 收到客户端消息后调用的方法
   *
   * @param message 客户端发送过来的消息
   */
  @OnMessage
  public void onMessage(String message, Session session) {
    log.info("user id:" + userId + ",message:" + message);
  }

  /**
   * .
   *
   * @param session 回话
   * @param error 错误信息
   */
  @OnError
  public void onError(Session session, Throwable error) {
    log.error("user id:" + this.userId + ",reason:" + error.getMessage());
    error.printStackTrace();
  }

  /**
   * . 实现服务器主动推送
   */
  public void send(String message) throws IOException {
    if (this.session != null) {
      synchronized (session) {
        this.session.getBasicRemote().sendText(message);
      }
    }
  }

  /**
   * . 实现服务器主动推送
   */
  public static void send(String userId, String message) throws IOException {
    MessageWebSocket socket = mapUserId.get(userId);
    if (socket != null) {
      try {
        socket.send(message);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }

  /**
   * 广播发送.
   *
   * @param message webSocket消息
   */
  public static void broadcast(WebSocketMessage message) {
    if (null == message) {
      return;
    }
    String content = JSON.toJSONString(message);
    //log.info("message :{}", content);
    for (String userId : mapUserId.keySet()) {
      try {
        send(userId, content);
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
}

  前端代码(VUE):百度搜索前端连接WebSocket

 methods: {
            initWebSocket() { //初始化weosocket
                const wsuri = "ws://127.0.0.1:8080";
                this.websock = new WebSocket(wsuri);
                this.websock.onmessage = this.websocketonmessage;
                this.websock.onopen = this.websocketonopen;
                this.websock.onerror = this.websocketonerror;
                this.websock.onclose = this.websocketclose;
            },
            websocketonopen() { //连接建立之后执行send方法发送数据
                let actions = {
                    "test": "123"
                };
                this.websocketsend(JSON.stringify(actions));
            },
            websocketonerror() { //连接建立失败重连
                this.initWebSocket();
            },
            websocketonmessage(e) { //数据接收
                const redata = JSON.parse(e.data);
            },
            websocketsend(Data) { //数据发送
                this.websock.send(Data);
            },
            websocketclose(e) { //关闭
                console.log('断开连接', e);
            },
        }

  

posted @ 2020-09-11 16:37  MoreThinking  阅读(471)  评论(0编辑  收藏  举报