【问题标题】:HTML5 canvas with Node.js, clustering and Socket.IO带有 Node.js、集群和 Socket.IO 的 HTML5 画布
【发布时间】:2019-05-13 11:32:45
【问题描述】:

我正在创建一个 Node.js 应用程序,用于在 HTML5 画布上进行协作绘图。我正在使用 Socket.IO 进行通信,并且我已经实现了集群,因此我能够扩展我的应用程序。我的讲师告诉我,使用集群是一个好主意,但让 CPU 中的每个核心都做同样的事情并不明智,也就是说,这违背了目的。因此,在我的情况下,让 8 个核心在完全相同的绘画上工作并不明智,而是可能有 8 种不同的绘画,每个核心一张绘画。我也知道 Socket.IO 只通过一个核心进行通信。现在我对从哪里开始以及如何开始有点困惑。我知道有这个“粘性”socket.io 模块,但它只是共享通信,而不是为每个核心制作不同的绘画?

这是我制作的服务器:

let http = require('http').Server(application);
let socketIO = require('socket.io')(http);
let cluster = require('cluster'); 
let cores= require('os').cpus().length;

if (cluster.isMaster) {
    for (let i = 0; i < cores; i++) {
        cluster.fork();
    }

} else {
    process.exit();
}

function connect(socket){
    socket.on('test',
        function emit(data) {
            socket.broadcast.emit('test', data);
        });
}

socketIO.on('connection', connect);

http.listen(port);

【问题讨论】:

  • 我们期望 CPU 在这种情况下做什么?他们没有做任何正确的绘图吗?,他们只负责服务套接字/因此可以转移坐标/颜色?
  • 没错,我只发出颜色和坐标
  • 在我看来,你的 CPU 无论如何都会做同样的事情(socket.io 工作)。我认为,如果您有一些后台代理/工作人员角色来做不同的事情,那么拆分任务会更有意义。
  • 我希望他们每个人都画不同的画 :)
  • 这样我就不会为了一幅画浪费所有 8 个核心

标签: node.js sockets socket.io scalability sticky-session


【解决方案1】:

我认为你的 CPU 内核无论如何都会做一些非常相似的事情,但我相信这个问题应该重新措辞,它正在探索如何通过利用多个 CPU 来解决这个问题,假设你有 >= X 绘画其中 X是 CPU 的数量。您无需直接将 CPU 分配给单个画作,操作系统已经过优化,可以提供智能方法来选择最佳可用画作。

看看工人是如何设置监听套接字连接的?您可以在每个工作人员中发出您想要发出的数据。

以下代码取自this SO 帖子,我稍作改动。

var cluster = require('cluster');
var os = require('os');

if (cluster.isMaster) {
  // we create a HTTP server, but we do not use listen
  // that way, we have a socket.io server that doesn't accept connections
  var server = require('http').createServer();
  var io = require('socket.io').listen(server);
  var redis = require('socket.io-redis');

  io.adapter(redis({ host: 'localhost', port: 6379 }));

  for (var i = 0; i < os.cpus().length; i++) {
    cluster.fork();
  }

  cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  }); 
}

if (cluster.isWorker) {
  var express = require('express');
  var app = express();

  var http = require('http');
  var server = http.createServer(app);
  var io = require('socket.io').listen(server);
  var redis = require('socket.io-redis');

  io.adapter(redis({ host: 'localhost', port: 6379 }));
  io.on('connection', function(socket) {
    // grandeFasola - emit what you what to emit here.
    socket.emit('data', 'connected to worker: ' + cluster.worker.id);
  });

  app.listen(80);
}

【讨论】:

  • 所以只是为了正确理解。上面的代码创建了一个服务器,但没有监听它?如果它是一个worker,我们创建另一个服务器,所以我们最终为每个worker 一个服务器,一个给master?
  • 是的 - 我认为这样做是为了表明您可以分离职责。工作人员将在同一个套接字上监听,这应该分配处理/发射
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-19
  • 2017-11-05
  • 2012-08-18
  • 1970-01-01
  • 2021-12-30
  • 2011-12-27
  • 2016-06-06
相关资源
最近更新 更多