【问题标题】:How to avoid reconnections with socket.io-client and React app?如何避免与 socket.io-client 和 React 应用程序重新连接?
【发布时间】:2021-04-15 15:49:47
【问题描述】:

我尝试将 React 客户端连接到我的 Socket.IO 服务器。我注意到 Socket.IO 客户端每 +/- 5 秒重新连接一次。当我尝试使用 vanilla html/js 简单应用程序做同样的事情时,一切正常。

React 组件内部:

useEffect(() => {
  const s = getChatClient();
}, []);

socket.io-client 模块内部:

var chatClient;

export function getChatClient(
  token = "secret"
) {
  if (!chatClient) {
    chatClient = io("http://localhost:5000/chat", {
      query: {
        token,
      },
    });
    chatClient
      .on("connect", () => {
        chatClient.emit("textMessage", "123cos");
      })
      .on("hello", (msg) => {
        console.log("12");
      });
  }
  return chatClient;
}

顺便说一句:我知道我可以导出 const 等(我已更改为这个版本,因为我认为它会有所帮助)。

我尝试了不同的方法来解决这个问题,但我陷入了困境。有什么想法吗?

当我打开 html/js 简单客户端时从服务器登录:

15:30:00 User Ilona connected to the socket.io server on /

当我退出时:

  15:29:12 User Ilona disconnected 

使用 React 应用程序:

  15:30:00 User Ilona connected to the socket.io server on '/'
  15:30:05 User Ilona disconnected 
  15:30:10 User Ilona connected to the socket.io server on '/' 
  15:30:15 User Ilona disconnected 
  15:30:20 User Ilona connected to the socket.io server on '/' 
  15:30:25 User Ilona disconnected

此问题与组件重新渲染或类似问题无关。

我正在开发 MacOS Big Sur。

【问题讨论】:

    标签: reactjs socket.io


    【解决方案1】:

    考虑创建,然后从上下文中使用:

    SocketContext.jsx:

    import { createContext, useState } from 'react';
    
    export const SocketContext = createContext();
    
    export default function SocketContextProvider(props) {
      const [sock, setSocket] = useState(null);
    
      let socket = async () => {
        if (sock) {
          return Promise.resolve(sock); // If already exists resolve
        }
        return new Promise((resolve, reject) => {
          let newSock = io('URL'),
            {
              query: {
                // Options
              },
            }; // Try to connect
          
          let didntConnectTimeout = setTimeout(() => {
            reject();
          }, 15000) // Reject if didn't connect within 15 seconds
    
          newSock.once('connect', () => {
            clearTimeout(didntConnectTimeout); // It's connected so we don't need to keep waiting 15 seconds
            setSocket(newSock); // Set the socket
            resolve(newSock); // Return the socket
          })
        });
      };
    
      return (
        <SocketContext.Provider value={{ socket }}>
          {props.children}
        </SocketContext.Provider>
      );
    }
    

    Component.jsx:

    import { useContext, useState, useEffect } from 'react';
    import { SocketContext } from './SocketContext.jsx';
    
    export default function MyComponent() {
      const { socket } = useContext(SocketContext);
      const [sock, setSock] = useState(null);
    
      useEffect(() => {
        socket()
          .then((resultSocket) => setSock(resultSocket))
          .catch(() => {
          /* Catch any errors here */
            console.log('Couldn\'t connect the socket!')
          });
      }, []);
    
      return (
        <div>
          <code>I'm a context consumer...</code>
        </div>
      );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 2020-06-01
      • 1970-01-01
      • 2017-12-04
      • 2018-10-05
      • 2019-04-27
      • 1970-01-01
      相关资源
      最近更新 更多