不要再自己去实现websocket了,学会这个让你事半功倍
|
admin
2025年8月26日 10:16
本文热度 20
|
很多时候,我们在项目中都有用到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.注入SimpMessagingTemplate
private 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 编辑过