WebSocket 是 HTML5 開始提供的一種在單個 TCP 鏈接上進行全雙工通信的協議。
WebSocket 使得客戶端和服務器之間的數據交換變得更加簡單,容許服務端主動向客戶端推送數據。在 WebSocket API 中,瀏覽器和服務器只須要完成一次握手,二者之間就直接能夠建立持久性的鏈接,並進行雙向數據傳輸。html
在 WebSocket API 中,瀏覽器和服務器只須要作一個握手的動做,而後,瀏覽器和服務器之間就造成了一條快速通道。二者之間就直接能夠數據互相傳送。前端
如今,不少網站爲了實現推送技術,所用的技術都是 Ajax 輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,而後由服務器返回最新的數據給客戶端的瀏覽器。這種傳統的模式帶來很明顯的缺點,即瀏覽器須要不斷的向服務器發出請求,然而HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費不少的帶寬等資源。vue
HTML5 定義的 WebSocket 協議,能更好的節省服務器資源和帶寬,而且可以更實時地進行通信。html5
詳細的WebSocket介紹請參考菜鳥教程WebSocketweb
由於近期所使用的技術棧爲VUE和SpringBoot,所以此文章所用技術環境也爲VUE以及SpringBoot下。spring
建議先在後端(SpringBoot)配置好WebSocket。後端
maven依賴(由於個人SpringBoot項目爲2.0以上,會自動選擇最優版本,所以此處沒有帶上版本號):api
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
WebSocket配置類:瀏覽器
@Configuration public class WebSocketConfig { /** * 注入ServerEndpointExporter, * 這個bean會自動註冊使用了@ServerEndpoint註解聲明的Websocket endpoint */ @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
WebSocket操做類:服務器
WebSocket的向用戶推送能夠爲向全部用戶推送以及單點推送
@Component @ServerEndpoint("/websocket/{shopId}") //此註解至關於設置訪問URL public class WebSocket { private Session session; private static CopyOnWriteArraySet<WebSocket> webSockets =new CopyOnWriteArraySet<>(); private static Map<String,Session> sessionPool = new HashMap<String,Session>(); @OnOpen public void onOpen(Session session, @PathParam(value="shopId")String shopId) { this.session = session; webSockets.add(this); sessionPool.put(shopId, session); System.out.println("【websocket消息】有新的鏈接,總數爲:"+webSockets.size()); } @OnClose public void onClose() { webSockets.remove(this); System.out.println("【websocket消息】鏈接斷開,總數爲:"+webSockets.size()); } @OnMessage public void onMessage(String message) { System.out.println("【websocket消息】收到客戶端消息:"+message); } // 此爲廣播消息 public void sendAllMessage(String message) { for(WebSocket webSocket : webSockets) { System.out.println("【websocket消息】廣播消息:"+message); try { webSocket.session.getAsyncRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } // 此爲單點消息 public void sendOneMessage(String shopId, String message) { Session session = sessionPool.get(shopId); if (session != null) { try { session.getAsyncRemote().sendText(message); } catch (Exception e) { e.printStackTrace(); } } } }
在Controller中使用
@RestController @RequestMapping("api") public class TestController { @Autowired private WebSocket webSocket; @RequestMapping("/sendAllWebSocket") public String test() { webSocket.sendAllMessage("清晨起來打開窗,心情美美噠~"); return "websocket羣體發送!"; } @RequestMapping("/sendOneWebSocket") public String sendOneWebSocket() { webSocket.sendOneMessage("DPS007", "只要你乖給你買條gai!"); return "websocket單人發送"; } }
在前端中(VUE)使用WebSocket
固然不在vue中使用也是同樣的,只不過要注意的是WebSocket在普通js中如何建立以及銷燬
<script> export default { data() { return { shopId:'' } }, created() { // 頁面建立生命週期函數 this.initWebSocket() }, destroyed: function () { // 離開頁面生命週期函數 this.websocketclose(); }, methods: { collapse: function(){ this.isCollapse = !this.isCollapse; if (this.isCollapse) { this.iconClass = "cebianlanzhankai"; } else{ this.iconClass = "cebianlanshouhui"; } }, initWebSocket: function () { // WebSocket與普通的請求所用協議有所不一樣,ws等同於http,wss等同於https this.websock = new WebSocket("ws://localhost:8046/websocket/DPS007"); this.websock.onopen = this.websocketonopen; this.websock.onerror = this.websocketonerror; this.websock.onmessage = this.websocketonmessage; this.websock.onclose = this.websocketclose; }, websocketonopen: function () { console.log("WebSocket鏈接成功"); }, websocketonerror: function (e) { console.log("WebSocket鏈接發生錯誤"); }, websocketonmessage: function (e) { var da = JSON.parse(e.data); console.log(da); this.message = da; }, websocketclose: function (e) { console.log("connection closed (" + e.code + ")"); } } } </script>