WebSocket集合SSM的第一次使用
阿新 • • 發佈:2020-07-27
一、新增依賴
<!-- WebSocket配置開始--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>4.3.25.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>4.3.25.RELEASE</version> </dependency> <!-- WebSocket配置結束-->
二、JAVA伺服器程式碼
1.SpringWebSocketConfig
package com.fz.websocket; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;import org.springframework.web.socket.handler.TextWebSocketHandler; @Configuration @EnableWebMvc @EnableWebSocket public class SpringWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer { public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(webSocketHandler(),"/websocket").addInterceptors(new SpringWebSocketHandlerInterceptor()); registry.addHandler(webSocketHandler(), "/sockjs").addInterceptors(new SpringWebSocketHandlerInterceptor()).withSockJS(); } @Bean public TextWebSocketHandler webSocketHandler(){ return new SpringWebSocketHandler(); } }
2.SpringWebSocketHandler
package com.fz.websocket; import java.io.IOException; import java.util.ArrayList; import org.apache.log4j.Logger; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; public class SpringWebSocketHandler extends TextWebSocketHandler { private static final ArrayList<WebSocketSession> users;//這個會出現效能問題,最好用Map來儲存,key用userid private static Logger logger = Logger.getLogger(SpringWebSocketHandler.class); static { users = new ArrayList<WebSocketSession>(); } public SpringWebSocketHandler() { // TODO Auto-generated constructor stub } /** * 連線成功時候,會觸發頁面上onopen方法 */ public void afterConnectionEstablished(WebSocketSession session) throws Exception { // TODO Auto-generated method stub System.out.println("connect to the websocket success......當前數量:"+users.size()); users.add(session); //這塊會實現自己業務,比如,當用戶登入後,會把離線訊息推送給使用者 int i=0; while (true){ TextMessage returnMessage = new TextMessage("訊息"+i); session.sendMessage(returnMessage); i++; Thread.sleep(3000); } } /** * 關閉連線時觸發 */ public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { logger.debug("websocket connection closed......"); String username= (String) session.getAttributes().get("WEBSOCKET_USERNAME"); System.out.println("使用者"+username+"已退出!"); users.remove(session); System.out.println("剩餘線上使用者"+users.size()); } /** * js呼叫websocket.send時候,會呼叫該方法 */ @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { super.handleTextMessage(session, message); } public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { if(session.isOpen()){session.close();} logger.debug("websocket connection closed......"); users.remove(session); } public boolean supportsPartialMessages() { return false; } /** * 給某個使用者傳送訊息 * * @param userName * @param message */ public void sendMessageToUser(String userName, TextMessage message) { for (WebSocketSession user : users) { if (user.getAttributes().get("WEBSOCKET_USERNAME").equals(userName)) { try { if (user.isOpen()) { user.sendMessage(message); } } catch (IOException e) { e.printStackTrace(); } break; } } } /** * 給所有線上使用者傳送訊息 * * @param message */ public void sendMessageToUsers(TextMessage message) { for (WebSocketSession user : users) { try { if (user.isOpen()) { user.sendMessage(message); } } catch (IOException e) { e.printStackTrace(); } } } }
3.SpringWebSocketHandlerInterceptor
package com.fz.websocket; import java.util.Map; import javax.servlet.http.HttpSession; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor; /** * WebSocket攔截器 * @author WANG * */ public class SpringWebSocketHandlerInterceptor extends HttpSessionHandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { // TODO Auto-generated method stub System.out.println("Before Handshake"); if (request instanceof ServletServerHttpRequest) { ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; HttpSession session = servletRequest.getServletRequest().getSession(false); if (session != null) { //使用userName區分WebSocketHandler,以便定向傳送訊息 String userName = (String) session.getAttribute("SESSION_USERNAME"); if (userName==null) { userName="default-system"; } attributes.put("WEBSOCKET_USERNAME",userName); } } return super.beforeHandshake(request, response, wsHandler, attributes); } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) { // TODO Auto-generated method stub super.afterHandshake(request, response, wsHandler, ex); } }
三、客戶端HTML程式碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <body> <input id="CreateSocket" type="button" value="建立WebSocKet" /> 收到訊息<p id="message"></p> <input id="Close" type="button" value="關閉WebSocket" /> </body> <script type="text/javascript"> var websocket = new WebSocket('ws://localhost:8080/websocket'); if ('WebSocket' in window){ websocket = new WebSocket('ws://localhost:8080/websocket'); } else{ console.log('該瀏覽器不支援WebSocket') } websocket.onopen = function(event) { console.log('WebSocket建立成功') } websocket.onclose = function (event) { console.log('連結關閉') }; websocket.onmessage = function (event) { document.getElementById('message').innerHTML=event.data console.log('收到訊息'+event.data) } websocket.onerror=function () { alert('websocket通訊發生錯誤') } websocket.onbeforeunload=function () { websocket.close() } </script> </body> </html>