Nodejs 使用socket.io的一个进程,负责向浏览器端推送消息。当需要推送消息的时候,如何通知到这个“进程”??
Nodejs 使用socket.io的一个进程,负责向浏览器端推送消息。当需要推送消息的时候,如何通知到这个“进程”??
假设五个用户处于已登录状态,当一个用户写了新博文,处理业务逻辑的进程把博文写入数据库,然后负责推送的这个进程向其他四个人推送通知,这个应该怎么实现?或者说处理业务逻辑的进程如何通知到负责推送的这个进程,有点绕口,大概是这个意思。不甚感激。
Node.js 使用 socket.io 的一个进程,负责向浏览器端推送消息。当需要推送消息的时候,如何通知到这个“进程”?
背景描述
假设五个用户处于已登录状态,当一个用户写了新博文,处理业务逻辑的进程(例如后端 API)会将博文写入数据库。然后,你需要通知负责推送的进程,让其向其他四个用户推送通知。
实现方法
在这种场景下,可以使用 socket.io
的命名空间(Namespace)或者房间(Rooms)来实现不同进程之间的通信。这里,我们通过一个简单的例子来说明如何实现这种通信。
示例代码
- 创建负责推送的进程
const io = require('socket.io')(3000);
io.on('connection', (socket) => {
console.log('A user connected:', socket.id);
// 将用户加入一个特定的房间,例如 'blog-updates'
socket.join('blog-updates');
socket.on('disconnect', () => {
console.log('User disconnected:', socket.id);
});
});
- 创建处理业务逻辑的进程
在这个进程中,我们需要找到负责推送的进程,并发送通知。我们可以使用 socket.io-client
来连接到推送进程的 socket.io 服务器。
const ioClient = require('socket.io-client');
const pushSocket = ioClient.connect('http://localhost:3000');
// 当有新博文时
function handleNewBlogPost(postData) {
// 将博文写入数据库...
// 然后通知所有在 'blog-updates' 房间中的客户端
pushSocket.to('blog-updates').emit('new-blog-post', postData);
}
解释
-
命名空间(Namespace) 和 房间(Rooms):在
socket.io
中,你可以使用房间来组织连接。在这个例子中,我们将用户加入名为'blog-updates'
的房间。 -
socket.io-client:这个库允许你在另一个进程中连接到 socket.io 服务器,从而实现进程间的通信。
-
pushSocket.to('blog-updates').emit('new-blog-post', postData);
:这条语句会向所有在'blog-updates'
房间中的客户端发送一条名为'new-blog-post'
的消息,并附带博文数据。
通过这种方式,你可以在处理业务逻辑的进程中触发推送通知,而无需直接管理多个进程间的复杂通信逻辑。
你要把消息发到服务器然后再从服务器广播到其余客户端
我是这样处理的,socket.io 连接建立后 export 一个io对象, io对象传入到后台作业(我用的是kue),那么每次有推送需求时建立一个job,kue进行推送处理。。好像说得有点绕。
一开始我也是连接到服务端再通过服务端广播到客户端。。
我不太想搞这么复杂。我用socket.io listen一个简单的HTTP服务器对象,只接受来自业务逻辑进程发出的HTTP请求,然后基本上就可以实现目的了。
应该单独搭建一个socket.io的监听,把业务逻辑的线程也作为socket.io的一个客户端(使用socket.io-client库),完成写数据库的逻辑后向监听服务中发一条消息,然后监听服务广播一条消息到所有的浏览器客户端。
要解决这个问题,可以使用socket.io-redis
模块来实现socket.io
在多进程或多服务器之间的通信。socket.io-redis
使得不同的socket.io
实例能够共享连接信息,这样你就可以在一个进程中发送消息给另一个进程所管理的客户端。
首先,确保安装了必要的包:
npm install socket.io socket.io-redis redis
接下来是基本步骤:
- 设置Redis:在你的服务器上运行Redis,用于存储和传输连接信息。
- 配置Socket.IO:配置
socket.io
以使用Redis进行消息传递。
以下是配置示例代码:
服务器端(推送进程)
const io = require('socket.io')(3000);
const pub = require('socket.io-redis');
io.adapter(pub({ host: 'localhost', port: 6379 }));
io.on('connection', function(socket) {
console.log("User connected:", socket.id);
// 当收到新的文章时,调用此函数向所有连接的客户端发送消息
function sendNotification(message) {
socket.broadcast.emit('newMessage', message);
}
// 示例:接收来自业务逻辑进程的消息
process.on('message', function(message) {
if (message.type === 'newPost') {
sendNotification(message.content);
}
});
});
业务逻辑进程(向推送进程发送消息)
const client = require('socket.io-client');
const socketClient = client.connect('http://localhost:3000', {transports: ['websocket']});
// 当需要发送通知时
function notifyUsers(content) {
socketClient.send({ type: 'newPost', content: content });
}
// 示例:模拟一篇新文章的发布
notifyUsers("这是一篇新发布的文章");
在这个例子中,当业务逻辑进程完成操作后,它会通过send
方法将消息发送到与推送进程相连的客户端。推送进程监听这种类型的消息,并将其广播给所有连接的客户端。这种方法允许你在多个进程或服务器之间轻松地实现消息传递。