2016-03-24 1 views
0

У меня есть узел кластер, где мастер отвечает на http-запросы. Сервер также прослушивает подключения к сети (через socket.io). Клиент подключается к серверу через указанный веб-узел. Теперь клиент выбирает между различными играми (каждый узел обрабатывает игру).Узел кластеризации с websockets

Вопросы, которые я бы следующие:

  • Должен ли я открыть новое соединение для каждого процесса узла? Как сообщить клиенту, что он должен подключиться к точному процессу узла X? (Потому что сервер может обрабатывать входящие запросы на соединение на своем)
  • Возможно ли передать сокет узлу, так что нет необходимости открывать новое соединение?
  • Каковы недостатки, если я просто использую одно соединение (в основном процессе) и передаю сообщения пользователя соответствующим процессам узлов и сообщениям процесса обратно пользователю? (Я чувствую, что это стоит много ресурсов процессора, чтобы скопировать довольно большие объекты при отправке сообщений между процессами)

ответ

2

Можно ли передать сокет к процессу узла, так что нет необходимости открытие нового соединения?

Вы можете отправить простой TCP-сокет другому процессу узла, как описано в node.js doc here. Основная идея заключается в следующем:

const child = require('child_process').fork('child.js'); 
child.send('socket', socket); 

Затем в child.js, вы бы это:

process.on('message', (m, socket) => { 
    if (m === 'socket') { 
    // you have a socket here 
    } 
}); 

«гнездо» Идентификатор сообщения может быть любое имя, сообщение, которое вы выбрали - это не специальная , node.js имеет код, который, когда вы используете child.send(), и данные, которые вы отправляете, распознаются как сокет, он использует межпроцессную связь, специфичную для платформы, для совместного использования этого сокета с другим процессом.

Но я считаю, что это работает только для простых сокетов, которые еще не имеют локального состояния, кроме состояния TCP. Я не пробовал это с установленным соединением webSocket сам, но я предполагаю, что это не сработает для этого, потому что, как только веб-приложение имеет более высокое состояние состояния, связанное с ним, помимо только TCP-сокета (например, ключи шифрования), возникает проблема, поскольку ОС не будет автоматически передавать это состояние новому процессу.

Должен ли я открыть новое соединение для каждого процесса узла? Как сообщить клиенту , что он должен подключиться к процессу точного узла X? (Поскольку сервер может обрабатывать входящие соединения-запросы на ИТС)

Это, вероятно, самый простой способ получить Socket.io подключение к новому процессу. Если вы убедитесь, что ваш новый процесс прослушивает уникальный номер порта и поддерживает CORS, вы можете просто взять соединение socket.io, которое у вас уже есть между основным процессом и клиентом, и отправить на него сообщение клиенту , который сообщает клиенту, с которой следует подключиться (номер порта). Затем клиент может содержать код для прослушивания этого сообщения и подключения к этому новому месту назначения.

Каковы недостатки, если я просто использовать одно соединение (в основных процессе) и передать пользовательские сообщения на соответствующий узел обрабатывает сообщения и процесса обратно пользователю? (Я чувствую, что это стоит много процессора скопировать довольно большие объекты при отправке сообщений между процессами)

Недостатками являются, как вы догадкой. Ваш основной процесс просто должен тратить энергию ЦП, являясь средним человеком, отправляющим пакеты в обоих направлениях. Независимо от того, важна ли эта дополнительная работа для вас, она полностью зависит от контекста и должна определяться измерением.


Это ome больше информации Я обнаружил. Похоже, что если входящее соединение socket.io, которое поступает на master, немедленно отправляется к дочернему объекту кластера до того, как соединение установит исходное состояние socket.io, эта концепция может работать и для соединений socket.io.

Адрес an article on sending a connection to another server с кодом реализации. Это, по-видимому, выполняется немедленно во время соединения, поэтому оно должно работать для входящего соединения socket.io, предназначенного для определенного кластера. Идея здесь заключается в том, что существует липкое назначение для конкретного процесса кластера, и все входящие соединения любого типа, которые доходят до мастера, немедленно передаются дочернему элементу кластера, прежде чем они установят какое-либо состояние.

+0

[Документация] (https://nodejs.org/api/child_process.html#child_process_child_send_message_sendhandle_options_callback) указывает, что весь сервер может быть отправлен через 'child_process.send'. Я не уверен, можем ли мы отправить WebSocketServer в другой кластер. Эта функциональность может помочь избежать повторного подключения всех подключений от сбоев. – Lewis

+0

@Tresdin - Вы действительно не отправляете «весь сервер». Вы отправляете сокет, который прослушивает входящие соединения, чтобы другой процесс мог прослушивать входящие соединения. В обычной установке обычно нет отдельного WebSocketServer, поскольку входящие соединения WebSocket обычно используют один и тот же порт (и, следовательно, сервер) в качестве обычных HTTP-соединений веб-сервера. И помните, что все соединения socket.io начинают работу как HTTP-соединение, а затем проходят процесс обновления, чтобы согласовать изменение протокола с протоколом webSocket. – jfriend00

+0

@Tresdin - Но да, вы могли бы отправить сокет слухового сервера другому процессу. – jfriend00