我应该创建一个特定于 SocketIO 的路由吗?
Should I create a route specific for SocketIO?
我是 Socket.IO 的新手,我完成了文档的聊天教程和聊天应用程序的“作业”以了解其工作原理,现在我正在尝试连接 NodeJS 服务器和一个带套接字的 React App。我花了一整天时间尝试这样做,但我收到了这个错误:
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 创建路由还是什么?
Should I create a route for SocketIO or what?
没有。当您这样做时:
const io = socketIO(server)
socket.io 库已经为以 /socket.io
开头的路由和它需要的任何其他路由安装了自己的路由处理程序。你不需要自己做。
但是,您确实遇到了问题,因为您正在连接 socket.io 到您从未启动过的服务器。
当你这样做时:
app.listen(PORT, () => console.log(`Application up and running on ${PORT}`))
这将创建一个新的 http 服务器,然后在其上调用 .listen()
并 returns 该新服务器。您将需要捕获该服务器并将 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。
而不是:
app.listen(PORT, () => console.log(`Application up and running on ${PORT}`))
使用这个:
server.listen(PORT, () => 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
我是 Socket.IO 的新手,我完成了文档的聊天教程和聊天应用程序的“作业”以了解其工作原理,现在我正在尝试连接 NodeJS 服务器和一个带套接字的 React App。我花了一整天时间尝试这样做,但我收到了这个错误:
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 创建路由还是什么?
Should I create a route for SocketIO or what?
没有。当您这样做时:
const io = socketIO(server)
socket.io 库已经为以 /socket.io
开头的路由和它需要的任何其他路由安装了自己的路由处理程序。你不需要自己做。
但是,您确实遇到了问题,因为您正在连接 socket.io 到您从未启动过的服务器。
当你这样做时:
app.listen(PORT, () => console.log(`Application up and running on ${PORT}`))
这将创建一个新的 http 服务器,然后在其上调用 .listen()
并 returns 该新服务器。您将需要捕获该服务器并将 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。
而不是:
app.listen(PORT, () => console.log(`Application up and running on ${PORT}`))
使用这个:
server.listen(PORT, () => 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