如何确保每个用户仅打开一个 socket.io 连接?

You*_*hod 4 node.js socket.io reactjs

我分别在 Express 和 React 端使用 socket.io 和 socket.io-client 。

在服务器端,我使用socket.id在连接事件中console.log,当我只打开一个页面时,它总是显示两个连接,如下所示:

用户连接 woF_Gu_8ElqMB7a5AAAC 用户连接 lBAycJ6j0X5Q469SAAAD

然而,当从前端发出消息时,仅使用一个连接。

这是我设置 socket.io 服务器端的方法:

// ** bin/www file **
var server = http.createServer(app);
const io = require('socket.io')(server);

// Get socket module and pass it the io socket from here
require('../sockets')(io);

// ** sockets.js **
module.exports = io => {
  io.on('connection', (socket) => {
    console.log("A user connected", socket.id); // Fires twice with different IDs

    socket.on("Setup", data => {
      console.log("Data received:", data); // Only fires once per emit from frontend
    }

    socket.on("disconnect", () => {
      console.log("User disconnected");
    }

}
Run Code Online (Sandbox Code Playgroud)

这是我设置客户端的方式,尽管我不确定这是否重要,因为即使我没有此代码,它也会持续发生:

// ** bin/www file **
var server = http.createServer(app);
const io = require('socket.io')(server);

// Get socket module and pass it the io socket from here
require('../sockets')(io);

// ** sockets.js **
module.exports = io => {
  io.on('connection', (socket) => {
    console.log("A user connected", socket.id); // Fires twice with different IDs

    socket.on("Setup", data => {
      console.log("Data received:", data); // Only fires once per emit from frontend
    }

    socket.on("disconnect", () => {
      console.log("User disconnected");
    }

}
Run Code Online (Sandbox Code Playgroud)

知道为什么我总是有两个连接吗?谢谢!

编辑:添加网络屏幕截图。在此输入图像描述

You*_*hod 5

我解决了我的问题,并想在这里分享解决方案,尽管我不知道为什么我之前所做的不起作用。

我在 App.js 中使用 React Router,并在路由到的组件中导入 socket.io-client 。由于某种原因(或更多,取决于我放置线路的位置),这提供了双重连接const socket = io();

我的解决方案是在 App.js 中导入 socket.io-client 并在需要时将 io 作为 prop 传递给组件,如下所示:

import * as io from 'socket.io-client';

const socket = io();

class App extends Component {
 render() {
  return (
   <Router>
    <Header/>
    <Switch>
     <Route exact path="/" render={props => (<Home/>)}/>
     <Route exact path="/story" render={props => (<Start socket={socket} />)}/>
    </Switch>
   </Router>
  );
 }
}

export default App;
Run Code Online (Sandbox Code Playgroud)

这在高层定义了套接字,并在需要的地方向下传递,因此没有任何内容会被调用两次,并且我会停留在一个连接上。