這篇文章給大家介紹SpringMVC中怎么開放WebSocket接口,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
創(chuàng)新互聯(lián)2013年至今,是專業(yè)互聯(lián)網(wǎng)技術服務公司,擁有項目成都網(wǎng)站制作、成都做網(wǎng)站、外貿營銷網(wǎng)站建設網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元懷柔做網(wǎng)站,已為上家服務,為懷柔各地企業(yè)和個人服務,聯(lián)系電話:028-86922220
1)首先創(chuàng)建websocket專屬的package(規(guī)范問題,實現(xiàn)某一功能的源碼應放到統(tǒng)一路徑下)。
2)創(chuàng)建WebSocketConfig類,繼承WebMvcConfigurationSupport類,實現(xiàn)WebSocketConfigurer接口并實現(xiàn)其定義的方法。添加類注解
@Configuration
@EnableWebMvc
@EnableWebSocket
3)實現(xiàn)的registerWebSocketHandlers方法中,使用參數(shù)WebSocketHandlerRegistry的對象開放WebSocket接口。
registry.addHandler(websocket消息處理實現(xiàn)類實例,websocket地址).setAllowedOrigins("*").addInterceptors(攔截器實例);
其中setAllowedOrigins為設置訪問權限,通常不限制訪問時使用“*”;addInterceptors為添加攔截器,如果不需要攔截器則可不調用此方法。
通常開放WebSocket接口開放兩個,因瀏覽器支持的問題,前端只能使用SockJS插件實現(xiàn)WebSocket連接,所以我們還要開放一個專為SockJS服務的WebSocket接口,只需調用withSockJS接口即可。
registry.addHandler(websocket消息處理實現(xiàn)類實例,websocket地址).setAllowedOrigins("*").addInterceptors(攔截器實例).withSockJS();
至此,第一步,配置WebSocket信息已完成。
1)創(chuàng)建WebSocket消息處理接口,繼承WebSocketHandler接口(為開放操作接口給其他服務調用,一般與業(yè)務相關,服務端希望推送消息時調用此接口,同樣關乎規(guī)范,亦可使用其他方式實現(xiàn))。
2)創(chuàng)建WebSocket消息處理實現(xiàn)類,實現(xiàn)第一步創(chuàng)建的接口。其中,業(yè)務接口請自行實現(xiàn),從WebSocketHandler繼承實現(xiàn)的接口有:
afterConnectionEstablished:建立WebSocket連接成功時觸發(fā)。
handleMessage:收到客戶端發(fā)送的消息時觸發(fā)。
handleTransportError:發(fā)生異常時觸發(fā)。
afterConnectionClosed:與客戶端斷開連接時觸發(fā)。
supportsPartialMessages:是否支持部分消息處理(一般返回false,此標志一般用來拆分大型或未知大小的WebSocket消息,當支持部分消息時,一個消息會拆分成多個消息調用handleMessage,可以利用WebSocketMessage的isLast方法判斷是否最后一次消息)。
1)創(chuàng)建WebSocket攔截器,實現(xiàn)HandshakeInterceptor接口。實現(xiàn)方法有:
beforeHandshake:消息處理前。
afterHandshake:消息處理后。
此處使用配置掃描包的形式,在配置文件中添加<context:component-scan base-package="com.???.???.???.websocket" />
其中base-package可以根據(jù)自己項目的實際包路徑配置。
下面就是實例代碼,細節(jié)處可根據(jù)實際項目修改:
WebSocket配置信息
package com.???.???.???.websocket; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowire; 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.WebMvcConfigurationSupport; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; /** * websocket配置類 * * @author Heller.Zhang * @since 2018年11月8日 上午10:23:04 */ @Configuration @EnableWebMvc @EnableWebSocket public class MyWebSocketConfig extends WebMvcConfigurationSupport implements WebSocketConfigurer { private Logger logger = LoggerFactory.getLogger(MyWebSocketConfig.class); /* (non-Javadoc) * @see org.springframework.web.socket.config.annotation.WebSocketConfigurer#registerWebSocketHandlers(org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry) */ @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { logger.debug("----------開始注冊MyWebSocketConfig----------"); logger.debug("----------注冊普通websocket----------"); registry.addHandler(msgSocketHandle(), "/websocket/myWebSocketServer").setAllowedOrigins("*"); logger.debug("----------注冊sockjs/websocket----------"); registry.addHandler(msgSocketHandle(), "/websocket/sockjs/myWebSocketServer").setAllowedOrigins("*").withSockJS(); } @Bean(name = "myMsgScoketHandle", autowire = Autowire.BY_NAME) public MyMsgScoketHandle msgSocketHandle() { return new MyMsgScoketHandleImpl(); } }
自定義WebSocket消息處理接口
package com.???.???.???.websocket; import org.springframework.web.socket.WebSocketHandler; /** * websocket消息處理器 * * @author Heller.Zhang * @since 2018年11月13日 下午5:13:20 */ public interface MyMsgScoketHandle extends WebSocketHandler { public void sendMessage(Long userId, Integer num); }
自定義WebSocket消息處理接口實現(xiàn)
package com.???.???.???.websocket; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketMessage; import org.springframework.web.socket.WebSocketSession; import com.hzsparrow.framework.common.exception.ServiceException; import com.hzsparrow.framework.utils.JsonUtils; import com.hzsparrow.framework.utils.NumberUtils; /** * websocket消息處理類 * * @author Heller.Zhang * @since 2018年11月8日 上午11:15:22 */ public class MyMsgScoketHandleImpl implements MyMsgScoketHandle { private Logger logger = LoggerFactory.getLogger(MyMsgScoketHandleImpl.class); private ConcurrentMap<String, List<WebSocketSession>> webSocketMap = new ConcurrentHashMap<>(); public MyMsgScoketHandleImpl() { logger.debug("--------init MyMsgScoketHandle-----------"); } /* (non-Javadoc) * @see org.springframework.web.socket.WebSocketHandler#afterConnectionEstablished(org.springframework.web.socket.WebSocketSession) */ @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { logger.debug("-----------建立websocket連接---------"); } /* (non-Javadoc) * @see org.springframework.web.socket.WebSocketHandler#handleMessage(org.springframework.web.socket.WebSocketSession, org.springframework.web.socket.WebSocketMessage) */ @Override public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { logger.debug("-----------處理消息---------"); TextMessage msg = (TextMessage) message; //建立連接發(fā)送的用戶id String msgStr= msg.getPayload(); logger.debug("----------msg:" + msgStr); if (StringUtils.equals(msgStr, "heartbeat")) { // 心跳消息,不予處理 return; } session.getAttributes().put("mykey", msgStr + "|" + UUID.randomUUID().toString()); //通過用戶id獲取session集合 List<WebSocketSession> list = webSocketMap.get(msgStr); //判斷集合是否為空 if (CollectionUtils.isNotEmpty(list)) { list.add(session); } else { list = new ArrayList<WebSocketSession>(); list.add(session); } //將用戶id和session集合綁定到map webSocketMap.put(msgStr, list); logger.debug("消息處理完畢"); } /* (non-Javadoc) * @see org.springframework.web.socket.WebSocketHandler#handleTransportError(org.springframework.web.socket.WebSocketSession, java.lang.Throwable) */ @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { logger.debug("-----------處理異常---------"); } /* (non-Javadoc) * @see org.springframework.web.socket.WebSocketHandler#afterConnectionClosed(org.springframework.web.socket.WebSocketSession, org.springframework.web.socket.CloseStatus) */ @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { logger.debug("-----------斷開連接---------"); String myKey = session.getAttributes().get("mykey").toString(); String userId = myKey.split("|")[0]; List<WebSocketSession> list = webSocketMap.get(userId); WebSocketSession delSession = null; if (CollectionUtils.isNotEmpty(list)) { for (WebSocketSession webSocketSession : list) { String delKey = webSocketSession.getAttributes().get("mykey").toString(); if (StringUtils.equals(myKey, delKey)) { delSession = webSocketSession; break; } } } if (delSession != null) { list.remove(delSession); } } /* (non-Javadoc) * @see org.springframework.web.socket.WebSocketHandler#supportsPartialMessages() */ @Override public boolean supportsPartialMessages() { return false; } /** * 給單個用戶發(fā)送消息 * * @param session * @param type * @param data * @throws IOException * @author Heller.Zhang * @since 2018年11月8日 下午2:05:32 */ public void sendMessage(WebSocketSession session, Object data) throws IOException { if (session.isOpen()) { String json = JsonUtils.serialize(data); TextMessage outMsg = new TextMessage(json); session.sendMessage(outMsg); } } /** * 發(fā)送鏈接成功消息 * * @param session * @throws IOException * @author Heller.Zhang * @since 2018年11月10日 下午3:16:35 */ public void sendSuccessMsg(WebSocketSession session, Integer type) throws IOException { logger.debug("---------發(fā)送鏈接成功消息-----------"); TextMessage outMsg = new TextMessage(""); session.sendMessage(outMsg); } @Override public void sendMessage(Long userId, Integer num) { //獲取用戶下的session集合 List<WebSocketSession> list = webSocketMap.get(NumberUtils.num2Str(userId)); //向每一條session中發(fā)送數(shù)據(jù) if (CollectionUtils.isNotEmpty(list)) { for (WebSocketSession webSocketSession : list) { try { sendMessage(webSocketSession, num); } catch (IOException e) { throw new ServiceException("發(fā)送消息失敗"); } } } } }
攔截器
package com.???.???.???.websocket; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.HandshakeInterceptor; /** * websocket攔截器 * * @author Heller.Zhang * @since 2018年11月8日 上午10:40:51 */ public class MyWebSocketHandshakeInterceptor implements HandshakeInterceptor { private Logger logger = LoggerFactory.getLogger(MyWebSocketHandshakeInterceptor.class); /* (non-Javadoc) * @see org.springframework.web.socket.server.HandshakeInterceptor#beforeHandshake(org.springframework.http.server.ServerHttpRequest, org.springframework.http.server.ServerHttpResponse, org.springframework.web.socket.WebSocketHandler, java.util.Map) */ @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { logger.debug("---------websocket 攔截器 握手前------------"); return true; } /* (non-Javadoc) * @see org.springframework.web.socket.server.HandshakeInterceptor#afterHandshake(org.springframework.http.server.ServerHttpRequest, org.springframework.http.server.ServerHttpResponse, org.springframework.web.socket.WebSocketHandler, java.lang.Exception) */ @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { logger.debug("---------websocket 攔截器 握手后------------"); } }
掃描包配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <context:component-scan base-package="com.???.???.???.websocket" /> </beans>
關于SpringMVC中怎么開放WebSocket接口就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
分享標題:SpringMVC中怎么開放WebSocket接口
鏈接URL:http://muchs.cn/article34/jpippe.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供外貿網(wǎng)站建設、定制網(wǎng)站、建站公司、標簽優(yōu)化、App設計、響應式網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)