Spring webScoket原生API整合Vue
之前这篇文章是基于stomp协议的:https://blog.csdn.net/niugang0920/article/details/83830867
但是以上测试环境就丢失连接(项目比较特殊怀疑是网络的问题),所以基于stomp的最终不合适虽然它是高级协议,最后搞了半天选择远程的websocket(但是它有限制)。
以下演示就是项目代码:
WebSocketConfig.java 【websocket配置】
package com.xdja.dsc.webscoket.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; 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 com.xdja.dsc.webscoket.service.SendReceiveMessageHandler; /** * * @ClassName: WebSocketConfig * @Description: 基于原生websocketAPI的配置 * @author niugang * @date 2018年11月9日 */ @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { // .withSockJS(); registry.addHandler(sendReceiveMessageHandler(), "/marco").setAllowedOrigins("*"); } @Bean public SendReceiveMessageHandler sendReceiveMessageHandler() { return new SendReceiveMessageHandler(); } }
SendReceiveMessageHandler.java 【消息处理发送类,定时任务为模拟发送】
package com.xdja.dsc.webscoket.service; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; 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; import com.alibaba.fastjson.JSONObject; import com.xdja.dsc.validation.exception.ServiceException; import com.xdja.dsc.validation.result.Result; /** * * @ClassName: SendReceiveMessageHandler * @Description: 发送消息处理器 * @author niugang * @date 2018年11月9日 */ @EnableScheduling @Component public class SendReceiveMessageHandler extends TextWebSocketHandler { private static final Map<String, WebSocketSession> ONLINEOBJECT; static { ONLINEOBJECT = new HashMap<String, WebSocketSession>(); } private static final Logger logger = LoggerFactory.getLogger(SendReceiveMessageHandler.class); @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { logger.info("received client message: " + message.getPayload()); // Thread.sleep(2000); // String exc = // "{\"result\":{\"nginx\":\"failed\",\"vtun\":\"OK\",\"getdns\":\"OK\",\"filter\":\"OK\",\"urlserver\":\"OK\",\"sysos\":\"Centos7\"}}"; // session.sendMessage(new TextMessage(exc)); } @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { logger.info("current sessionId [{}]", session.getId()); logger.info("connect to the websocket success......当前数量[{}]", ONLINEOBJECT.size()); ONLINEOBJECT.put(session.getId(), session); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { logger.info("connection closed .......status:{}", status); logger.info(" sessionId [{}] 已退出", session.getId()); ONLINEOBJECT.remove(session); logger.info("剩余在线数量:[{}]", ONLINEOBJECT.size()); } @Override public void handleTransportError(WebSocketSession session, Throwable thrwbl) throws Exception { if (session.isOpen()) { logger.info(" sessionId [{}] closed", session.getId()); session.close(); } } /** * 发送消息 * @param message * @date 2018年11月9日 * @throws */ public void sendMessageToClient(TextMessage message) { int count = 0; if (ONLINEOBJECT.size() > 0) { Set<Entry<String, WebSocketSession>> entrySet = ONLINEOBJECT.entrySet(); Iterator<Entry<String, WebSocketSession>> iterator = entrySet.iterator(); while (iterator.hasNext()) { Entry<String, WebSocketSession> next = iterator.next(); WebSocketSession user = next.getValue(); if (user.isOpen()) { try { user.sendMessage(message); count++; } catch (IOException e) { logger.error("api send message to client fail {}", e); } } } logger.info("actual send count [{}]", count); } } /** * 发送消息封装 * @param info * @date 2018年11月9日 * @throws */ public void sendMessage(Result info) { try { if (info == null) { throw new NullPointerException("info object not null"); } JSONObject jsonObject = new JSONObject(); jsonObject.put("code", info.getCode()); jsonObject.put("message", info.getMessage()); String resStr = jsonObject.toJSONString(); logger.info("send message to browser,message content [{}]", resStr); sendMessageToClient(new TextMessage(resStr)); } catch (Exception ex) { logger.error("send message exception [{}]", ex); } } /** * * 40秒讯轮模拟向浏览器推消息 * @date 2018年11月6日 * @throws */ @Scheduled(cron = "0/40 * * * * ? ") public void test() { this.sendMessage(new Result(ServiceException.Service.DUPLICATED)); } }
前端vue
<script> import SockJS from 'sockjs-client'; let api = require('../../../static/config.json').api; export default { data(){ return { tagsList: [], collapse: false, websock: null, timer:null } }, methods:{ //初始化 originInitWebSocket(){ let host=window.location.hostname; let port=api.split(":")[2]; const wsuri = "ws://"+host+":"+port+"/dsc/marco"; console.log("websocket connection url:"+wsuri); this.websock =new WebSocket(wsuri); this.websock.onopen=this.websocketsend; this.websock.onmessage = this.websocketonmessage; this.websock.onclose = this.websocketclose; }, websocketonmessage(e){ //数据接收 if(e&&e.data){ let res= JSON.parse(e.data); this.$notify({ title: '警告', message: res, type: 'warning' }); } }, websocketsend(){//数据发送 console.log("send test data to server..."); this.websock.send("test....."); }, websocketclose(e){ //关闭 console.log("client connection closed (" + e.code + ")"); } }, //销毁页面之前,断开连接 beforeDestroy: function () { this.websock.close();//离开路由之后断开websocket连接 }, mounted(){ //原始webscoketAPI this.originInitWebSocket(); }, } </script>
微信公众号