【问题标题】:Should I create a route specific for SocketIO?我应该为 SocketIO 创建一个特定的路由吗?
【发布时间】:2021-07-01 00:19:19
【问题描述】:

我是 Socket.IO 的新手,我完成了文档的聊天教程和聊天应用程序的“作业”以了解它是如何工作的,现在我正在尝试连接 NodeJS 服务器和 React 应用程序带插座。我花了一整天的时间尝试这样做,但我收到了这个错误:

GET http://localhost:4000/?EIO=4&transport=polling&t=NYW26Ea 404 (Not Found)

我的应用程序的目的是显示时间更新,我使用套接字每秒钟更新一次屏幕上的时间。 这是我的 Server.js 文件,是的,它非常简单:

const express = require("express")
const http = require("http")
const socketIO = require("socket.io")
var cors = require('cors')

const PORT = 4000;
const routes = require("./routes/index")

const app = express()
app.use(cors())
app.use(routes)

const server = http.createServer(app)

const io = socketIO(server)

let interval

io.on("connection", (socket) => {
    console.log("New client connected!")
    if(interval) {
        clearInterval(interval)
    }
    interval = setInterval(() => getApiAndEmit(socket), 1000)
    socket.on("disconnect", () => {
        console.log("Client is disconnected")
        clearInterval(interval)
    })
})

const getApiAndEmit = socket => {
    const response = new Date()
    socket.emit("from-api", response)
}

app.listen(PORT, () => console.log(`Application up and running on ${PORT}`))

如果我访问我使用 express 创建的路线,它工作正常。

这是我的 App.js 文件:

import React, { useState, useEffect } from "react";
import socketIOClient from "socket.io-client";
const ENDPOINT = "http://127.0.0.1:4000";

function App() {
  const [response, setResponse] = useState("");

  useEffect(() => {
    const socket = socketIOClient(ENDPOINT);
    socket.on("from-api", data => {
      setResponse(data);
    });
  }, []);

  return (
    <p>
      It's <time dateTime={response}>{response}</time>
    </p>
  );
}

export default App;

我应该为 SocketIO 创建路由还是什么?

【问题讨论】:

    标签: javascript node.js reactjs sockets socket.io


    【解决方案1】:

    我应该为 SocketIO 创建路由还是什么?

    没有。当你这样做时:

    const io = socketIO(server)
    

    socket.io 库已经为以/socket.io 开头的路由和它需要的任何其他路由安装了自己的路由处理程序。你不需要自己做。

    但是,您确实遇到了问题,因为您将 socket.io 连接到您从未启动过的服务器。

    当你这样做时:

    app.listen(PORT, () => console.log(`Application up and running on ${PORT}`))
    

    这将创建一个新的 http 服务器,然后在其上调用 .listen() 并返回该新服务器。您需要捕获该服务器并将 socket.io 连接到它:

    所以,替换这个:

    const server = http.createServer(app)
    
    const io = socketIO(server)
    
    app.listen(PORT, () => console.log(`Application up and running on ${PORT}`))
    

    有了这个:

    const server = app.listen(PORT, () => console.log(`Application up and running on ${PORT}`))
    const io = socketIO(server);
    

    然后,您将创建并启动一个 http 服务器并将 Express 和 socket.io 连接到它。它们可以在同一个端口上共享同一个 http 服务器。 Socket.io 将使用路由前缀 /socket.io 来区分它自己的路由,一旦给定的 socket.io 连接建立,该特定连接将协议切换到 webSocket 协议(上面有 socket.io 数据帧)和不再使用 http。

    【讨论】:

    • 很好的解释。我按照你说的做了,在客户端反应应用程序上我添加了这一行: const socket = openSocket(ENDPOINT, { transports: ['websocket'] });现在它工作正常并与 NodeJS 套接字服务器通信!
    • @Bruno - 很高兴成功了!如果这回答了您的问题,那么您可以通过单击答案左侧的复选标记向社区表明这一点。这也将为您在此处遵循正确的程序赢得一些声誉积分。
    【解决方案2】:

    代替:

    app.listen(PORT, () =&gt; console.log(`Application up and running on ${PORT}`))

    使用这个:

    server.listen(PORT, () =&gt; console.log(`Application up and running on ${PORT}`))

    原因:您分配给socketIO的服务器实例与您正在监听的服务器实例不同。

    使用 express 你可以像这样传递服务器实例:

    var express   = require('express');
    var app       = express();
    ...
    ...
    ...
    var server    = app.listen(PORT);
    var io        = require('socket.io').listen(server);
    
    io.sockets.on('connection', function (socket) {
      ...
    });
    

    你可以参考这个:Express.js - app.listen vs server.listen

    【讨论】:

      猜你喜欢
      • 2017-10-26
      • 2020-01-18
      • 1970-01-01
      • 2013-07-01
      • 1970-01-01
      • 2010-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多