ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

【websocket合集1】uni-app 小程序 WebSocket 接入说明

【websocket合集1】uni-app 小程序 WebSocket 接入说明 uni-app 小程序 WebSocket 接入说明这篇文章记录当前项目里的utils/order-websocket.js是怎么工作的以及其他页面要怎么接入 WebSocket。当前这个 WebSocket 主要用于订单状态变化通知。比如后端取消订单、订单状态更新后前端不用一直轮询接口后端可以直接推一条消息给小程序。小程序收到消息后再刷新当前页面的数据。一、整体流程现在的流程可以理解成这样页面调用addOrderUpdateListener()注册监听。utils/order-websocket.js自动建立 WebSocket 连接。连接成功后前端发送 STOMP 的CONNECT消息。后端确认连接后前端订阅/user/queue/order-updates。后端有订单变化时向当前用户推送订单 ID。前端收到订单 ID 后通知页面执行刷新逻辑。页面不用自己处理连接、重连、订阅、解析消息。页面只需要关心一件事收到订单 ID 之后要不要刷新当前页面。二、后端和前端约定当前后端发送消息的方式类似这样simpMessagingTemplate.convertAndSendToUser(userId,/queue/order-updates,orderId);前端订阅的地址是/user/queue/order-updates这里要注意后端发的是/queue/order-updates前端订阅的是/user/queue/order-updates后端发给哪个userId这个用户的小程序才会收到当前消息内容一般是订单 ID比如208xxx如果后端以后改成发 JSON也可以兼容{orderId:208xxx}三、utils/order-websocket.js负责什么这个文件是 WebSocket 的统一封装。它主要做这些事情根据当前环境自动生成 WebSocket 地址建立 WebSocket 连接发送 STOMP 连接消息订阅订单更新队列接收后端推来的消息从消息里解析订单 ID通知页面刷新数据断线后自动重连页面隐藏或退出时取消页面自己的监听这样做的好处是每个页面不用重复写连接代码只要注册自己的刷新方法。四、几个关键配置1. WebSocket 路径constORDER_WS_PATH/ws这个是后端 WebSocket 的路径。当前接口地址类似http://192.168.0.114:9003/api/wxapp前端会自动推导成ws://192.168.0.114:9003/api/wxapp/ws如果以后项目的网关前缀变了比如不是/api/wxapp就要改getGatewayWsBaseUrl()里面拼地址的逻辑。2. 订阅地址constORDER_DESTINATION/user/queue/order-updates这个必须和后端保持一致。如果后端改成convertAndSendToUser(userId,/queue/message-updates,data)那前端就要改成constORDER_DESTINATION/user/queue/message-updates3. 重连时间constRECONNECT_DELAY5000意思是断开后 5 秒再重连。这样可以处理网络切换、锁屏、后端重启等情况。五、页面怎么接入页面接入时一般只需要三步。第一步引入方法import{addOrderUpdateListener}from/utils/order-websocketimport{onShow,onHide,onUnload}fromdcloudio/uni-app第二步定义取消监听变量letremoveOrderUpdateListenernull这个变量用来保存“取消监听”的方法。页面隐藏或者退出时要调用它避免页面重复注册监听。第三步在页面显示时注册监听onShow((){removeOrderUpdateListener?.()removeOrderUpdateListeneraddOrderUpdateListener((orderId){// 收到后端推来的订单 ID// 这里写当前页面自己的刷新逻辑loadData()})})页面隐藏和退出时取消监听onHide((){removeOrderUpdateListener?.()removeOrderUpdateListenernull})onUnload((){removeOrderUpdateListener?.()removeOrderUpdateListenernull})六、列表页怎么写列表页一般不需要关心具体是哪个订单变化。只要有订单变化就刷新当前列表。示例import{addOrderUpdateListener}from/utils/order-websocketimport{onShow,onHide,onUnload}fromdcloudio/uni-appletremoveOrderUpdateListenernullonShow((){getOrderList()removeOrderUpdateListener?.()removeOrderUpdateListeneraddOrderUpdateListener((){currentPage.value1getOrderList()})})onHide((){removeOrderUpdateListener?.()removeOrderUpdateListenernull})onUnload((){removeOrderUpdateListener?.()removeOrderUpdateListenernull})适合这些页面订单列表消息列表回收员首页订单列表运输员订单列表七、详情页怎么写详情页最好判断一下后端推来的订单 ID是不是当前页面正在看的订单。如果不是当前订单就不刷新。示例import{addOrderUpdateListener}from/utils/order-websocketimport{onShow,onHide,onUnload}fromdcloudio/uni-appconstidref()letremoveOrderUpdateListenernullonShow((){removeOrderUpdateListener?.()removeOrderUpdateListeneraddOrderUpdateListener((orderId){if(String(orderId)!String(id.value))returngetOrderDetail(id.value)uni.showToast({title:订单状态已更新,icon:none})})})onHide((){removeOrderUpdateListener?.()removeOrderUpdateListenernull})onUnload((){removeOrderUpdateListener?.()removeOrderUpdateListenernull})适合这些页面订单详情待接单详情派单详情支付详情八、消息页怎么写消息页收到 WebSocket 推送后一般重新拉第一页消息。示例import{addOrderUpdateListener}from/utils/order-websocketimport{onShow,onHide,onUnload}fromdcloudio/uni-appletremoveOrderUpdateListenernullonShow((){loadMessages(true)removeOrderUpdateListener?.()removeOrderUpdateListeneraddOrderUpdateListener((){loadMessages(true)})})onHide((){removeOrderUpdateListener?.()removeOrderUpdateListenernull})onUnload((){removeOrderUpdateListener?.()removeOrderUpdateListenernull})九、为什么要在onHide和onUnload取消监听如果不取消监听会出现这些问题页面每进来一次就多注册一次监听后端只推一次消息页面可能刷新多次页面已经离开了还在执行刷新方法时间久了可能造成页面越来越卡所以每个页面都要记住removeOrderUpdateListener?.()removeOrderUpdateListenernull十、什么时候需要改utils/order-websocket.js普通页面接入时不需要改utils/order-websocket.js。只有这些情况才需要改后端 WebSocket 地址变了网关前缀变了后端订阅地址变了后端消息内容字段变了后端要求带 token 或其他身份信息后端不再使用 STOMP而是普通 WebSocket如果只是某个页面收到消息后刷新数据只改页面就可以。十一、如何测试测试时按这个顺序来打开需要接入 WebSocket 的页面。确认控制台没有 WebSocket 连接错误。让后端触发一次订单状态变化。看页面是否自动刷新。如果是详情页确认只有当前订单变化时才刷新。退出页面再进入确认不会重复刷新多次。如果连接失败先看是不是后端或网关没有正确支持 WebSocket。正常 WebSocket 连接时握手应该成功。如果用工具测试返回的是200通常说明后端或网关没有把请求升级成 WebSocket。十二、其他项目怎么复用可以复用这份封装但至少要检查四个地方WebSocket 地址是不是新项目的地址网关前缀是不是新项目的前缀订阅地址是不是后端给的新地址后端推来的字段是不是还是orderId如果新项目也是订单推送页面接入方式基本不用变。如果新项目是聊天、通知、任务状态更新也可以复用这个思路只是名字和字段要换一下。十三、常见问题1. 为什么页面没有刷新先确认后端有没有真的推消息。然后确认页面有没有调用addOrderUpdateListener()再确认后端推来的订单 ID和详情页当前的订单 ID 是否一致。2. 为什么刷新了很多次通常是页面重复注册了监听但是没有在onHide或onUnload取消。检查页面里有没有removeOrderUpdateListener?.()removeOrderUpdateListenernull3. 为什么列表页不用判断订单 ID列表页展示的是一批订单。只要其中一个订单变了重新拉一遍列表最简单。详情页只展示一个订单所以详情页才需要判断是不是当前订单。4. 为什么不用每个页面都自己连接 WebSocket因为一个小程序里不应该到处重复连接。现在统一封装后页面只注册刷新方法。连接、重连、订阅、解析消息都由utils/order-websocket.js处理。
返回列表