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

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

1:首先谈谈websocket是什么?

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

2: vue中怎么使用

实例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<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
1
this.websock.close()
  1. websocket链接地址,配置在index.html页面
1
2
3
4
5
<script>
   window._CONFIG['IP'] = '127.0.0.1';
   //后台接口访问
   window._CONFIG['domianURL'] = 'http://' + window._CONFIG['IP'] + ':9036/csp';
</script>

3:websocket的属性讲解

  1. 创建WebSocket 实例

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

1
this.websock = new WebSocket(url);
  1. websocket属性
1
2
3
4
5
6
7
8
9
10
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种。可根据具体项目的需求来利用此状态,写对应的需求。

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

4:手动关闭websocket

1
this.websock.close()

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

5.websocket封装

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
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
};

引入

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

在某一页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<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

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

 


__EOF__

  • 本文作者: 林恒
  • 本文链接: https://www.cnblogs.com/smileZAZ/p/16506083.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • posted @   林恒  阅读(6293)  评论(0编辑  收藏  举报
    相关博文:
    阅读排行:
    · 本地部署 DeepSeek:小白也能轻松搞定!
    · 如何给本地部署的DeepSeek投喂数据,让他更懂你
    · 从 Windows Forms 到微服务的经验教训
    · 李飞飞的50美金比肩DeepSeek把CEO忽悠瘸了,倒霉的却是程序员
    · 超详细,DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方Dee
    又是一年情人节,2025年找到对象了嘛~
    点击右上角即可分享
    微信分享提示