今天簡單看了一下webscoket的相關內容,寫了一個入門demo,簡單記錄一下。
1、服務端
服務端使用springboot來搭建,引入spring-boot-starter-websocket模塊,以及web模塊來做頁面。頁面使用簡單的thymeleaf模板。
-
配置websocket
服務的配置websocket需要先定義WebSocketExporter的bean,使用默認的構造方法即可。
package com.chat.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
-
創建websocket服務
創建websocket服務主要需要處理創建連接、發送消息、斷開連接、發生錯誤這幾種情況的邏輯。
package com.chat.bean; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CopyOnWriteArraySet; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; import org.springframework.stereotype.Component; @ServerEndpoint(value="/sunSocket") @Component public class SunWebSocket { /** * 記錄在線鏈接數 */ private static int onLineNum = 0; /** * concurrent包的線程安全set,存放每個客戶端連接對應的webSocket對象。 */ private static CopyOnWriteArraySet<SunWebSocket> webSocketSet = new CopyOnWriteArraySet<>(); /** * 與某個客戶端的會話,通過會話給客戶端傳遞消息 */ private Session session; /** * 開啟一個客戶端對話連接 * @param session */ @OnOpen public void onOpen(Session session) { this.session = session; webSocketSet.add(this); addOnlineCount(); sendMsg("歡迎加入聊天室", session); } /** * 當連接斷開時調用的方法 * @param session */ @OnClose public void onClose(Session session) { webSocketSet.remove(this); subOnlineCount(); System.out.println("有人走了"); } /** * 當有來自客戶端的消息時 * @param msg * @param session */ @OnMessage public void onMessage(String msg,Session session) { Map<String, String> map = new HashMap<>(); map.put("ip",session.getId()); map.put("msg",msg); for (SunWebSocket sunWebSocket : webSocketSet) { try { sunWebSocket.session.getBasicRemote().sendText(session.getId() + ":" + msg); } catch (IOException e) { e.printStackTrace(); } } } @OnError public void onError(Session session,Throwable error) { try { session.getBasicRemote().sendText(error.getMessage()); } catch (IOException e) { error.printStackTrace(); e.printStackTrace(); } } public void sendMsg(String msg, Session session) { try { session.getBasicRemote().sendText(msg); } catch (IOException e) { e.printStackTrace(); } } public static synchronized int getOnlineCount() { return onLineNum; } public static synchronized void addOnlineCount() { onLineNum++; } public static synchronized void subOnlineCount() { onLineNum--; } }
啟動springboot服務后台內容即完成。
2、客戶端
demo的客戶端使用html5的websocket來編寫。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <title>在線聊天</title> <style type="text/css"> #msg-view{ height: 400px; overflow: scroll; } </style> </head> <body> <div id="msg-view"> </div> <div id="msg-input"> <input id="msg"/> <button id="sendBtn" onclick="sendMsg()">發送</button> </div> <script type="text/javascript"> var websocket = null; if('WebSocket' in window){ websocket = new WebSocket("ws://localhost:8080/sunSocket") } else{ alert('Not support websocket') } websocket.onmessage = function (event) { var data = event.data; if(typeof(data) == 'string'){ showMsg(data) }else{ showMsg(data.ip + ':' + data.msg) } } /* 頁面關閉監聽 */ window.onbeforeunload = function(){ websocket.close(); } /** * 錯誤情況 */ websocket.onerror = function () { showMsg('連接異常') } function sendMsg() { var msg = document.getElementById('msg').value; websocket.send(msg) } function showMsg(msg) { document.getElementById('msg-view').innerHTML += msg + '<br/>'; } </script> </body> </html>