在React中使用Socket.IO连接会导致不断重新加载

3

我以前从未遇到过这个问题,也无法弄清楚是什么原因导致的。我正在使用Express和Socket.io作为后端,使用create-react-app作为React前端的项目。

server/index.js...

代码非常标准,据我所知应该可以正常运行...

const app = express();
const server = app.listen(config.port);
io.attach(server);

if (process.env.NODE_ENV === 'production') {
  app.use(express.static(path.join(__dirname, '..', 'build')));
  app.get('/', (req, res) => res.sendFile(path.join(__dirname, '..', 'build', 'index.html')));
}

io.on('connection', socket => {
  *blah blah blah*
});

src/index.js...

class App extends Component {
  constructor(props) {
    super(props);
    this.socket = io.connect(window.location);
  }

  render = () => {
    if (view === 'start') {
      return <StartContainer socket={this.socket} />;
    } else if (view === 'game') {
      return <Game socket={this.socket} />;
    }
  }
}

我正在测试部署过程,所以我一直在运行set NODE_ENV=production&& node server/index.js来测试Express应用程序的文件服务。

在开发中,我运行两个服务器:一个是create-react-app,另一个是Express & Socket.io服务器。这个问题在开发中不会出现。

所以,我启动服务器,转到本地主机,但页面一直在刷新。如果我从App中删除socket连接,则问题消失。希望我没有忽略什么超级简单的东西。感谢任何帮助。

为了简洁起见,我省略了一些App组件,但如果您认为问题可能出在其他地方,请告诉我,我会添加更多内容。

编辑问题明显出现在客户端。我提供了构建的React项目,并遇到了同样的问题。


你检查过两个服务器是否都没有指向相同的本地主机:端口吗? - manAbl
@ManuelBlanco 在开发环境中只有两个服务器在运行,它们位于不同的端口。这个问题只存在于从 Express 服务器(生产)中提供文件的情况下。 - jolaleye
创建的React应用程序也可以在生产环境中使用吗?您是否尝试在express/socket.io处于生产状态时以开发模式运行create-react-app?您的express/socket.io服务器中是否有检查生产标志的任何组件? - SILENT
@SILENT 开发和生产环境之间前端唯一的变化是 socket.io 连接 URL。在开发环境中,它是 http://localhost:3001(Express 服务器所在的端口),而在生产环境中,它是 window.location。在生产环境中独立运行 Express 服务器和 React 服务器会导致 React 服务器正常工作,而 Express 服务器不工作。这是因为从 Express 服务器提供的前端仍然无法工作,而 React 服务器正在连接到 Express 服务器。 - jolaleye
1个回答

0

问题已解决

之前,连接是这样的:

this.setState({ socket: io.connect(config.socketIO) });

其中config.socketIOprocess.env.NODE_ENV === 'production' ? window.location : 'http://localhost:3001'

我以为这样会起作用,因为文档中说io()默认为window.location。显然传递window.location并不相同。到目前为止,可行的解决方案是...

if (process.env.NODE_ENV === 'production') {
  this.setState({ socket: io.connect() });
} else {
  this.setState({ socket: io.connect('http://localhost:3001') });
}

我还应该注意到,我将连接移动到了componentDidMount中,因此使用了setState

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接