2013-06-03 4 views
2

У меня есть автономное приложение Node.js, у которого есть SocketIO-сервер, который слушает на определенном порту, например. 8888. Теперь я пытаюсь запустить это приложение в кластере и потому, что кластер случайно назначает работников запросам, клиенты SocketIO в режиме опроса XHR после того, как рукопожатие и разрешено одним рабочим, направляются к другому работнику, где они не рукопожаты, а беспорядок начинается ,SocketIO в кластере Node.js

А поскольку работники ничего не разделяют, я не могу найти обходное решение. Известно ли решение этой проблемы?

+0

Вам действительно нужен socket.io и запрос опроса? Вы можете просто использовать ws. –

+0

в нашем случае клиенты socketio могут находиться на устройствах, которые не имеют надежного HTTP-соединения, например. http://teradek.com/pages/bond, поэтому ws не всегда будет работать - xhr-опрос более надежный –

+0

Это все еще нерешенная проблема с socket.io https://github.com/LearnBoost/socket. io/issues/952 Он намекает добавить тайм-аут в часть обновления http, чтобы смягчить ее. –

ответ

1

Нет «простого» решения. То, что вы должны сделать следующее:

  • Если клиент подключается к работнику, за исключением соединения идентификатор вместе с рабочим идентификатором и потенциальной дополнительной идентификации идентификатором в глобальной (= для всех работников доступны) хранилище (т.е. redis).
  • Если клиент перенаправляется другому работнику, используйте хранилище, чтобы посмотреть, какой рабочий является ответственным за этот клиент (либо с идентификатором соединения, либо с идентификатором идентификатора, а затем передать его этому сотруднику (либо с помощью nodejs-рабоче-мастер-работник-связи или с помощью Redis-PUB-суб)

Я Habe осуществил такую ​​вещь с sock.js и дополнительную степень сложности: у меня есть два Node.js-серверов с четырьмя рабочими каждый из них, поэтому мне пришлось использовать redis-pub-sub для связи между работником/работником, потому что не гарантировано, что они находятся на одной машине.

+0

Спасибо, @heinob. Вам нужно было взломать источник sock.io, чтобы сделать это? –

+1

Как я уже сказал, я сделал это с sock.js, потому что он кажется намного более стабильным, чем io. Но я не взломал источник. Обычный стандарт. – heinob

+0

Это рукопожатие, но, насколько я помню, он не может найти транспорт. В основном мне пришлось переключиться на использование протокола websockets вместо XHR-опроса (в каких случаях он будет подключаться к различным рабочим узлам и, следовательно, должен повторно подключаться) и использовать диспетчер pub-sub Redis для обработки событий. Но в идеале я хочу, чтобы Socket.io просто работал для меня. Мне пришлось бы экспериментировать больше. –

1

Фактически там is a простое решение: с использованием Redis для хранения сокетов.
Все объясняется в Socket.IO documentation:

'сессия' хранения по умолчанию в Socket.io в памяти (MemoryStore).

MemoryStore только позволяет развертывать Socket.io на одном процессе. Если вы хотите масштаб для нескольких процессов и/или несколько серверов , вы можете использовать наш RedisStore, который использует базу данных Redis NoSQL как человек в середине.

Так что для того, чтобы изменить магазин экземпляр RedisStore мы добавим следующее:

var RedisStore = require('socket.io/lib/stores/redis') 
    , redis = require('socket.io/node_modules/redis') 
    , pub = redis.createClient() 
    , sub = redis.createClient() 
    , client = redis.createClient(); 

// Needs to be done after 'listen()' 
io.set('store', new RedisStore({ 
    redisPub : pub 
, redisSub : sub 
, redisClient : client 
})); 

Конечно вам нужно будет иметь ход Redis сервера.

+0

Я знаю об этом, но он не работает. –

+0

Он работает отлично для меня как в dev, так и в prod. Какой у вас вопрос? Все еще не квитирования? – maxdec

Смежные вопросы