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等方法直接监听本次消息是否执行成功,以及获取到执行过程中服务端返回的一些数据!

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

相关推荐
前端摸鱼匠2 分钟前
YOLOv8 环境配置全攻略:Python、PyTorch 与 CUDA 的和谐共生
人工智能·pytorch·python·yolo·目标检测
WangYaolove13148 分钟前
基于python的在线水果销售系统(源码+文档)
python·mysql·django·毕业设计·源码
AALoveTouch15 分钟前
大麦网协议分析
javascript·python
●VON25 分钟前
React Native for OpenHarmony:2048 小游戏的开发与跨平台适配实践
javascript·学习·react native·react.js·von
ZH154558913134 分钟前
Flutter for OpenHarmony Python学习助手实战:自动化脚本开发的实现
python·学习·flutter
xcLeigh1 小时前
Python入门:Python3 requests模块全面学习教程
开发语言·python·学习·模块·python3·requests
xcLeigh1 小时前
Python入门:Python3 statistics模块全面学习教程
开发语言·python·学习·模块·python3·statistics
YongCheng_Liang1 小时前
从零开始学 Python:自动化 / 运维开发实战(核心库 + 3 大实战场景)
python·自动化·运维开发
鸽芷咕1 小时前
为什么越来越多开发者转向 CANN 仓库中的 Python 自动化方案?
python·microsoft·自动化·cann
秋邱1 小时前
用 Python 写出 C++ 的性能?用CANN中PyPTO 算子开发硬核上手指南
开发语言·c++·python