我正在尝试使用 next.js 和 node.js 创建一个基本游戏。当我运行它时,我得到多个“已连接”日志,当我检查适配器时 - 使用 io.sockets.adapter.rooms - 即使只有一个客户端(chrome 上的一个选项卡)已连接:
io.sockets.adapter.rooms 日志:
Map(4) {
'tiTjbdGFj3EGgbwRAAAB' => Set(1) { 'tiTjbdGFj3EGgbwRAAAB' },
'DsCKvImAuh8H6Vr3AAAD' => Set(1) { 'DsCKvImAuh8H6Vr3AAAD' },
'FtJispkyF08rhHBDAAAF' => Set(1) { 'FtJispkyF08rhHBDAAAF' },
'PFO72' => Set(1) { 'FtJispkyF08rhHBDAAAF' }
}
app.js(服务器后端)
const app = require('express')();
const server = require('http').createServer(app);
const fs = require('fs');
const dirImage = './public/images';
const path = require( 'path' );
const io = require('socket.io')(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
}
});
server.listen(8000);
前端反应上下文套接字连接:
import {createContext} from 'react';
import io from "socket.io-client";
export const socket = io("http://localhost:8000", {transports : ['websocket']});
export const SocketContext = createContext(socket);
还使用 useContext 钩子在每个页面中创建套接字变量:
const socket = useContext(SocketContext);
当我运行服务器时,我仍然从一个客户端获得 5 个连接
Connected!
Connected!
Connected!
Connected!
Connected!
有什么问题吗?
在您的前端应用程序中,您正在使用上下文 api 来连接套接字,但没有使用 useEffect Hooks,因此您的连接线运行的次数与您的应用程序重新渲染的次数相同。我建议使用带有空依赖数组的 useEffect 钩子来仅在第一次渲染中运行连接。
我为您附上示例代码:
import io from "socket.io-client";
useEffect(() => {
socket = io.connect("http://localhost:8000");
return () => {
socket.disconnect();
};
}, []);
这将首次连接您的套接字连接,并且当组件弹出时它将断开连接。
应该是这样吗?
上下文文件:
const SocketContext = createContext();
const SocketContextProvider = ({children}) =>{
const [socket,setSocket] = useState(null);
useEffect(()=>{
setSocket(io.connect("http://localhost:8000"));
},[]);
return (
// the Provider gives access to the context to its children
<SocketContext.Provider value={socket}>
{children}
</SocketContext.Provider>
);
}
export {SocketContext,SocketContextProvider}
更好的方法是将 autoConnect 选项设置为 false 并使用以下命令手动连接客户端: 步骤1: //它将阻止客户端自动连接 const 套接字 = io({autoconnect: false}); 第2步: //它将连接客户端 套接字.connect()