记录--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> |
- 手动关闭websocket
1 | this .websock.close() |
- 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的属性讲解
- 创建WebSocket 实例
WebSocket 对象作为一个构造函数,用于新建 WebSocket 实例
1 | this .websock = new WebSocket(url); |
- 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的绝对路径。 |
- 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__
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 本地部署 DeepSeek:小白也能轻松搞定!
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 从 Windows Forms 到微服务的经验教训
· 李飞飞的50美金比肩DeepSeek把CEO忽悠瘸了,倒霉的却是程序员
· 超详细,DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方Dee