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>

微信公众号

                          
原文地址:https://www.cnblogs.com/niugang0920/p/12187104.html