WebSocket实现消息实时通信

后端代码实现

1、导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <version>3.2.5</version>
</dependency>

2、创建websocket客户端对象。

@Getter
@Setter
public class WebSocketClient {

    // 与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    //连接的uri
    private String uri;
}

3、创建WebSocket服务类

@ServerEndpoint(value = "/websocket/message/{userName}")
@Component("msgWebSocketService")
public class WebSocketService {
    /**
     * 日志
     */
    private static final Logger LOG = LoggerFactory.getLogger(WebSocketService.class);

    /**
     * concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
     */
    private static ConcurrentHashMap<String, WebSocketClient> webSocketMap = new ConcurrentHashMap<>();

    /**
     * 与某个客户端的连接会话,需要通过它来给客户端发送数据
     * */
    private Session session;

    /**
     * 接收userName
     * */
    private String userName="";


    /**
     * 连接建立成功调用的方法
     *
     * */
    @OnOpen
    public void onOpen(Session session, @PathParam("userName") String userName) {
        this.session = session;
        this.userName= userName;
        WebSocketClient client = new WebSocketClient();
        client.setSession(session);
        client.setUri(session.getRequestURI().toString());
        webSocketMap.put(userName, client);
        LOG.info("----------------------------|-----------------------------------------------");
        LOG.info("用户{}连接消息中心。", userName);
        try {
            sendMessage("消息中心:连接成功!");
        } catch (IOException e) {
            LOG.error("消息中心:网络异常!");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if(webSocketMap.containsKey(userName)){
            webSocketMap.remove(userName);
        }
        LOG.info("用户{}断开消息中心连接", userName);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        LOG.info("收到用户{}向消息中心推送的消息:{}", userName, message);
    }

    /**
     * 捕获并记录错误信息
     */
    @OnError
    public void onError(Session session, Throwable error) {
        LOG.error("用户{}连接消息中心异常:{}", userName, error.getMessage());
        error.printStackTrace();
    }

    /**
     * 连接服务器成功后主动推送
     */
    public void sendMessage(String message) throws IOException {
        synchronized (session){
            this.session.getBasicRemote().sendText(message);
        }
    }

    /**
     * 向指定客户端发送消息
     * @param userName 用户名
     * @param message 消息内容
     */
    public static void sendMessage(String userName, String message){
        try {
            WebSocketClient webSocketClient = webSocketMap.get(userName);
            if(webSocketClient!=null){
                webSocketClient.getSession().getBasicRemote().sendText(message);
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }


    public static ConcurrentHashMap<String, WebSocketClient> getWebSocketMap() {
        return webSocketMap;
    }

    public static void setWebSocketMap(ConcurrentHashMap<String, WebSocketClient> webSocketMap) {
        WebSocketService.webSocketMap = webSocketMap;
    }

    public Session getSession() {
        return session;
    }

    public void setSession(Session session) {
        this.session = session;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

4、推送消息给客户端

webSocketService.sendMessage('用户', '消息内容')

前端对接

export default {
  data() {
    return {
      webSocketObj: {
        // 定义ws对象
        webSocket: null,
        // ws请求链接(类似于ws后台地址)
        webSocketUri: '',
        // ws定时器
        webSockeTimer: null
      },
    }
  },
  methods: {
    errorHandler (event) {
      console.log(event, '消息中心通信发生错误')
    },
    closeHandler (event) {
      console.log(event, '消息中心关闭')
    },
    messageHandler(msg) {
      const data = msg.data
      const obj = JSON.parse(data);
      console.log("收到消息中心通知:", obj);
    },
    openHandler (event) {
      console.log('消息中心websocket建立连接成功')
    },
    //消息中心WebSocket初始化
    webSocketInit(){
      const wsuri = 'ws://' + window.location.hostname +':80/websocket/message/system'
      this.webSocketObj.webSocketUri= wsuri
      // 初始化WebSocket
      this.webSocketObj.webSocket = new WebSocket(this.webSocketObj.webSocket)
      // WebSocket连接建立时触发
      this.webSocketObj.webSocket.addEventListener('open', this.openHandler)
      // WebSocket服务端给客户端推送消息
      this.webSocketObj.webSocket.addEventListener('message', this.messageHandler)
      // WebSocket通信发生错误时触发
      this.webSocketObj.webSocket.addEventListener('error', this.errorHandler)
      // WebSocket关闭时触发
      this.webSocketObj.webSocket.addEventListener('close', this.closeHandler)
    },
    // 销毁WebSocket
    destroy () {
      if (this.webSocketObj.webSocket !== null) {
        this.webSocketObj.webSocket.removeEventListener('open', this.openHandler)
        this.webSocketObj.webSocket.removeEventListener('message', this.messageHandler)
        this.webSocketObj.webSocket.removeEventListener('error', this.errorHandler)
        this.webSocketObj.webSocket.removeEventListener('close', this.closeHandler)
        this.webSocketObj.webSocket.close()
        this.webSocketObj.webSocket = null
        clearInterval(this.webSocketObj.webSockeTimer)
      }
    },
  },
  created() {
    this.webSocketInit()
  },
  beforeDestroy () {
    this.destroy()
  }
}
posted @   IamHzc  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示
主题色彩