reactjs - 如何避免与 socket.io-client 和 React 应用程序重新连接?
问题描述
我试图将 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。
解决方案
考虑创建,然后从上下文中使用:
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>
);
}
组件.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>
);
}
推荐阅读
- python - VBS 调用 Python - 未找到 sys 参数
- java - 需要一个 GPath 查询来查找最大日期 + 一个字符串字段
- python - pySerial serial.open() 在交互式 shell 中工作,但作为脚本引发异常
- javascript - 如何对电容器项目进行单元测试?
- ios - 构建错误 - 目标操作系统版本不支持使用线程局部变量
- c# - 在 Dot Net Standard 2 中,一些枚举具有重复值。为什么?
- python - 截取窗口的最快方法
- c# - 如何在不使用邮件正文的情况下比较电子邮件?
- r - 在R中将pcre REGEX转换为ICU REGEX
- java - 从表视图和 sql 中删除数据