Javascript-форум (https://javascript.ru/forum/)
-   Node.JS (https://javascript.ru/forum/node-js-io-js/)
-   -   Сервер socket на nodejs (https://javascript.ru/forum/node-js-io-js/82636-server-socket-na-nodejs.html)

HotReboot 04.06.2021 03:36

Сервер socket на nodejs
 
Здравствуйте. Не могу разобраться в структуре массивов socket, sockets. Как должно: при подключение отправляется user_nick. Может быть в разных браузерах/вкладках одинаковый user_nick. При отправки сообщения отправляется user_from равный user_nick, а так же user_to. Сервер должен взять и user_from и user_to послать только им сообщение. Спасибо.

ksa 04.06.2021 08:00

Цитата:

Сообщение от HotReboot
в разных браузерах/вкладках одинаковый user_nick

Ты про веб сокеты имел ввиду?
Поскольку сокеты это просто сетевое соединение (не http(s))...

ksa 04.06.2021 08:57

Цитата:

Сообщение от HotReboot
Может быть в разных браузерах/вкладках одинаковый user_nick.

Вот что написано в некоем описании веб-сокетов
Цитата:

Каждое соединение имеет свой уникальный идентификатор, зная который можно отправить сообщение конкретному клиенту (см. в примере маршрут /client/:id).
https://nodejsdev.ru/doc/websocket/

Про user_nick там вообще ни слова... :)

HotReboot 04.06.2021 10:26

ksa,
Это я знаю. Но есть же split. Т.е. у сервера база юзеров будет например так user_from-client/:id

ksa 04.06.2021 10:48

Цитата:

Сообщение от HotReboot
Это я знаю.

Значит ты сможешь понять каким ИД нужно отвечать.
Если идеологически у тебя есть какие-то "юзеры" (х/з как определяемые) - ты так же можешь определить на какие ИД (подключения) отсылать или не отсылать сообщения.

HotReboot 04.06.2021 11:18

ksa,
Вся проблема в том, что не из документации, не из примеров в инете я не могу найти пример как вытащить id конкретного соединения т.е алгоритм примерно такой:
при соединение у меня отсылается типа ник.
socket = io("https://example.com:8443", {
  auth: {
    token: "example_user"
  }
});

и в сокет он доступен по socket.handshake.auth.token
socket.on("message", (data) // формат data [user_from, user_to, msg]
for (тут перебираем массив сокетов) // вот тут я не понимаю какой массив брать.
    if (socket.handshake.auth.token == data.user_to)
     //берём id сокета и отсылаем 
       io.sockets.sockets[id].emit('message', data.msg...

Vlasenko Fedor 04.06.2021 11:56

HotReboot,
неправильно так идентифицировать с помощью ника пользователя
socket.io - говно еще то может работать в нескольких режимах transports "polling", "websocket" по дефолту это polling, а в режиме websocket оно не работает по умолчанию
причем в режиме polling можно отпровлять заголовки header, а в websocket такого они не реализовали
к чему я это все
вам нужен transport websocket и в этом режиме вызывать auth где использовать обычный jwt токен для идентификации, всем остальным дисконнект
у клиента может быть несколько сессий
примерно так
const Connections = new Set();
socket.on('auth', token => {
        const user = verifyToken(token);
        if (user) {
            socket.user = user;
            Connections.add(socket);
            redisPub.sadd("users", user.id);
        } else {
            socket.emit('error', {message: 'UNAUTHORIZED'});
            socket.disconnect();
        }
    })
//--------
const send = (msg, users) => {
    Connections.forEach(socket => {
        if ('user' in socket && users.includes(socket.user.id)) {
            socket.emit('message', msg);
        }
    });
};

при этом стоит использовать хотя-бы redis для маштабирования
Использование Redis в качестве брокера сообщений стр 357
Каскиаро М., Маммино Л.
Шаблоны проектирования Node.js / пер. с анг. А. Н. Киселева. – М.: ДМК Пресс,
2017. – 396 с.: ил.

HotReboot 04.06.2021 12:28

Vlasenko Fedor,
Это вы мне примерно уже отвечали. Только вот websoket при close рвёт все соединения в вкладках. Точнее так - если открыты 3 вкладки и одна пересоединилась, то в других соединения порвутся.

Vlasenko Fedor 04.06.2021 12:44

Цитата:

Сообщение от HotReboot
Точнее так - если открыты 3 вкладки и одна пересоединилась, то в других соединения порвутся.

Не наблюдаю такого эффекта
Открываю несколько вкладок везде connect и auth
Принудительно перерезагружаю одну, закрываю все остальные работают(принимают и отправляют)
каждая вкладка это отдельный сокет с одним и тем же user, но разным socket.id
потому привел пример как отослать сообщения всем сокет сеансам одного (нескольким) пользователя (..лям)

HotReboot 04.06.2021 12:49

Vlasenko Fedor,
Да и мне бы разобраться хотя бы с этим, а вы мне ещё redis подбрасываете. У меня есть-то 10 юзеров да сервер с 1 ядром и 1 гигабайтом.


Часовой пояс GMT +3, время: 14:12.