- A+
所属分类:Web前端
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
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>
- 手动关闭websocket
this.websock.close()
- websocket链接地址,配置在index.html页面
<script> window._CONFIG['IP'] = '127.0.0.1'; //后台接口访问 window._CONFIG['domianURL'] = 'http://' + window._CONFIG['IP'] + ':9036/csp'; </script>
3:websocket的属性讲解
- 创建WebSocket 实例
WebSocket 对象作为一个构造函数,用于新建 WebSocket 实例
this.websock = new WebSocket(url);
- 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的绝对路径。
- 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>