不要再自己去实现websocket了,学会这个让你事半功倍
|
admin
2025年8月26日 10:16
本文热度 718
|
很多时候,我们在项目中都有用到websocket的场景,如数据实时更新、实时聊天,实时通知等,下面我将带大家了解什么是websocket,websocket和http的区别。 WebSocket 是一种在单个 TCP 连接上实现全双工通信的网络协议,它允许客户端和服务器之间建立持久连接,实现实时双向数据传输。与传统的 HTTP 协议(请求 - 响应模式)相比,WebSocket 最大的优势是服务器可以主动向客户端推送数据,无需客户端频繁轮询,极大提升了实时性和效率。WebSocket 的核心作用
实时双向通信
打破 HTTP “客户端请求→服务器响应” 的单向模式,实现服务器和客户端的 “平等对话”:
例:聊天应用中,A 发送消息后,服务器可立即将消息推送给 B,无需 B 反复刷新页面。
减少网络开销
低延迟响应
避免了 HTTP 轮询(客户端定时发送请求)带来的延迟和资源浪费:
与 HTTP 的对比
自己实现websocket服务需要基于TCP协议处理握手、帧解析和双向通信。
(1)握手阶段
(2)帧解析与构建
(3)广播功能
注解式的实现是我们常用的websocket实现,只需要使用@ServerEndpoint注解标记类为websocket的服务端点,客户端就可以使用ws://地址:端口/端点进行连接。下面是简单的实现
@ServerEndpoint("/chat")public class ChatServer { private static final Set<Session> onlineSessions = Collections.synchronizedSet(new HashSet<>()); * 客户端连接建立时触发(对应@OnOpen) */ @OnOpen public void onOpen(Session session) { onlineSessions.add(session); System.out.println("新客户端连接,会话ID:" + session.getId()); broadcast("系统消息:有新用户加入,当前在线:" + onlineSessions.size() + "人"); } * 客户端断开连接时触发(对应@OnClose) */ @OnClose public void onClose(Session session) { onlineSessions.remove(session); System.out.println("客户端断开,会话ID:" + session.getId()); broadcast("系统消息:有用户离开,当前在线:" + onlineSessions.size() + "人"); } * 收到客户端消息时触发(对应@OnMessage) */ @OnMessage public void onMessage(String message, Session session) { System.out.println("收到消息(" + session.getId() + "):" + message); broadcast("用户" + session.getId().substring(0, 6) + ":" + message); } * 发生错误时触发(对应@OnError) */ @OnError public void onError(Session session, Throwable error) { System.err.println("会话错误(" + session.getId() + "):" + error.getMessage()); } * 广播消息给所有在线客户端 */ private static void broadcast(String message) { for (Session session : onlineSessions) { try { session.getBasicRemote().sendText(message); } catch (IOException e) { System.err.println("广播失败:" + e.getMessage()); } } }
<dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.1</version> <scope>provided</scope> </dependency>
spring websocket实现-SimpMessagingTemplate spring 是spring对JSR 356之上的更高封装,简化消息发送,整合spring生态,SimpMessagingTemplate 消息发送更为简便。
SimpMessagingTemplate 会话方式
messagingTemplate.convertAndSend("/topic/news", "新闻内容"); messagingTemplate.convertAndSendToUser("user123", "/queue/msg", "私信");
废话不多说,项目代码看一下。简单三步实现。
1.pom引入spring-boot-starter-websocket<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId></dependency>2.注入SimpMessagingTemplateprivate final SimpMessagingTemplate websocketTemplate;3.发送消息websocketTemplate.convertAndSend("/topic/device-updates", message);
这种方式有一个问题:一直发送(如前端订阅页面关闭),我需要只有订阅者在线的时候才发送。于是根据spring websocket 做了一个监听
然后再发送消息时,对在线数进行检查
这是后端所需要实现的,前端我们只需要进行订阅就可以了。
前端我们引入两个js
<script src="/static/util/sockjs.min.js"></script>
<script src="/static/util/stomp.min.js"></script>
然后订阅后端的destination
该文章在 2025/8/29 12:23:03 编辑过