不同的 WebSocket“onmessage”处理程序取决于屏幕

Posted

技术标签:

【中文标题】不同的 WebSocket“onmessage”处理程序取决于屏幕【英文标题】:Different WebSocket "onmessage" handlers depending on screen 【发布时间】:2021-03-09 01:37:09 【问题描述】:

我的 React Native 应用(iosandroid)使用单个全局 WebSocket 连接。

我想根据屏幕对来自服务器的相同消息做出不同的响应,例如主屏幕 (A) 上的一种方式和屏幕 B 上的不同方式。

因为在屏幕 B 打开后,主屏幕仍处于挂载状态并处于“活动状态”,所以我不能只覆盖 websocket“onmessage”处理程序,因为这会导致不一致。

谁能指出我正在努力实现的正确方向?

【问题讨论】:

【参考方案1】:

没有看到关于您想要实现的目标的一些代码,我认为您通常想要的是订阅模型。您只有一个向套接字注册的处理程序,但该处理程序可以委托给可以根据需要添加/删除的其他功能。

一般来说,我建议在反应树的某处创建 websocket 连接,例如带有上下文提供程序的钩子。不过,为了避免在这里混淆这个想法,我们假设您的 websocket 连接定义为静态上下文(即在模块中,而不是在组件或钩子中)。

// socket.js
const messageHandlers = new Set()

export const addMessageHandler = (handler) => 
  messageHandlers.add(handler)


export const removeMessageHandler = (handler) => 
  messageHandlers.delete(handler)


const socket = new WebSocket('ws://example.com')

socket.onmessage = (event) => 
  messageHandlers.forEach((handler) => handler(event))

然后在你的屏幕上:

import  addMessageHandler, removeMessageHandler  from '/path/to/socket.js'

const SomeScreen = () => 
  useCallback(() => 
    const handler = (event) =>  /* do something with event */ 
      
    addMessageHandler(handler)
    return () => removeMessageHandler(handler)
  , [])

即使屏幕在后台,这也会让监听器保持活跃。如果您使用 react-navigation,您也可以使用useFocusEffect 使其仅在屏幕为当前屏幕时注册,例如:

  useFocusEffect(
    useCallback(() => 
      const handler = (event) =>  /* do something with event */ 
      
      addMessageHandler(handler)
      return () => removeMessageHandler(handler)
    , [])
  )

【讨论】:

我知道您应该避免使用不会进一步添加任何内容的 cmets,但这个解决方案对于我的用例来说绝对完美 - 非常感谢。

以上是关于不同的 WebSocket“onmessage”处理程序取决于屏幕的主要内容,如果未能解决你的问题,请参考以下文章

WebSocket 频繁 onmessage 零拷贝

Java WebSocket:onMessage 未触发

onMessage WebSocket 中的消息处理

C# 创建 websocket - onmessage 函数不起作用

Glassfish websocket OnMessage方法突然退出

Vue.js 在 websocket onmessage 事件中更新 html