如何实现RSocket返回的数据可在不同浏览器标签页同步获取?
问题根因
你当前调用的是RSocket的requestResponse交互模式,属于单次请求-单次响应的点对点同步模式,仅发起请求的客户端连接会话能收到服务端返回,所以只有触发操作的标签页能拿到数据。
改造方案
1. 后端RSocket逻辑调整(全场景生效正解)
需要新增广播类的路由接口,采用requestStream交互模式实现全量推送:
- 后端接收到
insert.notification请求插入通知成功后,不要仅给当前请求会话返回结果,而是要把通知消息推送给所有接入的、订阅了通知推送的客户端会话 - 新增专门的通知订阅路由,比如
subscribe.notifications,用于客户端建立长连接订阅全量通知推送
2. 前端代码调整
2.1 适配服务端推送的代码改造
每个标签页初始化RSocket连接后,都主动向服务端发起requestStream请求订阅通知推送,只要有新通知产生服务端就会主动推送给所有订阅的客户端:
client.connect() .then((sock) => { // 原有点击触发插入通知的逻辑保留 document.getElementById("connect") .addEventListener("click", (event) => { numberRequester(sock); }); // 新增:每个标签页启动后都订阅全局通知推送 sock.requestStream({ data: { subscriber: retrieveData.id }, metadata: String.fromCharCode("subscribe.notifications".length) + "subscribe.notifications", }).subscribe({ onNext: responseHanlder, // 收到新通知直接触发弹窗 onError: errorHanlder, onSubscribe: (sub) => sub.request(0x7fffffff) // 无上限接收推送 }) }, errorHanlder);
2.2 轻量原型快速实现方案(无需改后端)
如果暂时不想调整服务端逻辑,可以用浏览器自带的storage事件实现同域名下的跨标签页同步:
// 修改原有响应处理逻辑,收到通知后先写入localStorage const responseHanlder = (payload) => { // 加时间戳避免重复识别相同内容的通知 localStorage.setItem('latest_notification', JSON.stringify({ data: payload.data, timestamp: Date.now() })) this.sendNotification(payload.data); }; // 所有标签页全局监听storage事件,其他标签页更新通知时触发本地弹窗 window.addEventListener('storage', (e) => { if (e.key === 'latest_notification') { const notify = JSON.parse(e.newValue) this.sendNotification(notify.data) } })
该方案仅支持同浏览器同域名的标签页同步,跨设备场景不生效,适合快速验证原型效果。
内容的提问来源于stack exchange,提问作者Guillermo Espinoza
相关产品推荐
相关产品推荐

