feat(gateway): WebSocket Gateway с HELLO, IDENTIFY и READY
Реализован Gateway по AGENT.md §8.3:
- оп-коды 0/1/2/3/4/7/10/11, единый конверт {op,t,d,s};
- HELLO с интервалом сердцебиения (45 с) и идентификатором сессии;
- IDENTIFY/RESUME с проверкой токена через auth.ResolveSession;
- READY: пользователь, серверы, видимые комнаты, роли, участники и права,
собранные через движок прав (VIEW_CHANNEL-фильтрация);
- HEARTBEAT → HEARTBEAT_ACK, лимит частоты IDENTIFY (5 с);
- RESUME: буфер на 1000 событий с TTL 5 минут, догон пропущенных событий и
подтверждение RESUMED, полный READY при расхождении состояния;
- рассылка Dispatch/SendToUser с буферизацией для отключённых сессий;
- проверка Origin по allowlist доменов инстанса (AGENT.md §9.7);
- httpx.statusRecorder пробрасывает Hijack, иначе апгрейд ломается.
Тесты: 6 сценариев Gateway (READY, скрытые комнаты, неверный токен,
heartbeat, dispatch, RESUME) и 2 теста маршрута /gateway через полный стек
middleware, включая отклонение чужого Origin.
This commit is contained in:
+3
-1
@@ -16,6 +16,7 @@ import (
|
||||
"glchat/internal/auth"
|
||||
"glchat/internal/config"
|
||||
"glchat/internal/database"
|
||||
"glchat/internal/gateway"
|
||||
"glchat/internal/server"
|
||||
"glchat/internal/store"
|
||||
)
|
||||
@@ -145,7 +146,8 @@ func run() error {
|
||||
return fmt.Errorf("initialize authentication: %w", err)
|
||||
}
|
||||
|
||||
srv := server.New(cfg, db, logger, server.Deps{Store: st, Auth: authService})
|
||||
gatewayService := gateway.New(st, authService, gateway.NewSnapshot(st), logger, cfg.AllowedOrigins())
|
||||
srv := server.New(cfg, db, logger, server.Deps{Store: st, Auth: authService, Gateway: gatewayService})
|
||||
errCh := make(chan error, 1)
|
||||
go func() {
|
||||
logger.Info("http server listening",
|
||||
|
||||
Reference in New Issue
Block a user