websocket结合promise的通信协议

1.前言

为什么会将websocketpromise所联系起来呢?

因为websocket不像http请求一样,发送的请求不会得到对应的回复,这样就会导致如果通过websocket发送消息之后,就无法对此消息进行追溯,使用起来非常不方便,并且很多功能无法实现,与客户端/服务端协调好数据个时候,就可以通过promise获取到消息的回执结果了

如何结合起来?

大致就是websocket的两端(客户端,服务端),提前确定好websocket消息的格式,进行协调,需要注意有个关键点,就是每个消息都会有一个唯一标识(uuid),发送到服务端的消息的状态以及promise的成功与失败,都需要根据这个唯一标识进行处理

2.步骤拆分

  1. 首先创建一个自定义的websocket的消息发送的方法
js 复制代码
const send = (param) => {}
  1. 在每个发送到服务端消息中都添加一个uuid,用于标识当前消息
js 复制代码
const send = (param) => {
    const data = {
        uuid:... // uuid
        ...param
    }
}
  1. 发送消息的方法返回一个promise,得到promiseresolvereject方法
js 复制代码
const send = (param) => {
  return new Promise((resolve,reject)=>{
    const data = {
        uuid:... // uuid
        ...param
    }
   })
}
  1. 创建一个空对象,对象中保存promiseresolvereject方法(这里可以自定义websocket消息超时的处理逻辑,可自行拓展)
js 复制代码
const send = (param) => {
  return new Promise((resolve,reject)=>{
    const data = {
        uuid:... // uuid
        ...param
    }
    const promiseData = {resolve,reject}
   })
}
  1. 将此对象添加到一个Map解构,其中的key就是唯一标识,value就是上方创建的对象,这样的话,每个消息都会有一个单独的对象,可以控制此消息的成功,失败,超时等等处理
js 复制代码
const receiverMap = new Map()
const send = (param) => {
  return new Promise((resolve,reject)=>{
    const data = {
        uuid:... // uuid
        ...param
    }
    const promiseData = {resolve,reject}
    receiverMap.set(data.uuid, promiseData)
   })
}
  1. 然后将websocket消息发送出去(需要保证在这些操作之前websocket已经连接了)
js 复制代码
const receiverMap = new Map()
const send = (param) => {
  return new Promise((resolve,reject)=>{
    const data = {
        uuid:... // uuid
        ...param
    }
    const promiseData = {resolve,reject}
    receiverMap.set(data.uuid, promiseData)
    webscoket.send(data)
   })
}
  1. 服务端接收到客户端发送的websocket消息之后,将唯一标识(uuid)提取出来,然后执行对应操作
  2. 对应操作执行成功或失败后按照与客户端协定好的格式返回给客户端,例如定义一个status字段,0表示成功,1表示执行失败,需要注意,这里的uuid也需要返回给客户端,客户端需要获取消息对应的请求是什么
  3. 客户端接收到请求后,将status,uuid字段解构出来,此时就可以通过uuidMap解构中获取到对应的promiseresolvereject方法了,此时再根据status的状态决定调用resolve还是reject即可
js 复制代码
 webscoket.addEventListener('message', (data)=>{
   // 解析messageData的内容
  const { uuid, status,param } = data
  // 获取当前接受到的消息所对应的websocket消息对象
  const msgRectiver = receiverMap.get(uuid)
  
  if(status === 0){
    msgRectiver.resolve(param)
  } else {
    msgRectiver.reject(param)
  }
 })
  1. 注意,请求收到后,无论失败还是成功,都需要将Map解构中当前的uuid删除掉,避免大量数据不清楚导致的Map解构过大
js 复制代码
 webscoket.addEventListener('message', (data)=>{
   // 解析messageData的内容
  const { uuid, status,param } = data
  // 获取当前接受到的消息所对应的websocket消息对象
  const msgRectiver = receiverMap.get(uuid)
  
  if(status === 0){
    msgRectiver.resolve(param)
  } else {
    msgRectiver.reject(param)
  }
  // 从Map中删除对应的消息
  receiverMap.delete(uuid)
 })

3.整体代码

js 复制代码
const receiverMap = new Map()
const send = (param) => {
  return new Promise((resolve,reject)=>{
    const data = {
        uuid:... // uuid
        ...param
    }
    const promiseData = {resolve,reject}
    receiverMap.set(data.uuid, promiseData)
    webscoket.send(data)
   })
}

 webscoket.addEventListener('message', (data)=>{
   // 解析messageData的内容
  const { uuid, status,param } = data
  // 获取当前接受到的消息所对应的websocket消息对象
  const msgRectiver = receiverMap.get(uuid)
  
  if(status === 0){
    msgRectiver.resolve(param)
  } else {
    msgRectiver.reject(param)
  }
  // 从Map中删除对应的消息
  receiverMap.delete(uuid)
 })

4.补充以及总结

这里只是大致实现了websocketpromise结合后的效果,内部可以进行很多其他的自定义操作,例如超时判断,消息警告,消息正在处理中,等等。

可以根据自己的需求进行调整,通过这里的方法,就可以对websocket消息进行追踪了,并且使用体验也比较好,可以直接使用.then,.catch等方法直接监听本次消息是否执行成功,以及获取到执行过程中服务端返回的一些数据!

到这里,本篇文章内容已经全部结束了,如果有什么其他的想法或者好的建议,欢迎大家私信或评论😁

相关推荐
还是大剑师兰特4 小时前
Vue3 中的 defineExpose 完全指南
前端·javascript·vue.js
吴佳浩4 小时前
GPU 编号进阶:CUDA\_VISIBLE\_DEVICES、多进程与容器化陷阱
人工智能·pytorch·python
泯泷4 小时前
阶段一:从 0 看懂 JSVMP 架构,先在脑子里搭出一台最小 JSVM
前端·javascript·架构
全栈凯哥5 小时前
18.Python中的导入类完全指南
python
sunwenjian8865 小时前
Java进阶——IO 流
java·开发语言·python
华洛5 小时前
利好打工人,openclaw不是企业提效工具,而是个人助理
前端·javascript·产品经理
xkxnq5 小时前
第六阶段:Vue生态高级整合与优化(第93天)Element Plus进阶:自定义主题(变量覆盖)+ 全局配置与组件按需加载优化
前端·javascript·vue.js
guts3506 小时前
图像篡改数据集下载:COVERAGE、CASIA
python·数据集
森林猿6 小时前
java-modbus-读取-modbus4j
java·网络·python
2401_879693876 小时前
将Python Web应用部署到服务器(Docker + Nginx)
jvm·数据库·python