封装websocket请求-----vue项目实战(完整版)

前言:
如果项目中多个组件都使用到WebSocket请求,那么我们需要对WebSocket进行封装,方便我们使用。

下面我根据我的项目结构来创建文件和引入文件,大家注意一下自己项目结构。

一、在utils目录下创建websocket.js文件

import { Message } from 'element-ui'
import { getToken } from '@/utils/authToken' // 与后端的协商,websocket请求需要带上token参数
let websock = null
let messageCallback = null
let errorCallback = null
let wsUrl = ''
let tryTime = 0
 
// 接收ws后端返回的数据
function websocketonmessage (e) { 
  messageCallback(JSON.parse(e.data))
}
 
/**
 * 发起websocket连接
 * @param {Object} agentData 需要向后台传递的参数数据
 */
function websocketSend (agentData) {
  // 加延迟是为了尽量让ws连接状态变为OPEN   
  setTimeout(() => { 
    // 添加状态判断,当为OPEN时,发送消息
    if (websock.readyState === websock.OPEN) { // websock.OPEN = 1 
      // 发给后端的数据需要字符串化
      websock.send(JSON.stringify(agentData))
    }
    if (websock.readyState === websock.CLOSED) { // websock.CLOSED = 3 
      console.log('websock.readyState=3')
      Message.error('ws连接异常,请稍候重试')
      errorCallback()
    }
  }, 500)
}
 
// 关闭ws连接
function websocketclose (e) {  
  // e.code === 1000  表示正常关闭。 无论为何目的而创建, 该链接都已成功完成任务。
  // e.code !== 1000  表示非正常关闭。
  if (e && e.code !== 1000) {
    Message.error('ws连接异常,请稍候重试')
    errorCallback()
    // // 如果需要设置异常重连则可替换为下面的代码,自行进行测试
    // if (tryTime < 10) {
    //   setTimeout(function() {
    //    websock = null
    //    tryTime++
    //    initWebSocket()
    //    console.log(`第${tryTime}次重连`)
    //  }, 3 * 1000)
    //} else {
    //  Message.error('重连失败!请稍后重试')
    //}
  }
}
// 建立ws连接
function websocketOpen (e) {
  // console.log('ws连接成功')
}
 
// 初始化weosocket
function initWebSocket () { 
  if (typeof (WebSocket) === 'undefined') {
    Message.error('您的浏览器不支持WebSocket,无法获取数据')
    return false
  }
  
  const token = 'JWT=' + getToken()
  // ws请求完整地址
  const requstWsUrl = wsUrl + '?' + token
  websock = new WebSocket(requstWsUrl)

  websock.onmessage = function (e) {
    websocketonmessage(e)
  } 
  websock.onopen = function () {
    websocketOpen()
  }
  websock.onerror = function () {
    Message.error('ws连接异常,请稍候重试')
    errorCallback()
  }
  websock.onclose = function (e) {
    websocketclose(e)
  } 
}
 
/**
 * 发起websocket请求函数
 * @param {string} url ws连接地址
 * @param {Object} agentData 传给后台的参数
 * @param {function} successCallback 接收到ws数据,对数据进行处理的回调函数
 * @param {function} errCallback ws连接错误的回调函数
 */
export function sendWebsocket (url, agentData, successCallback, errCallback) { 
  wsUrl = url
  initWebSocket()
  messageCallback = successCallback
  errorCallback = errCallback
  websocketSend(agentData)
}

/**
 * 关闭websocket函数
 */
export function closeWebsocket () {
  if (websock) {
    websock.close() // 关闭websocket
    websock.onclose() // 关闭websocket
  }
}

二、在vue组件中使用WebSocket封装好的功能

<template>
  <div>
    <button @click="requstWs">点击发起websocket请求</button>
  </div>
</template>
<script>
import { sendWebsocket, closeWebsocket } from '@/utils/websocket.js'

export default {
  beforeDestroy () {
    // 页面销毁时关闭ws。因为有可能ws连接接收数据尚未完成,用户就跳转了页面
    // 在需要主动关闭ws的地方都可以调用该方法
    closeWebsocket()
  },
  methods: {
    // ws连接成功,后台返回的ws数据,组件要拿数据渲染页面等操作
    wsMessage (data) {
      const dataJson = data
      console.log(dataJson)
      // 这里写拿到数据后的业务代码
    },
    // ws连接失败,组件要执行的代码
    wsError () {
      // 比如取消页面的loading
    },
    requstWs () {
      // 防止用户多次连续点击发起请求,所以要先关闭上次的ws请求。
      closeWebsocket()
      // 跟后端协商,需要什么参数数据给后台
      const obj = {
        monitorUrl: 'xxxxxxxxxxxxx',
        userName: 'xxxxxxxxxx'
      }
      // 发起ws请求
      sendWebsocket('ws://test.ws.com', obj, this.wsMessage, this.wsError)
    }
  }
}
</script>

介绍WebSocket对象中的readyState属性
WebSocket的readyState属性用来定义连接状态,该属性的值有下面几种:

0 :对应常量 CONNECTING
正在建立连接连接,还没有完成。
1 :对应常量 OPEN
连接成功建立,可以进行通信。
2 :对应常量 CLOSING
连接正在进行关闭握手,即将关闭。
3 : 对应常量 CLOSED
连接已经关闭或者根本没有建立。
————————————————

介绍WebSocket断开连接onclose的重要信息错误状态码
WebSocket断开时,会触发CloseEvent, CloseEvent会在连接关闭时发送给使用 WebSockets 的客户端. 它在 WebSocket 对象的 onclose 事件监听器中使用。CloseEvent的code字段表示了WebSocket断开的原因。可以从该字段中分析断开的原因。

CloseEvent有三个字段需要注意, 通过分析这三个字段,一般就可以找到断开原因。

CloseEvent.code: code是错误码,是整数类型
CloseEvent.reason: reason是断开原因,是字符串
CloseEvent.wasClean: wasClean表示是否正常断开,是布尔值。一般正常断开时,该值为true

如下是在关闭ws连接的时候打印出来的CloseEvent对象

 

关闭状态码表

下面标红的状态码是我在项目中测试遇到过的。

状态码    描述
0–999    保留段, 未使用
1000    正常关闭; 无论为何目的而创建, 该链接都已成功完成任务.
1001    终端离开, 可能因为服务端错误, 也可能因为浏览器正从打开连接的页面跳转离开.
1002    由于协议错误而中断连接.
1003    由于接收到不允许的数据类型而断开连接 (如仅接收文本数据的终端接收到了二进制数据).
1004    保留. 其意义可能会在未来定义.
1005    保留. 表示没有收到预期的状态码.
1006    保留. 用于期望收到状态码时连接非正常关闭 (也就是说, 没有发送关闭帧).
1007    由于收到了格式不符的数据而断开连接 (如文本消息中包含了非 UTF-8 数据).
1008    由于收到不符合约定的数据而断开连接. 这是一个通用状态码, 用于不适合使用 1003 和 1009 状态码的场景.
1009    由于收到过大的数据帧而断开连接.
1010    客户端期望服务器商定一个或多个拓展, 但服务器没有处理, 因此客户端断开连接.
1011    客户端由于遇到没有预料的情况阻止其完成请求, 因此服务端断开连接.
1012    服务器由于重启而断开连接.
1013    服务器由于临时原因断开连接, 如服务器过载因此断开一部分客户端连接.
1014    由 WebSocket标准保留以便未来使用.
1015    保留. 表示连接由于无法完成 TLS 握手而关闭 (例如无法验证服务器证书).
1016–1999    由 WebSocket标准保留以便未来使用.
2000–2999    由 WebSocket拓展保留使用.
ps: 其他注意事项
如果你的服务所用的协议是HTTPS的,那么使用的WebSocket协议也必须是wss, 而不能是ws

最后!!!提供个完整的测试例子给大家学习
仓库中的代码比上面的封装代码还要详细:包括失败重连、心跳检测等,还有详细的注释。
在vscode编辑器中安装Live Server插件,如下图在index.html文件中右键操作即可运行测试。仓库地址:websocket-test-project: 测试js原生websocket的例子
更多好用的vscode插件可看: 这里项目开发应该知道这些vscode插件(40+个)_winne雪的博客-CSDN博客_vscode 查看svg

 

  • 7
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值