一、首先在pom文件中引入Webscoekt的依賴html
<!-- websocket依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
二、經過註解方式構建Websocket服務java
package com.kk.server.chat.websocket; import com.kk.server.chat.service.CheckTokenService; import com.kk.server.chat.service.QueryService; import com.kk.server.chat.service.SaveMongodbService; import org.apache.log4j.Logger; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * Created by yxl on 2018-03-19. */ @ServerEndpoint("/chat/{userId}") //關鍵註解,將WebSocket服務端運行在 ws://[Server端IP或域名]:[Server端口]/websockets/chat/{userId} 的訪問端點,客戶端瀏覽器已經能夠對 WebSocket客戶端API發起HTTP長鏈接了。 @Component public class ChatWebsocket { private Logger logger = Logger.getLogger(ChatWebsocket.class); private static ApplicationContext applicationContext; private SaveMongodbService saveMongodbService; private CheckTokenService checkTokenService; private QueryService queryService; //靜態變量,用來記錄當前在線鏈接數。應該把它設計成線程安全的。 private static int onlineCount = 0; //concurrent包的線程安全Set,用來存放每一個客戶端對應的MyWebSocket對象。若要實現服務端與單一客戶端通訊的話,可使用Map來存放,其中Key能夠爲用戶標識 private static Map<String, Session> webSocketSet = new ConcurrentHashMap<>(); //醫生web //解決Websocket不能注入bean的問題 public static void setApplicationContext(ApplicationContext applicationContext) { ChatWebsocket.applicationContext = applicationContext; } /** * 鏈接創建成功調用的方法 * * @param userId 用戶連接ID */ @OnOpen //創建鏈接的註解,當用戶創建鏈接時SpringBoot會監聽到,而後會調用該註解下的方法 public void onOpen(@PathParam("userId") String userId, Session session) { webSocketSet.put(userId, session); } /** * 鏈接關閉調用的方法 */ @OnClose public void onClose(Session session) { logger.info("進入關閉方法!"); if (session != null) { Map<String, String> pathParameters = session.getPathParameters(); String userId = pathParameters.get("userId"); //從當前關閉session中獲取用戶ID,前提是創建websocket鏈接時帶有userId,即 @ServerEndpoint("/chat/{userId}") webSocketSet.remove(userId); //從map中移除用戶 } } /** * 收到客戶端消息後調用的方法 * * @param message 客戶端發送過來的消息 * @param session 可選的參數 */ @OnMessage public void onMessage(String message, Session session) throws IOException { try { JSONObject jsonObject = JSONObject.parseObject(message); String receiver_id = jsonObject.getString("receiver_id") //接受者ID,經過該Id來獲取接受者的session Session session = webSocketSet.get("receiver_id") if (session != null) { session.getBasicRemote.sendText(message); //經過session發送消息 }else { //TODO 接收方不在線,處理離線消息 } }catch(IOException e) { e.printStackTrace; } } /** * 發生錯誤時調用 * * @param session * @param error */ @OnError public void onError(Session session, Throwable error) { //onClose(); if (session != null) { Map<String, String> pathParameters = session.getPathParameters(); String userId = pathParameters.get("userId"); //從當前關閉session中獲取用戶ID,前提是創建websocket鏈接時帶有userId,即 @ServerEndpoint("/chat/{userId}") webSocketSet.remove(userId); //從map中移除用戶 } logger.info("webscoket發生錯誤!"+error.getMessage()); error.printStackTrace(); } }
三、前臺調用方法(js)web
function WebSocketTest() { if ("WebSocket" in window) { alert("您的瀏覽器支持 WebSocket!"); // 打開一個 web socket var ws = new WebSocket("ws://服務器IP:端口/chat/123"); ws.onopen = function() { // Web Socket 已鏈接上,使用 send() 方法發送數據 ws.send('{"userId":"1555855","message" : "test"}'); ws.close("666666"); alert("數據發送中..."); }; ws.onmessage = function (evt) { console.log(evt) alert(evt.data); alert("數據已接收..."); }; ws.onclose = function(){ // 關閉 websocket alert("鏈接已關閉..."); }; }else { // 瀏覽器不支持 WebSocket alert("您的瀏覽器不支持 WebSocket!"); } }
四、固然,在使用websocket聊天時,可能會遇到一些數據須要查詢數據庫或者Redis,可是在websocket中又不能直接注入相應的Bean實例,這個時候能夠看個人另外一篇博客http://www.javashuo.com/article/p-rhjkeoys-eb.htmlspring