我使用Node集群,在每个Worker上都有一个正在运行的WebSocket服务器.Master正在运行一个HTTP服务器.

在主HTTP服务器上,我想要一个HTTP升级调用实现,它将把调用者连接到特定的Web套接字.

为什么?我希望能够将用户连接到正确的WebSocket,但我希望通过作为本地主机的单个入口点来实现:8000.连接到LOCALHOST:8000可能会无缝连接到LOCALHOST:8001.

我的 idea 是使用类似以下参数的参数调用Upgrade:

wscat -c ws://localhost:8000/?id=5

此调用应转到主服务器,并且主服务器将转发此升级调用并与本地主机:8005建立连接.

我以为我可以简单地使用worker.end()将升级参数转发给Worker,但这并不真正起作用,我在Worker中收到的对象遗漏了很多东西,这可能是我不知道的一些JS基础知识.

以下是我天真的实现:

var http = require('http');
var cluster = require('cluster')
var ws = require('ws');

var NumberOfInstances = 5;

if (cluster.isMaster) {

    var forks = []
    for (var i=0; i < NumberOfInstances; i++) {
        forks.push(cluster.fork());
    }

    server = http.createServer((req, res) => {
        res.writeHead(200);
    }).listen(8000);

    server.on('upgrade', (request, socket, head) => {
        var params = new URL(`https://localhost:8000${request.url}`);
        var id = parseInt(params.searchParams.get('clusterId')) - 1;

        // How do I forward upgrade??
        forks[id].send({r: request, s: socket, h: head});
    })

} else {

    portStr = `800${cluster.worker.id}`;
    wss = new ws.WebSocketServer({
        port: portStr
    });

    wss.on('connection', (ws, request) => {
        console.log(`${cluster.worker.id} got connection.`);
    })

    process.on('message', masterMessage => {
        // This absolutely doesn't work. 
        wss.handleUpgrade(masterMessage.r, masterMessage.s, masterMessage.h, (ws) => {
            wss.emit('connection', ws, masterMessage.r);
        })
    })
}

推荐答案

根据docs,您需要将套接字处理程序作为第二个参数发送到worker.send方法.

所以你应该这么做,

forks[id].send({ headers: request.headers, method: request.method, head: head }, socket); //socket is in second argument

在您的子代message事件处理程序中,执行以下操作

process.on('message', (request,socket) => {
    
    wss.handleUpgrade(request, socket, request.head, (ws) => {
        wss.emit('connection', ws, request);
    })
})

查看this个示例,了解如何将套接字对象作为参数传递.

Javascript相关问答推荐

想要检测字符串中的所有单词

如何在非独立组件中使用独立组件?

为什么使用MAX_SAFE_INTEGER生成随机整数时数字分布不准确?

如何将拖放功能添加到我已自定义为图像的文件输入HTML标签中?

JavaScript文本区域阻止KeyDown/KeyUp事件本身上的Alt GR +键组合

如何避免移动设备中出现虚假调整大小事件?

Chart.js V4切换图表中的每个条,同时每个条下有不同的标签.怎么做?

通过嵌套模型对象进行Mongoose搜索

我应该绑定不影响状态的函数吗?'

如何在Javascript中的控制台上以一行形式打印循环的结果

自定义高图中的x轴标签序列

cypress中e2e测试上的Click()事件在Switch Element Plus组件上使用时不起作用

Chart.js-显示值应该在其中的引用区域

Web Crypto API解密失败,RSA-OAEP

如何将数组用作复合函数参数?

Rxjs流中生成IMMER不能在对象上操作

输入的值的类型脚本array.排序()

Socket.IO在刷新页面时执行函数两次

为什么我看到的是回复,而不是我的文档?

设置复选框根据选中状态输入选中值