У меня есть приложение Socket IO, работающее с использованием балансировки нагрузки NGNIX, и мое приложение работает на 6 ядрах, и нагрузка распределяется между ними. Когда я делаю pm2 list myapp
, он показывает, что работает в режиме ветвления, но охватывает 6 процессов, из-за балансировки нагрузки nginx
│ myapp-1 │ 21 │ fork │
│ myapp-2 │ 45 │ fork │
│ myapp-3 │ 32 │ fork │
│ myapp-4 │ 11 │ fork │
│ myapp-5 │ 911 │ fork │
│ myapp-6 │ 101 │ fork │
Вот пример того, как мой файл ngnix выглядит
# Nodes for load balancing myapp
upstream myapp_nodes{
ip_hash;
server 1.2.3.4:1001;
server 1.2.3.4:1002;
server 1.2.3.4:1003;
server 1.2.3.4:1004;
server 1.2.3.4:1005;
server 1.2.3.4:1006;
}
В моем myapp.js у меня есть глобальная переменная, называемая Queue
, и она хранит пользователей, когда они приходят на страницу и ожидают соединения с другим человеком. Когда приходит другой человек, старый человек выталкивается из очереди, и у них обоих общий идентификатор, чтобы общаться вместе. я использую socket.id от первого лица в качестве комнаты.
Пример кода
var Queue = []; //global array of people waiting to chat
socket.on("newUserJoinedFromClient", function (Username) {
//check if someone is already waiting then pop it and return the pop SID as room
if (Queue.length > 0) {
var partner = Queue.pop();
//remove special char from SID
var room = partner.id.replace(/[^a-zA-Z0-9]/g, "");
//return and tell the client its room
socket.emit('sendRoomToClient', {
room: room,
users: numUsers
}); //this person room will be same as the waiting partner room
}
// if nobody is in queue, queue is empty
else {
//add this user socket id to queue
Queue.push(socket);
//remove special char from SID
var room = socket.id.replace(/[^a-zA-Z0-9]/g, "");
//return and tell the client its room
socket.emit('sendRoomToClient', {
room: room,
users: numUsers
}); //coz we r calling socket itself id as his room, and he will wait
}
});
Логика, кажется, прекрасно работает на одноядерном myapp.js, если я запускаю его в forkрежим в простом 1 процессоре, но когда я запускаю его в режиме балансировки нагрузки NGNIX, он не соединяет 2 пользователей, если они приходят с разных IP-адресов. (или я предполагаю, что если оба попадут в другой процесс. См. сценарий ниже, который я не хочу, но это происходит сейчас,
- Пользователь A приходит на страницу, используя процесс (скажем, процесс-2), => он добавляется в очередь
- Пользователь B заходит на страницу с помощью процесса (скажем, process-4), => он также добавляется в очередь, но на самом деле это не должно, потому что в процессе 2 уже ждут 1 человек. В идеальном случае, пользователь А должен быть подключен и подключен к пользователю Б. Но здесь пользователь Б продолжает ждать.
- Если пользователь C приходит, он также переходит в состояние ожидания: (
Как передать мою глобальную переменную и ее значения всем процессам myapp, которые обрабатываются-1 к процессу-6?
Я уже использую Redis, как вы можете видеть здесь внизу https://socket.io/docs/using-multiple-nodes/, но он может только передавать события emit другим процессам, как я могу поделиться своей переменной очередичтобы сохранить его постоянное состояние и значения среди всех процессов myapp? Так что если
В идеале я хочу, чтобы он работал так:
- Пользователь A (первыйпользователь) приходит на страницу, используя процесс (скажем, процесс-5 или любой другой процесс по выбору балансировщика нагрузки), => он добавляется в очередь
- Пользователь Б (второй пользователь) приходит на страницу, используя процесс(скажем, процесс-2 или любой другой процесс), => Пользователь A подключен и подключен к этому пользователю B, потому что пользователь A уже ожидал случайного подключения к кому-либо.
Я просто хочу 2пользователи должны быть связаны друг с другом, когда и какэ, они приходят на эту общую страницу. и если 3-й приходит, он остается в состоянии ожидания (в очереди) до 4-го приходит, а затем 3-й выдвигается для подключения к 4-му, и так далее. Но сейчас моя переменная Queue кажется уникальной среди 6 процессов myapp.
Я использую redis, как это:
var app = express();
if (process.env.ENV == "development") {
var server = require("http").createServer(app);
} else {
// Setting up a HTTPS Server
var server = require("https").createServer(,
app // i have removed configs for https.
);
}
var io = require('socket.io');
var redis = require("socket.io-redis");
io.adapter(redis({
host: "localhost",
port: 6379
}));
server.listen(port, function () {
console.log("Server listening at port %d", port);
});
io.attach(server);
, а затем
io.sockets
.on('connection', socketioJwt.authorize({
hash: jwt,
timeout: 15000 // 15 seconds to send the authentication message
})).on('authenticated', function (socket) {
//all socket io events go here
});
Я не уверен, каков синтаксис для хранения и восстановления значений / значений массива переменной Queue в redis. Могу ли я получить помощь, пожалуйста?