sockets - 最适合我的应用程序的 Socket.IO 设计是什么?
问题描述
意识到这将是一个非常笼统的问题,但我会尽量具体:
设计/构建 Socket.IO 应用程序的最佳方式是什么?
我有一个带有 React 前端的 NodeJS 后端,带有身份验证(用户必须登录)。我有几个 REST 端点,例如 /foo、/bar、/baz。
我知道您可以使用房间和命名空间,并且我知道您可以将身份验证添加到连接作为中间件,但我不知道最好的解决方案是将它们粘合在一起的最佳解决方案。我将把这个套接字用于多种用途。对于每个目的,我都很好奇最好的方法是什么(流动)。
一般 CRUD 消息:当有人在服务器端发布“foo”时,它也需要将其发送给该特定用户。当有人删除一个“foo”时,它还需要向这个用户发送一些东西。所以这个 CRUD 消息应该只针对一个特定的用户(基于登录的用户 ID)。如何构建这些消息?“foo”的命名空间?多个事件监听器:“foo create”、“foo delete”、“foo update?” 如何确保您只发送给该用户?
我在客户端有多个页面,用于各自的 CRUD 端点。因此,当我在“foo”页面上时,我需要获取“foo”后端对象的更新。我怎样才能做到这一点?
一般服务器端消息:我将在服务器端运行长时间运行的脚本,由用户(或时间触发器)启动。如果我在响应中转到该页面并且如果有属于我的长时间运行的脚本处于活动状态,我需要查看这些日志记录。(但同样,它们是个人的,所以这些消息只给我)。
如果您需要更多说明,请提前感谢我,我会将其添加到我的问题中。
编辑:
我认为CRUD部分可以更好地创建为只有一个“更新监听器”(如firebase onSnapshot)。所以在 foo 页面上,我会监听 foo 数据库中的更新,但更新或创建不是通过普通的 REST API 进行的。这确实是更好的方法吗?
解决方案
您可以在 'connection' 事件中或使用中间件 - doc验证 socket.io 连接。
你也可以使用来自 npm 的一些包,例如这个
身份验证后将用户数据存储在套接字对象中或作为“连接”事件范围中的单独对象。
io.on('connection', (socket) => {
const handshake = socket.handshake;
const user = // fetch user obj according data in handshake, for example, from jwt token in header
});
因此,您可以在此连接的其他事件中使用用户对象。
根据您在我的项目中使用房间实施的任务的私人消息。这里抽象的例子:
// this is just a helper to get room name according to userId
getUserRoomName(userId) {
return `user_${userId}`;
}
// function to send data to user
sendToUser(userId, event, data) {
io.to(getUserRoomName(userId)).emit(event, data);
}
// in 'connection' event add join to user room
io.on('connection', (socket) => {
const handshake = socket.handshake;
const user = // fetch user obj according data in handshake, for example, from jwt token in header
// join to private room
socket.join(getUserRoomName(user.userId), () => {
// some logic
});
});
因此,当用户连接到 socket.io 时,我们将他的连接加入到私人用户房间。并且同一用户的每个连接都会加入同一个房间,因此我们可以隔离向该房间发送消息的数据。
使用 sendToUser 方法,您可以从应用程序的任何部分向所有用户连接发送任何类型的数据:
sendToUser(userId, 'foo_create', data);
OR
sendToUser(userId, 'foo', {
action: 'create',
// some other data
});
推荐阅读
- python - psycopg2 的问题
- ruby-on-rails - Omniauth Twitter 未连接用户
- amazon-web-services - 为什么 AWS CodePipeline 抱怨“Dockerfile”和“Dockerrun.aws.json”?
- ruby-on-rails - 如何使用 ActiveAdmin Active Admin Ruby on Rails 和 MySQL 将多个字段形成一个 Json 列?
- node.js - 为什么会收到:处理请求时出错。在使用适配器之前不要注册任何解析器
- javascript - ReactJS 防止 Navbar 在某些组件上呈现
- javascript - 检查用户是否有 MANAGE_MESSAGES 权限
- vba - Outlook 附件计数
- apache-spark - Minio,在 EKS 集群上与 spark 一起使用时出现访问被拒绝错误
- node.js - 如何使用 NodeJS 获取 Netsuite Auth2.0 令牌