先上效果圖:
相對來說更好看那么一點但是,實現代碼都是一樣的。
先來準備工作導入依賴
<!--websocket依賴--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
其實springboot已經內置了,直接在主函數啟動就行。但我們這次就講這個。
導入依賴后掃描啟用
package com.nx.study.springstudy.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; @Configuration public class WS { @Bean public ServerEndpointExporter serverEndpointExporter(){ return new ServerEndpointExporter(); } }
**@ServerEndpoint("/websocket/{username}")**
接收前端傳回數據
@Component啟用
package com.nx.study.springstudy.bean; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import net.sf.json.JSONObject; import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; @ServerEndpoint("/websocket/{username}") @Component public class Myws { private static Map<String, Myws> webSocketSet = new ConcurrentHashMap<String, Myws>(); private static Map<String, Session> map = new HashMap<String, Session>(); private static List<String> namelist = new ArrayList<String>(); private static JSONObject jsonObject = new JSONObject(); private static JSONObject jsonObject2 = new JSONObject(); private static List<String> nm_msg = new ArrayList<String>(); private SocketMsg socketMsg; private Session session; private String name; @OnOpen public void onpen(Session session, @PathParam(value = "username") String username){ if(username == null){ username = "游客"; } this.session = session; // this.name = "南" + getname(); this.name = username; webSocketSet.put(name, this); map.put(username, session); namelist.clear(); // 清空原來的信息 setonlion(); jsonObject.put("onlinepp", namelist); String message = jsonObject.toString(); broadcast2(message); } @OnClose public void onclose(){ webSocketSet.remove(this.name); // 移除對象 namelist.clear(); setonlion(); jsonObject.clear(); jsonObject.put("onlinepp", namelist); String message = jsonObject.toString(); broadcast3(message); } @OnMessage public void onmessage(String message){ nm_msg.clear(); jsonObject2.clear(); nm_msg.add(name); nm_msg.add(message); jsonObject2.put("chat", nm_msg); String message2 = jsonObject2.toString(); broadcast(message2); } @OnError public void onError(Session session, Throwable error) { System.out.println("發生錯誤"); error.printStackTrace(); } public void broadcast(String message){ for (Map.Entry<String, Myws> item : webSocketSet.entrySet()){ item.getValue().session.getAsyncRemote().sendText(message); } } public void broadcast2(String message){ for (Map.Entry<String, Myws> item : webSocketSet.entrySet()){ item.getValue().session.getAsyncRemote().sendText(message); } } public void broadcast3(String message){ for (Map.Entry<String, Myws> item : webSocketSet.entrySet()){ if (!item.getKey().equals(name)){ item.getValue().session.getAsyncRemote().sendText(message); } } } public void setonlion(){ for (Map.Entry<String, Myws> item : webSocketSet.entrySet()){ namelist.add(item.getKey()); } } public String getname() { String linkNo = ""; // 用字符數組的方式隨機 String model = "小大天明畫美麗豪子余多少浩然兄弟朋友美韻紫萱好人壞蛋誤解不要停棲棲遑遑可"; char[] m = model.toCharArray(); for (int j = 0; j < 2; j++) { char c = m[(int) (Math.random() * 36)]; // 保證六位隨機數之間沒有重復的 if (linkNo.contains(String.valueOf(c))) { j--; continue; } linkNo = linkNo + c; } return linkNo; } }
其中重點就是4個注解
**@OnOpen,@OnClose,@OnMessage,@OnError**
- @OnOpenC>客戶端打開鏈接時候觸發執行
- @OnCloseC>客戶端關閉鏈接觸發執行
- @OnMessageC>客戶端發送信息觸發執行
- @OnErrorC>發送錯誤時候觸發執行
對象信息都儲存在Session,可以仔細看看上面代碼很好理解。
我們只需要理解這4個注解的作用就可以!
前端頁面代碼
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <link rel="icon" type="image/x-icon" th:href="@{/img/user/head/favicon.ico}" /> <script th:src="@{webjars/jquery/3.1.1/jquery.min.js}"></script> <script th:src="@{webjars/bootstrap/3.3.7/js/bootstrap.min.js}"></script> <link rel="stylesheet" th:href="@{webjars/bootstrap/3.3.7/css/bootstrap.min.css}" /> <link th:href="@{/css/home.css}" rel="stylesheet" type="text/css" /> <meta charset="UTF-8"> <title>在線聊天室</title> </head> <body> <div class="container-fluid"> <div style="width: 100%;height: 100px;text-align: center;margin-bottom: 30px;color: #495e6a;box-shadow: 0px 0px 10px #000000"> <br> <h1>文明用語,快樂你我他</h1> </div> <div style="width: 800px;height: 600px;margin: auto;background-color: #dce9f6;box-shadow: 0px 0px 10px #707074;display: flex"> <div style="width: 200px;height: 600px;background-color: #d4d1d1"> <div style="width: 160px;height: 40px;margin: auto;margin-top: 10px;background-color: #fdffff;text-align: center;box-shadow: 0px 0px 10px #474749;border-radius: 4px"> <span class="glyphicon glyphicon-globe" style="font-size: 30px;padding-top: 2px;padding-bottom: 2px"></span> <span style="font-size: 30px">群聊</span> </div> <div style="width: 160px;height: 40px;margin: auto;margin-top: 10px;background-color: #fdffff;text-align: center;box-shadow: 0px 0px 10px #474749;border-radius: 4px"> <span class="glyphicon glyphicon-star" style="font-size: 30px;padding-top: 2px;padding-bottom: 2px"></span> <span style="font-size: 30px" th:text="${Springuser.username}">游客</span> </div> <hr> <div id="online" style="width: 200px;height: 500px;word-break: break-word;overflow: auto"> </div> </div> <div style="width: 600px;height: 600px"> <div style="width: 600px;height: 500px;padding: 20px 20px 20px 20px;word-break: break-word;overflow: auto" id="message"> </div> <div style="width: 600px;height: 100px;background-color: #ddf1d7;display: flex"> <div style="width: 100px;height: 100px;text-align: center;background-color: #f5d2d2"> <button id="btn1" class="btn btn-success" style="margin-top: 5px">連接上線</button><br> <br> <button id="btn2" class="btn btn-danger">下線</button> </div> <div style="width: 500px;height: 100px;padding: 10px 10px 10px 10px" class="input-group"> <input id="msg" type="text" class="form-control" placeholder="在這里輸入想說的話吧!" /><br> <button id="btn3" class="btn btn-info" style="margin-top: 10px;float: right">發送消息</button> </div> </div> </div> </div> <div class="div2" style="margin-top: 30px;background-color: #ffffff"> <br><br> <a href="#"><span style="color: #000000;">關于我們</span></a> | <a href="mailto: [email protected]" style="color: #000000;">找我合作</a><br> <a href="http://beian.miit.gov.cn" style="color: #202223;">贛ICP備2021004042號</a> </div> </div> </body> <script th:inline="javascript" language='javascript'> $(document).ready(function(){ var select; var message = ""; var fromuser = ""; var touser = ""; var type = 0; var username = [[${Springuser.username}]]; var websocket = null; $("#btn1").click(function(){ //判斷當前瀏覽器是否支持WebSocket if(select === 1){ alert("你已連接上線路,無需重復連接!") }else { if ('WebSocket'in window) { websocket = new WebSocket("ws://wenhaosuper.top:8000/websocket/" + username); alert("歡迎-->" + username + "<--成功上線!"); select = 1; } else { alert('Not support websocket') } } //連接發生錯誤的回調方法 websocket.onerror = function() { alert("錯誤"); }; //連接成功建立的回調方法 websocket.onopen = function() { } //接收到消息的回調方法 websocket.onmessage = function(event) { var msg = event.data var obj = JSON.parse(msg); var zxname = obj.onlinepp; var chat = obj.chat; if (zxname != null){ onlinename(zxname); } if (chat != null){ setchat(chat); } } //連接關閉的回調方法 websocket.onclose = function() { alert("離開"); select = 2; $("#online").empty(); } //監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket連接,防止連接還沒斷開就關閉窗口,server端會拋異常。 window.onbeforeunload = function() { websocket.onclose; websocket.close(); } }); //將消息顯示在網頁上 function setchat(message) { $("<div style=\"width: 560px;min-height: 40px;display: flex;margin-bottom: 20px\">\n" + " <div style=\"width: 40px;height: 40px;background-color: #ffffff;text-align: center;border-radius: 20px\">\n" + " <span style=\"font-size: 28px;margin-top: 9px\"><strong>N</strong></span>\n" + " </div>\n" + " <div style=\"min-height: 40px;margin-left: 10px\">\n" + " <div style=\"height: 18px\">\n" + " <span style=\"color: #7f7777;font-size: 14px\">"+message[0]+"</span>\n" + " </div>\n" + " <div style=\"min-height: 20px;word-break: break-word;background-color: #ffffff;padding: 10px 10px 10px 10px;border-radius: 6px\">\n" + " <span>"+message[1]+"</span>\n" + " </div>\n" + " </div>\n" + " </div>").appendTo("#message"); } function onlinename(obj){ $("#online").empty(); obj.forEach(function (e){ $("<div style=\"width: 160px;height: 40px;margin: auto;margin-top: 10px;background-color: #fdffff;text-align: center;box-shadow: 0px 0px 10px #474749;border-radius: 4px;overflow: hidden\">\n" + " <span class=\"glyphicon glyphicon-user\" style=\"font-size: 30px;padding-top: 2px;padding-bottom: 2px\"></span>\n" + " <span style=\"font-size: 26px\">"+e+"</span>\n" + " </div>").appendTo("#online"); }); } $("#btn2").click(function(){ websocket.close(); }); //發送消息 $("#btn3").click(function(){ var message = $("#msg").val(); websocket.send(message); $("#msg").val(""); }); }); </script> </html>
因為我這個是springboot項目
模板引擎代碼如下
package com.nx.study.springstudy.controller; import com.nx.study.springstudy.bean.UserPostForm; import com.nx.study.springstudy.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @Controller public class WebSocketController { @Autowired private UserService userService; @RequestMapping("/websocket") public String webSocket(Model model, HttpServletRequest request){ HttpSession httpSession = request.getSession(); String username = (String) request.getSession().getAttribute("username"); String userpassword = (String) request.getSession().getAttribute("userpassword"); if (username != null){ UserPostForm Springuser = userService.query(username,userpassword); model.addAttribute("Springuser", Springuser); return "index/webSocket"; }else { return "index/ZGZG"; } } }
最后效果圖如下
以上就是使用springboot整合websocket實現群聊教程的詳細內容,更多關于springboot整合websocket實現群聊的資料請關注服務器之家其它相關文章!
原文鏈接:https://blog.csdn.net/nanxiang11/article/details/119791333