【问题标题】:How to send and close websocket with a function in React如何使用 React 中的函数发送和关闭 websocket
【发布时间】:2021-01-04 19:26:29
【问题描述】:

我正在尝试使用 websockets 连接到Kraken websocket API。我在初始渲染上创建了一个新实例并设置了侦听器。我正在尝试制作按钮来订阅和关闭,但按钮不起作用。

我正在使用this websocket 库。

const WebSocket = require('isomorphic-ws')
   

function App() {

  const ws = new WebSocket('wss://ws.kraken.com')
  
  useEffect(() => {

    ws.onopen = () => {
      console.log('connected')
    }

    ws.onmessage = (msg) => {
      const message = JSON.parse(msg.data)
      const sub = message[2]
      console.log(message)
    }

    ws.onclose = () => {
      console.log('closing connection')
      // ws.close()
    }

    return () => {
      ws.close()
    }
  }, [])

 const wsClose = () => {
   ws.close()
 }

  const wsSub = () => {
    ws.send(JSON.stringify(
      {
        "event": "subscribe",
        "pair": [
          "XBT/USD"
        ],
        "subscription": {
          "name": "ticker"
        }
      }
    ))
    console.log('send subscribe')
  }

  return (
    <button onClick={wsSub}>subscribe</button>
    <button onClick={wsClose}>close ws</button>
  )
}

export default App

如果我将wsSub 函数中的代码放在ws.onopen 侦听器下,订阅就可以工作,但是我想控制打开websocket 时不订阅的订阅。我正在使用这样的按钮进行测试。我想根据用户表单提交来订阅和取消订阅,但我觉得我应该能够先完成这项工作。

【问题讨论】:

    标签: node.js reactjs websocket


    【解决方案1】:

    现在,每次组件重新渲染时,您都会创建一个新套接字。效果回调引用创建的第一个套接字(在安装时),但 wsClosewsSub 没有(它们引用在前一个渲染中创建的套接字)。

    将套接字放入一个状态或一个引用:

    const wsRef = useRef();
    if (!wsRef.current) {
      wsRef.current = new WebSocket('wss://ws.kraken.com');
    }
    

    然后继续将ws 的所有用法替换为wsRef.current

    【讨论】:

    • 以不同的方式创建套接字会更好吗?如果在 App 函数之外还是在 useEffect 之内,会有什么不同吗?
    • 如果您确定在脚本运行时它总是(并且只)会被实例化一次,您可以将套接字设置为外部变量。这将使使用它更容易(因为您不必处理 refs 或过时的闭包等),但也会使组件的可重用性降低。这对你来说可能是也可能不是问题。您可以将套接字作为道具传递下去,但这只会在调用链中引发问题,并具有相同的问题和解决方案。
    • 我接受了你的回答,但还有一个问题:如果在我提交的代码中我在每个渲染上创建一个新的 websocket,前一个是否会自行关闭?这样做是不好的做法吗?如果在提交表单时我正在创建新订阅,那么每次使用订阅而不是取消订阅来创建一个新的 websocket 可能会更容易
    • 我认为,一旦没有其他东西可以引用套接字,它最终会被垃圾收集,当这种情况发生时,浏览器会关闭套接字。如果您确实出于充分的理由多次创建套接字,然后停止为 GC 引用它们,我认为这很好。对于这种特殊情况,我不确定上下文 - 我会做任何使代码更易于编写和理解的事情。
    猜你喜欢
    • 2011-03-22
    • 2015-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-04
    相关资源
    最近更新 更多