UnicoreCMS

Вебсокеты

Онлайн серверов и события доната в реальном времени

Сервер поднимает Socket.IO на том же порту, что и HTTP. По этому каналу уходит всё, что обновляется без перезагрузки страницы: онлайн серверов, события покупок, состояние текущего пользователя.

Подключение

import { io } from 'socket.io-client'

const socket = io('https://api.example.com')

Без авторизации клиент попадает в публичную комнату и видит только общие события, то есть онлайн серверов.

const socket = io('https://api.example.com', {
  auth: { token: refreshToken },
})

Передаётся refresh-токен, а не access. Access протухает за минуты, и соединение пришлось бы переустанавливать постоянно.

Токен можно передать и заголовком Authorization: Bearer <refresh>.

const socket = io('https://api.example.com', {
  extraHeaders: { Authorization: 'Api-Key ваш-ключ' },
})

Проверяется так же, как в HTTP: и сам ключ, и IP подключения.

Отказ не рвёт соединение

Если авторизоваться не удалось, клиент не отключается, а попадает в публичную комнату. Так сайт продолжает показывать онлайн даже с протухшей сессией.

Комнаты

После подключения сервер разводит клиента по комнатам, чтобы события уходили точно адресатам.

КомнатаКто там
publicВсе неавторизованные
user:<uuid>Конкретный пользователь
api-key:<секрет>Конкретный API-ключ
Каждое право пользователяНапример kernel.unicore.connect

Комнаты по правам работают так: событие в комнату kernel.unicore.connect получают все плагины, и только они.

События от сервера

СобытиеКомуПолезная нагрузка
meКаждому при подключенииТекущий пользователь или null
servers/onlineВсемОнлайн по серверам
give_groupkernel.unicore.connectИгрок купил привилегию
take_groupkernel.unicore.connectСрок привилегии вышел
give_permissionkernel.unicore.connectКуплено отдельное право
take_permissionkernel.unicore.connectСрок права вышел

Запросы к серверу

socket.emit('servers/online', (onlines) => {
  console.log(onlines)
})

Пока это единственный запрос: получить текущий онлайн, не дожидаясь очередной рассылки. Онлайн и так обновляется каждые пять секунд, так что запрос пригодится в основном при первой отрисовке.

Смена прав на лету

Когда права API-ключа меняются в админке, все его открытые соединения принудительно разрываются. Клиент переподключится и попадёт в комнаты заново. Иначе он продолжал бы получать события по старым правам.

Прокси

Вебсокетам нужен апгрейд соединения. В nginx:

location / {
    proxy_pass http://127.0.0.1:5000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
}

Без этих строк Socket.IO свалится на long-polling, а на некоторых конфигурациях не заработает вовсе. Симптом узнаваемый: онлайн серверов не обновляется, пока не перезагрузишь страницу.

Содержание