Решение проблем
Upgrade не проходит
| Симптом | Причина и решение |
|---|---|
| HTTP 400 | Запрос не является WebSocket upgrade. Проверьте схему URL клиента (ws:///wss://) и промежуточные прокси. |
| HTTP 401 | Аутентификатор выбросил исключение. Проверьте предупреждения в логе сервера. Установите AcceptAnonymousOnUpgradeAuthenticationException, чтобы вместо этого принимать соединение анонимно. |
| HTTP 403 | Origin страницы отсутствует в WebSocketOptions.AllowedOrigins или DarkWsOptions.AllowedOrigins. |
| HTTP 404 или upgrade так и не завершается | UseWebSockets() отсутствует или стоит после MapDarkWs, либо обратный прокси не передаёт заголовки Upgrade/Connection. |
| .NET-клиент перестаёт повторять попытки после 401/403 | Ошибки аутентификации постоянны. Исправьте учётные данные и вызовите ConnectAsync. |
За nginx передавайте заголовки upgrade и увеличьте таймаут чтения так, чтобы он превышал интервал heartbeat:
location /ws {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 120s;
}
Запросы завершаются ошибкой
| Ошибка | Причина и решение |
|---|---|
darkws:error:invalid-action | Имя не в формате handler:action, или сборка обработчика не зарегистрирована. |
darkws:error:authorization-required | У соединения нет сессии. Сначала пройдите аутентификацию или пометьте действие [AllowAnonymous]. В браузере используйте authenticationToken, чтобы переподключения проходили аутентификацию до запросов. |
darkws:error:invalid-request | Payload отсутствует для non-nullable параметра, имеет неверный тип или использует зарезервированный id. Сверьте имена JSON-свойств с политикой именования сервера. |
darkws:error:request-failed | Обработчик выбросил исключение, вернул null или вернул то, что не удаётся сериализовать. Исключение есть в логе сервера. |
darkws:error:busy | Слишком много медленных запросов в одном соединении. См. backpressure. |
| Таймаут без ответа | Обработчик медленный, или сокет полуоткрыт. Проверьте requestTimeout и настройки heartbeat. |
Соединения обрываются
| Код закрытия или симптом | Причина и решение |
|---|---|
| 1009 | Сообщение превысило MaxMessageSizeBytes (сервер) или MaxMessageSizeBytes (.NET-клиент). Отправляйте меньше или увеличьте лимит. |
| 1008 | Команды auth:/logout пришли, когда очередь была заполнена. Не флудите аутентификацией. |
| 1003 от .NET-клиента | Сервер отправил бинарный фрейм. |
| На .NET 8 простаивающие соединения закрываются примерно через 2 минуты | Клиент не отправляет трафик. Клиенты DarkWS отправляют ping каждые 30 секунд; собственные клиенты должны отправлять ping. |
| Браузер переподключается каждые 30 секунд | pong не приходит. Прокси может отбрасывать текстовые фреймы, или сервер перегружен. Проверьте pongTimeout. |
| Соединения закрываются во время деплоя | При остановке обработчики отменяются, а сокеты закрываются в пределах ShutdownTimeout. Клиенты переподключаются автоматически. |
Рассылки не доходят
- Сессия получателя не содержит группу. Группы читаются при подключении и повторной
аутентификации; после их изменения вызовите
IDarkWsConnections.Refresh(connection). - Цель исключает получателя (
ExceptConnection,ExceptSession). - Список групп, переданный в
BroadcastTarget.Groups, пуст. - При нескольких инстансах Redis не настроен, инстансы используют разные имена каналов, или инстанс был отключён от Redis в момент публикации сообщения.
- Инстанс версии ниже 5.0 использует тот же канал и пропускает сообщения с
Groups. - В браузере имя в
onActionотличается регистром; имена действий чувствительны к регистру. - В .NET типизированная подписка
On<T>требуетdata; для рассылок без данных используйтеOn(action, () => …).
Сессии выглядят неправильно
HandlerBase.Sessionвыбрасывает исключение для анонимных соединений. Для проверки на null используйтеConnection.Session.HandlerBase<TSession>.Sessionвыбрасывает исключение, если сессия не являетсяTSession, например когда всё ещё активен аутентификатор ASP.NET по умолчанию. ЗарегистрируйтеAddAuthenticator<TAuthenticator, TSession>().- После неудачной
auth:сессия очищается, если не установленKeepSessionOnFailedAuthentication. - После переподключения серверная сессия новая. Клиенты восстанавливают её только с
помощью
authenticationToken(браузер) илиAuthenticationTokenProvider(.NET).
Ошибки при запуске
InvalidOperationException при запуске указывает обработчик, метод и причину.
Частые причины:
[Authorize]или атрибут политики на обработчике или действии; см. Авторизация.- Действие, которое возвращает что-то кроме
IResponseилиTask<IResponse>, имеет более одного параметра или является generic. - Повторный вызов
AddDarkWs(),AddAuthenticator()илиAddRedis().
OptionsValidationException означает, что значение параметра вне допустимого
диапазона, например нулевой таймаут.