javascript - Socket IO 和动态房间
问题描述
如果有人对 Websockets / Socket IO 有经验,希望你能指出我正确的方向。
我制作了一个 Discord Clone,我正在尝试对其进行优化以更好地扩展。现在,当用户发送消息时,我会在数据库中查询该服务器的所有用户部分,并向他们的特定套接字发出消息。这显然不能很好地扩展,因为每条消息都需要在客户端列表中进行昂贵的查询和查找
// Emit messages to only users part of specific server
// Will only return list of users part of server and active in last 10 minutes
sqlQuery = `SELECT userservers.user_id FROM userservers
JOIN users ON users.user_id = userservers.user_id AND users.user_last_active > (NOW() - INTERVAL 10 minute)
WHERE server_id = ${sql.escape(serverId)}`;
const users = await sql.query(sqlQuery);
action = { type: "message", payload: msg };
// Iterate over users, and find them in clients list
// Emit over socket only to that user
users.forEach((user) => {
clients.forEach((client) => {
if (client.userId === user.user_id) {
io.to(client.id).emit(user.user_id, action);
}
})
});
但是,为每个服务器使用房间将消除我查询数据库的需要。我知道我可以在套接字服务器首次启动时执行此操作
// Get server list from Mysql DB
servers.forEach((server) => {
socket.join(server.name);
}
但是我的问题变成了,当用户在应用程序已经运行后创建新服务器时,它不会更新列表。
我可能错过了一些关于创建动态房间的概念。
编辑:我认为解决方案可能是每次创建“服务器”时,我都会向套接字服务器发送一条消息,以便它可以加入那个“房间”
解决方案
现在,当用户发送消息时,我会在数据库中查询该服务器的所有用户部分
我认为您可以向所有在线用户提交广播消息,因此forEach client => io.to(clientId)
您可以向所有连接的用户提交广播消息而不是io.emit('some event', { for: 'everyone' });
我也想知道你为什么要创建很多服务器?您可以通过 using 将服务器划分为命名空间const namespace = io.of('/thisIsASeparateNamespace');
,还可以通过以下方式向该命名空间内的所有用户提交广播消息namespace.emit('some event', { for: 'everyone in name space' });
所以你的聊天结构可以是这样的
服务器
- 命名空间//用于单独的聊天应用程序/或类似松弛的工作空间
- 房间 // 用于群聊
- ClientID // 一对一
推荐阅读
- php - 停止执行直到下一小时开始
- java - Javers - 如何使用 Spring Boot 获取单个记录的所有更改值?
- c# - Unity Web 请求缓存问题
- flutter - 使用 Flutter 进行 Firebase 身份验证
- angular - 如何在 Angular Universal 中显示静态 html 页面
- typescript - TypeScript 类型中成员中“typeof”的目的是什么?
- powershell - 在powershell中替换部分变量而不替换其余部分?
- python - 在 Python 中使用正则表达式获取子字符串
- wpf - 如何在自定义控件中获取控件?
- python-3.x - 我有一个包含两列的数据框。如何删除名称为 Sam、Ben、Ram 的行