生产中的NodeJS和Socket.io:处理状态

时间:2018-04-11 14:15:46

标签: node.js socket.io

在开发环境中,我有一个nodejs进程,它在给定端口上监听socket.io。客户端连接后,需要维护状态。 nodejs脚本对文件执行一些操作,并通过套接字发送处理状态。这就像是一批可能永远不会结束的。

如果客户端关闭浏览器然后再次打开(在开发环境中),网页将再次连接到套接字并获取进程的当前状态,该状态将处理后台中的文件处理特定用户。

为了让每个用户拥有一个进程并确保用户始终重新连接到他们启动的同一进程,在同一端口上,我需要管理这些进程,每个用户一个作为服务器上的服务并预订每个用户的端口。

我如何将此场景构建为单个nodejs入口点,该入口点可以使用Nginx,PM2和/或Nodejs集群来分离进程并相应地路由套接字连接。换句话说,在这样的场景中哪个是最好的生产架构?

关于州问题:

我持有的状态不仅仅是变量,可以存储在数据库中。我有连续的文件读取流,按照用户通过使用套接字连接到该进程的网页配置的顺序一个接一个地处理。此过程还连接到另一个套接字服务器到服务器,并且必须保持连接。

2 个答案:

答案 0 :(得分:2)

我可能会将您的流程的pid暴露给您的路由脚本,并利用会话和Cookie,将它们与分配给用户的pid一起保存到Redis DB

因此,在连接时,您设置了一个cookie和一个会话,可能使用了用户ID的datetime-hash(取决于您是否拥有与您的客户端关联的用户帐户),将其保存在用户cookie中并保存pid你的会议。

然后,您可以将用户重定向到路由器中相应的进程分支。

修改

我使用nodescript作为代理。我找到了this回答,因为您没有发布代码我不知道您是如何创建流程的,所以我将其用作参考:

const socketio = require('socket.io');
const redis = require('redis');

on.connect((req, res) => {
    let uid,
        pid,
        port;

    // if user does not have the cookie yet
    if (!req.cookies.uid) {
        uid = getNewUserID(req); // create uid from information from the request, set a cookie later
        pid = createWorker(uid); // generate new socket.io worker in cluster and return pid
        port = getSocketPort(pid); // get socket port from worker

        // save acquired variables to database
        redis.set(uid, [pid, port], function(err, reply) {
            if (err) throw err;
            console.log(reply);
        });
    };

    uid = req.cookies.uid; // get uid from request
    pid = getPid(uid); // get pid from redis

    socketio(getSocketPort(pid)); // connect client to port of correct worker
});

对于您的读取流,您可以在相应的工作者中执行它们。 1 Worker等于1 socket.io进程

答案 1 :(得分:0)

不要将你的状态保存在内存中。保存在数据库中(redis是一个很好的数据库,因为它基于内存和超快)然后你不必担心套接字重新连接到同一个进程甚至同一个服务器(如果有多个服务器加载 - 余额)。