Websocket实现消息推送的方式,是一种在 TCP 连接上进行全双工通信的协议,建立客户端和服务器之间的通信渠道。浏览器和服务器仅需一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
Websocket 示意图
SpringBoot 整合 Websocket,先引入 Websocket 相关的工具包,和 SSE 相比额外的开发成本。
<!-- 引入websocket --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
服务端使用@ServerEndpoint
注解标注当前类为一个 WebSocket 服务器,客户端可以通过ws://localhost:7777/webSocket/10086
来连接到 WebSocket 服务器端。
@Component @Slf4j @ServerEndpoint("/websocket/{userId}") public class WebSocketServer { //与某个客户端的连接会话,需要通过它来给客户端发送数据 private Session session; private static final CopyOnWriteArraySet<WebSocketServer> webSockets = new CopyOnWriteArraySet<>(); // 用来存在线连接数 private static final Map<String, Session> sessionPool = new HashMap<String, Session>(); /** * 链接成功调用的方法 */ @OnOpen public void onOpen(Session session, @PathParam(value = "userId") String userId) { try { this.session = session; webSockets.add(this); sessionPool.put(userId, session); log.info("websocket消息: 有新的连接,总数为:" + webSockets.size()); } catch (Exception e) { } } /** * 收到客户端消息后调用的方法 */ @OnMessage public void onMessage(String message) { log.info("websocket消息: 收到客户端消息:" + message); } /** * 此为单点消息 */ public void sendOneMessage(String userId, String message) { Session session = sessionPool.get(userId); if (session != null && session.isOpen()) { try { log.info("websocket消: 单点消息:" + message); session.getAsyncRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } }
前端初始化打开 WebSocket 连接,并监听连接状态,接收服务端数据或向服务端发送数据。
<script> var ws = new WebSocket('ws://localhost:7777/webSocket/10086'); // 获取连接状态 console.log('ws连接状态:' + ws.readyState); //监听是否连接成功 ws.onopen = function () { console.log('ws连接状态:' + ws.readyState); //连接成功则发送一个数据 ws.send('test1'); } // 接听服务器发回的信息并处理展示 ws.onmessage = function (data) { console.log('接收到来自服务器的消息:'); console.log(data); //完成通信后关闭WebSocket连接 ws.close(); } // 监听连接关闭事件 ws.onclose = function () { // 监听整个过程中websocket的状态 console.log('ws连接状态:' + ws.readyState); } // 监听并处理error事件 ws.onerror = function (error) { console.log(error); } function sendMessage() { var content = $("#message").val(); $.ajax({ url: '/socket/publish?userId=10086&message=' + content, type: 'GET', data: { "id": "7777", "content": content }, success: function (data) { console.log(data) } }) } </script>
页面初始化建立 WebSocket 连接,之后就可以进行双向通信了,效果还不错。