• 记录Vue中使用websocket的正确姿势


    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

    1:首先谈谈websocket是什么?

    WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。
    WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

    2: vue中怎么使用

    实例代码

    <script>
      import store from '@/store/'
      export default {
        name: "HeaderNotice",
        components: {
        },
        data () {
          return {
            websock: null,
          }
        },
        computed:{
        },
        created() {
          this.initWebSocket();
        },
        mounted() {
          //this.initWebSocket();
        },
        destroyed: function () { // 离开页面生命周期函数
          this.websocketclose();
        },
        methods: {
          initWebSocket: function () {
            // WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
            console.log("调用了链接websock  ,获取的用户id为   :"+store.getters.userInfo.id)
            var userId = store.getters.userInfo.id;
            var url = window._CONFIG['domianURL'].replace("https://","wss://").replace("http://","ws://")+"/websocket/"+userId;
            console.log(url);
            this.websock = new WebSocket(url);
            this.websock.onopen = this.websocketOnopen;
            this.websock.onerror = this.websocketOnerror;
            this.websock.onmessage = this.websocketOnmessage;
            this.websock.onclose = this.websocketOnclose;
          },
          websocketOnopen: function () {
            console.log("WebSocket连接成功");
            //心跳检测重置
            //this.heartCheck.reset().start();
          },
          websocketOnerror: function (e) {
            console.log("WebSocket连接发生错误");
            this.reconnect();
          },
          websocketOnmessage: function (e) {
          	 console.log('监听关闭' + e)
            console.log("-----接收消息-------",e.data);
            var data = eval("(" + e.data + ")"); //解析对象
          },
          websocketOnclose: function (e) {
            console.log("connection closed (" + e.code + ")");
            this.reconnect();
          },
          websocketSend(text) { // 数据发送
            try {
              this.websock.send(text);
            } catch (err) {
              console.log("send failed (" + err.code + ")");
            }
          },
    
          reconnect() {
            var that = this;
            if(that.lockReconnect) return;
            that.lockReconnect = true;
            //没连接上会一直重连,设置延迟避免请求过多
            setTimeout(function () {
              console.info("尝试重连...");
              that.initWebSocket();
              that.lockReconnect = false;
            }, 5000);
          },
        }
      }
    </script>
    1. 手动关闭websocket
    this.websock.close()
    1. websocket链接地址,配置在index.html页面
     <script>
    	window._CONFIG['IP'] = '127.0.0.1';
        //后台接口访问
        window._CONFIG['domianURL'] = 'http://' + window._CONFIG['IP'] + ':9036/csp';
     </script>

    3:websocket的属性讲解

    1. 创建WebSocket 实例

      WebSocket 对象作为一个构造函数,用于新建 WebSocket 实例

     this.websock = new WebSocket(url);
    1. websocket属性
    binaryType: "blob"                    //返回websocket连接所传输二进制数据的类型,如果传输的是Blob类型的数据,则为"blob",如果传输的是Arraybuffer类型的数据,则为"arraybuffer"
      bufferedAmount: 0             //为只读属性,用于返回已经被send()方法放入队列中但还没有被发送到网络中的数据的字节数。
      extensions: ""
      onclose: ƒ ()               //连接关闭时触发
      onerror: ƒ ()               //通信发生错误时触发
      onmessage: ƒ (e)              //客户端接收服务端数据时触发,e为接受的数据对象
      onopen: ƒ ()                //连接建立时触发
      protocol: ""                 //用于返回服务器端选中的子协议的名字;这是一个在创建websocket对象时,在参数protocols中指定的字符串。
      readyState: 1                //返回值为当前websocket的链接状态
      url: "ws://1xx.xxx.xxx.xxx:8080/ws"    //返回值为当构造函数创建WebSocket实例对象时URL的绝对路径。
    1. websocket属性之readyState

      readyState返回当前websocket的链接状态,共有4种。可根据具体项目的需求来利用此状态,写对应的需求。

    CONNECTING:值为0,表示正在连接。
    OPEN:      值为1,表示连接成功,可以通信了。
    CLOSING:   值为2,表示连接正在关闭。
    CLOSED:    值为3,表示连接已经关闭,或者打开连接失败。

    4:手动关闭websocket

    this.websock.close()

    websocketOnclose方法打印信息
    监听关闭[object CloseEvent]
    GlobalHeader.vue?70ef:647 connection closed (1005)

    5.websocket封装

    可在项目中定义一个socket.js文件,在需要建立socket的页面引入此js文件

    import Vue from 'vue'
    import { Message } from 'element-ui'
    let v = new Vue()
    v.$message = Message;
    var webSocket = null;
    var isConnect = false; //连接状态
    var globalCallback = function(e){ console.log(e) };//定义外部接收数据的回调函数
    var reConnectNum = 0;//重连次数
    
    var websocketUrl =  process.env.VUE_APP_API_WEBSOCKET_URL;
    
    //心跳设置
    var heartCheck = {
        heartbeatData:{
            DevID:{
                value:Vue.ls.get('devid')
            },
            DevHeart:{
                value:"1"
            }   
        },//心跳包
        timeout: 60 * 1000, //每段时间发送一次心跳包 这里设置为60s
        heartbeat: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象)
        start: function () {
            this.heartbeat = setInterval(()=>{
                if (isConnect){
                    webSocketSend(this.heartbeatData);
                }else{
                    this.clear();
                }
            }, this.timeout);
        },
        reset: function () {
            clearInterval(this.heartbeat);
            this.start();
        },
        clear:function(){
            clearInterval(this.heartbeat);
        }
    }
    
    //初始化websocket
    function initWebSocket(callback) {
        //此callback为在其他地方调用时定义的接收socket数据的函数
        if(callback){
            if(typeof callback == 'function'){
                globalCallback = callback     
            }else{
                throw new Error("callback is not a function")
            }
        }
        if ("WebSocket" in window) {
            webSocket = new WebSocket(websocketUrl);//创建socket对象
        } else {
            Message({
                message: '该浏览器不支持websocket!',
                type: 'warning'
            });
            return
        }
        //打开
        webSocket.onopen = function() {
            webSocketOpen();
        };
        //收信
        webSocket.onmessage = function(e) {
            webSocketOnMessage(e);
        };
        //关闭
        webSocket.onclose = function(e) {
            webSocketOnClose(e);
        };
        //连接发生错误的回调方法
        webSocket.onerror = function(e) {
            webSocketonError(e);
        };
    }
    
    //连接socket建立时触发
    function webSocketOpen() {
        console.log("WebSocket连接成功");
        //首次握手
        webSocketSend(heartCheck.heartbeatData);
        isConnect = true;
        heartCheck.start();
        reConnectNum = 0;
    }
    
    //客户端接收服务端数据时触发,e为接受的数据对象
    function webSocketOnMessage(e) {
        console.log("websocket信息:");
        console.log(e.data)
        const data = JSON.parse(e.data);//根据自己的需要对接收到的数据进行格式化
        globalCallback(data);//将data传给在外定义的接收数据的函数,至关重要。
    }
    
    //socket关闭时触发
    function webSocketOnClose(e){
        heartCheck.clear();
        isConnect = false; //断开后修改标识
        console.log(e)
        console.log('webSocket已经关闭 (code:' + e.code + ')')
        //被动断开,重新连接
        if(e.code == 1006){
            if(reConnectNum < 3){
                initWebSocket();
                ++reConnectNum;
            }else{
                v.$message({
                    message: 'websocket连接不上,请刷新页面或联系开发人员!',
                    type: 'warning'
                });
            }
        }
    }
    
    //连接发生错误的回调方法
    function webSocketonError(e){
        heartCheck.clear();
        isConnect = false; //断开后修改标识
        console.log("WebSocket连接发生错误:");
        console.log(e);
    }
    
    
    //发送数据
    function webSocketSend(data) {
        webSocket.send(JSON.stringify(data));//在这里根据自己的需要转换数据格式
    }
    //在其他需要socket地方主动关闭socket
    function closeWebSocket(e) {
        webSocket.close();
        heartCheck.clear();
        isConnect = false;
        reConnectNum = 0;
    }
    //在其他需要socket地方接受数据
    function getSock(callback) {
        globalCallback = callback
    }
    //在其他需要socket地方调用的函数,用来发送数据及接受数据
    function sendSock(agentData) {
        //下面的判断主要是考虑到socket连接可能中断或者其他的因素,可以重新发送此条消息。
        switch (webSocket.readyState) {
            //CONNECTING:值为0,表示正在连接。
            case webSocket.CONNECTING:
                setTimeout(function() {
                    sendSock(agentData, callback);
                }, 1000);
            break;
            //OPEN:值为1,表示连接成功,可以通信了。
            case webSocket.OPEN:
                webSocketSend(agentData);
            break;
            //CLOSING:值为2,表示连接正在关闭。
            case webSocket.CLOSING:
                setTimeout(function() {
                    sendSock(agentData, callback);
                }, 1000);
            break;
            //CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
            case webSocket.CLOSED:
            // do something
            break;
            default:
            // this never happens
            break;
        }
    }
    
    export default {
      initWebSocket,
      closeWebSocket,
      sendSock,
      getSock
    };

    引入

    import Vue from 'vue'
    import socketApi from "./utils/socket";//找到封装的socket.js文件
    Vue.prototype.socketApi = socketApi;//将其挂在原型上,这样 $socketApi就在所有的 Vue 实例中可用了。

    在某一页面

    <template>
    </template>
    <script>
    export default {
    	mounted(){
    	   // 建立socket连接, 并设置socket信息返回接受函数   
    	   this.$socketApi.initWebSocket(this.getsocketResult);
    	},
    	beforeDestroy(){
    	   this.$socketApi.closeWebSocket();
    	},
    	methods:{
    	   // socket信息返回接受函数
    	   getsocketResult(data) {
    	     console.log(data);
    	   },
    	   //发送socket信息
    	   websocketSend(data) {
    	     this.$socketApi.sendSock(data);
    	   }
    	}
    }
    </script>
    <style>
    </style>

    本文转载于:

    https://blog.csdn.net/weixin_43422861

    如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

     

  • 相关阅读:
    Windows FFMPEG开发环境配置
    双网卡单IP实现网卡冗余与负载均衡
    Thinking in Java 4th(Java编程思想第四版)文档、源码、习题答案(偶尔回顾)
    IDEA编译时出现 Information:java: javacTask: 源发行版 1.8 需要目标发行版 1.8
    运行java飞行记录器JFR(java flight recorder)
    Java黑科技之源:JVMTI完全解读
    jvisualvm安装visualgc插件
    系统运行缓慢,CPU 100%,以及Full GC次数过多问题的排查思路
    Jenkins 改成中文语言显示
    windows上Jenkins安装及其配置
  • 原文地址:https://www.cnblogs.com/smileZAZ/p/16506083.html
Copyright © 2020-2023  润新知