WebSocket協議是一種全雙工協議,服務端可以主動向客戶端推送消息,可以是文本也可以是二進制數據,而且沒有同源策略的限制,不存在跨域問題。這里主要介紹服務端向客戶端推送消息。
第一步:導入依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>sockjs-client</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>stomp-websocket</artifactId> <version>2.3.3</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.3.1</version> </dependency>
第二步:創建WebSocket進行消息的推送
package com.example.websocket.controller; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; import org.springframework.web.socket.server.standard.ServerEndpointExporter; import javax.websocket.*; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.concurrent.CopyOnWriteArraySet; /** * @Author: yushizhong * @Date: 2020/1/10 15:42 * @Title: 描述 */ @Component @ServerEndpoint(value = "/ws/myWebSocket") public class WebSocket { //每個客戶端都會有相應的session,服務端可以發送相關消息 private Session session; //J.U.C包下線程安全的類,主要用來存放每個客戶端對應的webSocket連接,為什么說他線程安全。在文末做簡單介紹 private static CopyOnWriteArraySet<WebSocket> copyOnWriteArraySet = new CopyOnWriteArraySet<WebSocket>(); @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } /** * 打開連接。進入頁面后會自動發請求到此進行連接 * @param session */ @OnOpen public void onOpen(Session session) { this.session = session; copyOnWriteArraySet.add(this); System.out.println("websocket有新的連接, 總數:"+ copyOnWriteArraySet.size()); } /** * 用戶關閉頁面,即關閉連接 */ @OnClose public void onClose() { copyOnWriteArraySet.remove(this); System.out.println("websocket連接斷開, 總數:"+ copyOnWriteArraySet.size()); } /** * 測試客戶端發送消息,測試是否聯通 * @param message */ @OnMessage public void onMessage(String message) { System.out.println("websocket收到客戶端發來的消息:"+message); sendMessage(message); } /** * 出現錯誤 * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { System.out.println("發生錯誤:" + error.getMessage()+session.getId()); error.printStackTrace(); } /** * 用於發送給客戶端消息(群發) * @param message */ public void sendMessage(String message) { //遍歷客戶端 for (WebSocket webSocket : copyOnWriteArraySet) { System.out.println("websocket廣播消息:" + message); try { //服務器主動推送 webSocket.session.getBasicRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } /** * 用於發送給指定客戶端消息, * * @param message */ public void sendMessage(String sessionId, String message) throws IOException { Session session = null; WebSocket tempWebSocket = null; for (WebSocket webSocket : copyOnWriteArraySet) { if (webSocket.session.getId().equals(sessionId)) { tempWebSocket = webSocket; session = webSocket.session; break; } } if (session != null) { tempWebSocket.session.getBasicRemote().sendText(message); } else { System.out.println("沒有找到你指定ID的會話:{}"+sessionId); } } }
第三步:創建頁面chat.html,導入相關的js文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>websocket</title> <script src="stomp.min.js"></script> <script src="sockjs.min.js"></script> </head> <body> <h2>測試連接websocket</h2> <p> 連接url: <input type="text" value="ws://localhost:8080/ws/myWebSocket" id="url"> <button onclick="openWeb()">打開連接</button> </p> <p> 發送信息內容: <input type="text" id="message"><button onclick="send()">發送信息</button> </p> <hr> <p>消息區域</p> <p id="show"></p> </body> <script type="text/javascript"> var url="";//socket所需要的地址 var socket;//socket對象 function openWeb(){ createWebSocket(document.getElementById("url").value) } //創建WebSocket連接 function createWebSocket(url){ if ('WebSocket' in window) { socket = new WebSocket(url); } else { socket = new SockJS(url); } //連接打開事件 socket.onopen = function() { console.log("Socket已連接到"+url); }; //收到服務器消息后響應 socket.onmessage = function(e) { console.log("收到服務端消息:"+e.data) document.getElementById("show").innerHTML+="<br>"+e.data }; //連接關閉事件 socket.onclose = function() { console.log("Socket已關閉連接"); }; //發生了錯誤事件 socket.onerror = function() { console.log("Socket發生了錯誤"); } //窗口關閉時,關閉連接 window.unload=function() { socket.close(); }; } function send(){ socket.send(document.getElementById("message").value) } </script> </html>
第四步:測試。啟動項目,在瀏覽器輸入localhost:8080/chat.html,然后點擊連接wensocket進行連接,接着輸入要發送的信息,點擊發送就可以在下面看到發送的信息。