1、新增pom依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
2、配置bean
@Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); }
3、websocket處理類
package com.oremouse.websocket; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; @Component @ServerEndpoint("/websocket/{username}") public class WebSocket { public static Logger logger = LoggerFactory.getLogger(WebSocket.class); /** * 在線人數 */ public static int onlineNumber = 0; /** * 以用戶的姓名為key,WebSocket為對象保存起來 */ private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>(); /** * 會話 */ private Session session; /** * 用戶名稱 */ private String username; /** * 建立連接 * * @param session */ @OnOpen public void onOpen(@PathParam("username") String username, Session session) { logger.info("現在來連接的客戶id:" + session.getId() + "用戶名:" + username); onlineNumber++; this.username = username; this.session = session; logger.info("有新連接加入! 當前在線人數" + onlineNumber); try { // messageType 1代表上線 2代表下線 3代表在線名單 4代表普通消息 // 先給所有人發送通知,說我上線了 Map<String, Object> map1 = new HashMap<String, Object>(); map1.put("messageType", 1); map1.put("username", username); sendMessageAll(JSON.toJSONString(map1), username); // 把自己的信息加入到map當中去 clients.put(username, this); // 給自己發一條消息:告訴自己現在都有誰在線 Map<String, Object> map2 = new HashMap<String, Object>(); map2.put("messageType", 3); // 移除掉自己 Set<String> set = clients.keySet(); map2.put("onlineUsers", set); sendMessageTo(JSON.toJSONString(map2), username); } catch (IOException e) { logger.info(username + "上線的時候通知所有人發生了錯誤"); } } @OnError public void onError(Session session, Throwable error) { logger.info("服務端發生了錯誤" + error.getMessage()); // error.printStackTrace(); } /** * 連接關閉 */ @OnClose public void onClose() { onlineNumber--; // webSockets.remove(this); clients.remove(username); try { // messageType 1代表上線 2代表下線 3代表在線名單 4代表普通消息 Map<String, Object> map1 = new HashMap<String, Object>(); map1.put("messageType", 2); map1.put("onlineUsers", clients.keySet()); map1.put("username", username); sendMessageAll(JSON.toJSONString(map1), username); } catch (IOException e) { logger.info(username + "下線的時候通知所有人發生了錯誤"); } logger.info("有連接關閉! 當前在線人數" + onlineNumber); } /** * 收到客戶端的消息 * * @param message 消息 * @param session 會話 */ @OnMessage public void onMessage(String message, Session session) { try { logger.info("來自客戶端消息:" + message + "客戶端的id是:" + session.getId()); JSONObject jsonObject = JSON.parseObject(message); String textMessage = jsonObject.getString("message"); String fromusername = jsonObject.getString("username"); String tousername = jsonObject.getString("to"); // 如果不是發給所有,那么就發給某一個人 // messageType 1代表上線 2代表下線 3代表在線名單 4代表普通消息 Map<String, Object> map1 = new HashMap<String, Object>(); map1.put("messageType", 4); map1.put("textMessage", textMessage); map1.put("fromusername", fromusername); if (tousername.equals("All")) { map1.put("tousername", "所有人"); sendMessageAll(JSON.toJSONString(map1), fromusername); } else { map1.put("tousername", tousername); sendMessageTo(JSON.toJSONString(map1), tousername); } } catch (Exception e) { logger.info("發生了錯誤了"); } } public void sendMessageTo(String message, String ToUserName) throws IOException { for (WebSocket item : clients.values()) { if (item.username.equals(ToUserName)) { item.session.getAsyncRemote().sendText(message); break; } } } public void sendMessageAll(String message, String FromUserName) throws IOException { for (WebSocket item : clients.values()) { item.session.getAsyncRemote().sendText(message); } } public static synchronized int getOnlineCount() { return onlineNumber; } }
4、頁面跳轉controller
@RequestMapping("/websocket/{name}") public String testWebSocket(@PathVariable String name,Model model){ try{ model.addAttribute("username",name); return "websocket"; } catch (Exception e){ return "error"; } }
5、頁面
<!DOCTYPE html> <html> <head> <title>websocket</title> <script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.min.js"></script> <script src="http://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script> <script src="https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js"></script> </head> <body> <br/> <div style="margin: auto;text-align: center"> <select id="onLineUser"> <option>--所有--</option> </select> <input id="text" type="text" /> <button id="sendMsgBtn" >發送消息</button> </div> <br> <div style="margin-right: 10px;text-align: right"> <button id="closeBtn" >關閉連接</button> </div> <hr/> <div id="message" style="text-align: center;"></div> <input type="text" th:value="${username}" id="username" style="display: none" /> </body> <script type="text/javascript"> var webSocket; var commWebSocket; if ("WebSocket" in window) { webSocket = new WebSocket("ws://localhost:8086/websocket/"+document.getElementById('username').value); //連通之后的回調事件 webSocket.onopen = function() { //webSocket.send( document.getElementById('username').value+"已經上線了"); console.log("已經連通了websocket"); setMessageInnerHTML("已經連通了websocket"); }; //接收后台服務端的消息 webSocket.onmessage = function (evt) { var received_msg = evt.data; console.log("數據已接收:" +received_msg); var obj = JSON.parse(received_msg); console.log("可以解析成json:"+obj.messageType); //1代表上線 2代表下線 3代表在線名單 4代表普通消息 if(obj.messageType==1){ //把名稱放入到selection當中供選擇 var onlineName = obj.username; var option = "<option>"+onlineName+"</option>"; $("#onLineUser").append(option); setMessageInnerHTML(onlineName+"上線了"); } else if(obj.messageType==2){ $("#onLineUser").empty(); var onlineName = obj.onlineUsers; var offlineName = obj.username; var option = "<option>"+"--所有--"+"</option>"; for(var i=0;i<onlineName.length;i++){ if(!(onlineName[i]==document.getElementById('username').value)){ option+="<option>"+onlineName[i]+"</option>" } } $("#onLineUser").append(option); setMessageInnerHTML(offlineName+"下線了"); } else if(obj.messageType==3){ var onlineName = obj.onlineUsers; var option = null; for(var i=0;i<onlineName.length;i++){ if(!(onlineName[i]==document.getElementById('username').value)){ option+="<option>"+onlineName[i]+"</option>" } } $("#onLineUser").append(option); console.log("獲取了在線的名單"+onlineName.toString()); } else{ setMessageInnerHTML(obj.fromusername+"對"+obj.tousername+"說:"+obj.textMessage); } }; //連接關閉的回調事件 webSocket.onclose = function() { console.log("連接已關閉..."); setMessageInnerHTML("連接已經關閉...."); }; } else{ // 瀏覽器不支持 WebSocket alert("您的瀏覽器不支持 WebSocket!"); } //將消息顯示在網頁上 function setMessageInnerHTML(innerHTML) { document.getElementById('message').innerHTML += innerHTML + '<br/>'; } $("#sendMsgBtn").click(function(){ var selectText = $("#onLineUser").find("option:selected").text(); if(selectText=="--所有--"){ selectText = "All"; } else{ setMessageInnerHTML(document.getElementById('username').value+"對"+selectText+"說:"+ $("#text").val()); } var message = { "message":document.getElementById('text').value, "username":document.getElementById('username').value, "to":selectText }; webSocket.send(JSON.stringify(message)); $("#text").val(""); }); $("#closeBtn").click(function(){ webSocket.close(); }); </script> </html>
示例:
參考:
https://blog.csdn.net/qq_38455201/article/details/80374712