本篇文章本人是根據實際項目需求進行書寫的初版,裏面有些內容對你們或許沒有用,可是核心代碼本人已對其作了紅色標註。文章講解我將從maven座標、HTML頁面、js文件及後端代碼一塊兒書寫。css
1、maven座標html
<!-- WebSocket配置開始--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>${spring.version}</version> </dependency> <!-- WebSocket配置結束-->
2、HTML頁面java
<!--消息框開始–--> <!-- 彈窗–>--> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <link rel="stylesheet" type="text/css" href="${basePath}/static/css/home/index.css"> <script src="${basePath}/static/js/common/jquery-1.8.3.min.js"></script> <script src="${basePath}/static/js/home/index.js"></script> <script src="${basePath}/static/css/layui/layui.js"></script> <title>後臺管理系統</title> </head> <body> <input type="hidden" value="${userId}" id="userId"> <input type="hidden" value="${cnName}" id="cnName"> <div class="tanchuang"> <div class="tanchuangClose"><span class="tanchuangCloseBtn">關閉</span></div> <h6>消息提示:</h6> <div id="messages"></div> </div> <!--消息框結束–--> <script src="${basePath}/static/js/home/index.js"></script> <script src="/static/js/webSocket.js"></script> </body> </html>
3、js文件(websocket.js)jquery
var websocket; // var host = document.location.host; var userId = $("#userId").val(); // 得到當前登陸人員的userName var cnName=$("#cnName").val(); // alert(username) //判斷當前瀏覽器是否支持WebSocket if ('WebSocket' in window) { // alert("瀏覽器支持Websocket") if(websocket ==null){
//如下用的是ip路徑,那麼在本地啓動項目時也須要使用ip地址進行訪問 websocket = new WebSocket("ws://192.168.200.102:8080/webSocket/"+userId+"/"+cnName); } } else { alert('當前瀏覽器 Not support websocket') } //鏈接發生錯誤的回調方法 websocket.onerror = function() { // setMessageInnerHTML("WebSocket鏈接發生錯誤"); }; //鏈接成功創建的回調方法 websocket.onopen = function() { // alert("WebSocket鏈接成功") // setMessageInnerHTML("WebSocket鏈接成功"); } //接收到消息的回調方法 websocket.onmessage = function(event) { // alert("接收到消息的回調方法") $('.tanchuang').css('display','block') // alert("這是後臺推送的消息:"+event.data); $("#messages").append(event.data + '<br/>') ; // websocket.close(); // alert("webSocket已關閉!") } //鏈接關閉的回調方法 websocket.onclose = function() { // setMessageInnerHTML("WebSocket鏈接關閉"); } //監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket鏈接,防止鏈接還沒斷開就關閉窗口,server端會拋異常。 /*window.onbeforeunload = function() { closeWebSocket(); }*/ //關閉WebSocket鏈接 function closeWebSocket() { websocket.close(); } //將消息顯示在網頁上 function setMessageInnerHTML(innerHTML) { document.getElementById('messages').innerHTML += innerHTML + '<br/>'; }
4、websocket鏈接控制器web
package com.yjlc.platform.utils.webSocket; import com.alibaba.fastjson.JSON; import com.yjlc.platform.User; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * -------------------------------------------------------------- * CopyRights(c)2018,YJLC * All Rights Reserved * <p> * FileName: WebSockets.java * Description:(該處未使用配置類)使用配置類後才能夠在該類中進行service的註解注入 * Author: cyb * CreateDate: 2018-11-28 * -------------------------------------------------------------- */ @ServerEndpoint("/webSocket/{userId}/{cnName}") public class WebSockets { private static int onlineCount = 0; public static Map<User, WebSockets> clients = new ConcurrentHashMap<User, WebSockets>(); private Session session; private Long userId;//用戶id private String cnName;//用戶真實名稱 private User user;//用戶實體 public static List<User> list = new ArrayList<>(); //在線列表,記錄用戶名稱 /** *@description: 鏈接websocket *@author:cyb *@date: 2018-12-03 19:12 *@param: userId 用戶id *@param: cnName 用戶真實名稱 *@param: session *@return: void */ @OnOpen public void onOpen(@PathParam("userId") Long userId,@PathParam("cnName") String cnName, Session session) throws IOException { this.userId = userId; this.session = session; this.cnName=cnName; System.out.println("cnName:"+cnName+"userId"+userId); user= new User(); user.setUserId(userId); user.setCnName(cnName); list.add(user); addOnlineCount();//添加在線人數 clients.put(user, this); /* String message = getMessage("["+cnName+"]進入聊天室,當前在線人數爲"+getOnlineCount()+"位", "notice", list); broadcast(message);//調用廣播 System.out.println("已鏈接");*/ } /** * 廣播消息 * @param message */ public void broadcast(String message){ for (WebSockets item : clients.values()) { String cnName = item.cnName; // String msg = message.replace("{userName}",cnName); item.session.getAsyncRemote().sendText(msg); } } /** * 組裝返回給前臺的消息 * @param message 交互信息 * @param type 信息類型 * @param list 在線列表 * @return */ public String getMessage(String message, String type, List list){ com.alibaba.fastjson.JSONObject member = new com.alibaba.fastjson.JSONObject(); member.put("message", message); member.put("type", type); member.put("list", list); return member.toString(); } /** * 對特定用戶發送消息 * @param message * @param session */ public void singleSend(String message, Session session){ try { session.getBasicRemote().sendText(message); } catch (IOException e) { e.printStackTrace(); } } /** *@description: 關閉鏈接 *@author:cyb *@date: 2018-12-03 14:33 *@param: *@return: void */ @OnClose public void onClose() throws IOException { System.out.println("關閉當前用戶鏈接:"+user.getCnName()); clients.remove(user); list.remove(user); //從在線列表移除這個用戶 subOnlineCount(); } /** *@description:前臺發送過來的消息 *@author:cyb *@date: 2018-12-03 14:33 *@param: _message *@return: void */ @OnMessage public void onMessage(String _message) throws IOException { com.alibaba.fastjson.JSONObject chat = JSON.parseObject(_message); com.alibaba.fastjson.JSONObject message = JSON.parseObject(chat.get("message").toString()); if(message.get("to") == null || message.get("to").equals("")){ //若是to爲空,則廣播;若是不爲空,則對指定的用戶發送消息 broadcast(_message); }else{ String [] userlist = message.get("to").toString().split(","); sendMessageTo(_message,message.get("from").toString()); // singleSend(_message, (Session) routetab.get(message.get("from"))); //發送給本身 } } @OnError public void onError(Session session, Throwable error) { error.printStackTrace(); } /** *@description:消息發送給指定人員 *@author:cyb *@date: 2018-12-03 14:35 *@param: message *@param: To *@return: void */ public void sendMessageTo(String message, String To) throws IOException { for (WebSockets item : clients.values()) { if (item.userId.equals(To) ) item.session.getAsyncRemote().sendText(message); } } public static synchronized int getOnlineCount() { return onlineCount; } public static synchronized void addOnlineCount() { WebSockets.onlineCount++; } public static synchronized void subOnlineCount() { WebSockets.onlineCount--; } public static synchronized Map<User, WebSockets> getClients() { return clients; } }
5、websocket輔助類spring
package com.yjlc.platform.utils.webSocket; import javax.servlet.http.HttpSession; import javax.websocket.HandshakeResponse; import javax.websocket.server.HandshakeRequest; import javax.websocket.server.ServerEndpointConfig; /** * -------------------------------------------------------------- * CopyRights(c)2018,YJLC * All Rights Reserved * <p> * FileName: HttpSessionConfigurator.java * Description:配置類 將http中的session傳入websocket中 * Author: cyb * CreateDate: 2018-11-26 * -------------------------------------------------------------- */ public class HttpSessionConfigurator extends ServerEndpointConfig.Configurator { @Override public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) { // 獲取當前Http鏈接的session HttpSession httpSession = (HttpSession) request.getHttpSession(); // 將http session信息注入websocket session sec.getUserProperties().put(HttpSession.class.getName(), httpSession); } }
6、後端代碼json
/** *@description:發送信息 *@author:cyb *@date: 2018-11-19 10:03 *@param: id *@return: java.util.Map<java.lang.String,java.lang.Object> */ @RequestMapping("sndmsg") @ResponseBody public Map<String,Object> sndmsg(Long id){ Map<String,Object> map = new HashMap<>(); AdminUser user=(AdminUser) SecurityUtils.getSubject().getSession().getAttribute("users"); try{ // int k=0; int k= service.sndmsg(id,user); if(k==200){ map.put("code",200); return map; }else { map.put("code",0); return map; } }catch (Exception e){ e.printStackTrace(); map.put("code",500); return map; } }
7、service層實現類後端
//該類下標紅的未重點,其他的代碼你們能夠跳過
public int sndmsg(Long id,AdminUser adminUser) { //獲取該條信息模板 SettingTemplateDTO templateDTO = templateDao.getSystemTemplateInfo(id); List<NotificationSendLog> logList = new ArrayList<>(); String content = templateDTO.getContent();//模板內容 Boolean result = false; int w=0;//操做結果 int count =0;//發送總條數 int sucNum=0;//發送成功條數 //查詢全部用戶列表 List<SecurityUser> userList =templateDao.getUserList(); if(templateDTO.getSendMode().equals("1")){//短信發送 }else if(templateDTO.getSendMode().equals("3")){//站內發送(桌面消息提示) if(templateDTO.getSendPeople().equals("1")){//我的用戶 }else if(templateDTO.getSendPeople().equals("2")){//企業用戶 WebSockets webSocket = new WebSockets(); List<User> onLineList =WebSockets.list;//獲取在線人人員id List<SecurityUser> userList1 = templateDao.getUserList(); List<NotificationUserLog> userLogList = new ArrayList<>(); for(SecurityUser list:userList1){ NotificationUserLog userLog = new NotificationUserLog(); //調用裝配發送日誌實體 NotificationSendLog sendLog =setSendLog(templateDTO,adminUser,list); userLog.setUserId(list.getId()); userLog.setMsgId(templateDTO.getId()); userLog.setMsgStatus(false); for(int i =0;i<onLineList.size();i++){ Long userId =onLineList.get(i).getUserId(); if(list.getId()==userId){ userLog.setMsgStatus(true); sendLog.setStatus(true);//發送成功 sucNum+=1; count+=1; } } userLogList.add(userLog); count= onLineList.size(); sucNum =onLineList.size(); logList.add(sendLog); } //插入發送系統通知與用戶的關聯關係 int ww = templateDao.insertUserSendLog(userLogList); webSocket.broadcast(templateDTO.getContent());//調用廣播() //插入系統日誌 String category="系統消息"; //調用生成發送日誌方法 NotificationLog notificationLog =assembleLog(adminUser,category,count,sucNum,templateDTO); int h = settingDao.insertLog(notificationLog); //插入發送日誌 w =templateDao.insertSendLog(logList); } } //修改發送狀態 templateDTO.setSendStatus(true); int z = templateDao.updateSystemTemplate(templateDTO); if(w>0){ return 200; } return 0;
注意點:項目在瀏覽器中訪問時,切記路徑要和websocket.js中的一致 瀏覽器
以上內容僅供參考,若是以上內容有所不當或者不清楚的能夠聯繫本人。技術在於溝通!websocket