Socket.io:如果在快速路由中使用,事件会触发两次
Posted
技术标签:
【中文标题】Socket.io:如果在快速路由中使用,事件会触发两次【英文标题】:Socket.io: Events firing twice if used inside an express route 【发布时间】:2020-04-03 10:56:14 【问题描述】:我正在使用 socketio 开发一个聊天应用程序。我遇到的问题是,如果我将io.on('connection', ..)
块放在快速路线app.get('/chat')
之外,一切正常,但是当我将它放在路线/chat
内时。连接内的所有内容都会触发两次。
server.js
// On new connection
io.on("connection", socket =>
console.log('Socket ID: ' + socket.id);
// I want the user object (inside /chat route) to be available here..
)
// @route:chat
app.get("/chat", auth, async (req, res) =>
const user = User.findbyId(req.userId);
// socket.io part moved outside the route
res.render('chat', )
)
第一次请求时输出到/chat
:
Socket ID: 5e82d1a21c9d4400003e9bce
第二次请求时输出到/chat
:
Socket ID: 5e82d1a21c9d4400003e9bce --> this is repeating
Socket ID: 5e82d1a21c9d4400003e9bc4
如果我继续请求/chat
,以此类推。
知道如何解决这个问题吗?
【问题讨论】:
这是因为您正在为 on('connection') 注册两个事件处理程序。把它放在路线之外。 是的,您正在回答标题中的问题... 我想在路由中使用io.on("connection") @i.brod 我在哪里注册两个事件处理程序? 在您的 GET /chat 路由中。每次请求到达此路由时,您都在为 io.on('connection') 注册另一个处理程序 【参考方案1】:通常,socketIO 操作不应依赖于快速路由。如果您希望用户加入 socketIO 连接,则应通过 SocketIO 的事件处理程序来完成。如果您想将“用户”与该套接字关联,您的前端应该启动连接,并将一些身份传递给 SocektIO。
我不知道你的应用程序如何处理身份验证,但一种常见的做法是向 SocketIO 连接建立传递一个令牌:
const socket = IO.connect('http://localhost:8000',
query:
token//This token will be available on the server.
);
那么在你的服务器中:
const middleware = async (socket,next)=>
const token = socket.handshake.query.token;//Now you have the user token, which presumably contains the user ID.
const verifiedUser = await getUserByToken(token);//Let's say this returns a user object, if the token is valid, false if not.
// Let's assume that behind the scenes this function also calls User.findbyId(id);
if(verifiedUser)
socket.userObject = verifiedUser;//You can place the userObject on the token object, to be used later.
next()//Will allow the "connection" event to proceed.
else
next(new Error('INVALID_CREDENTIALS'))//Will cause the on("error") event to fire in the front-end, passing this error.
//The on("connection") event here will not fire.
io.use(middleware)
io.on('connection', async (socket) =>
//This runs only if middleware is "successful".
)
我不知道这是否真的回答了您的问题,但它是套接字-用户关系的一个示例。
【讨论】:
以上是关于Socket.io:如果在快速路由中使用,事件会触发两次的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Express 4 路由中使用 socket.io 向连接的套接字发出事件?
如果使用 Node.js 在 Socket.io 中的应用程序中登录功能,则为特定用户发出事件