Перейти к основному содержимому
Версия: 4.x

Решение проблем

Upgrade не проходит​

СимптомПричина и решение
HTTP 400Запрос не является WebSocket upgrade. Проверьте схему URL клиента (ws:///wss://) и промежуточные прокси.
HTTP 403Origin страницы отсутствует в WebSocketOptions.AllowedOrigins.
HTTP 500 или другая ошибка сервераАутентификатор выбросил исключение во время upgrade; DarkWS 4.x это исключение не перехватывает. Проверьте лог ошибок сервера и возвращайте null для недействительных токенов вместо выбрасывания исключения.
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]. В браузере аутентифицируйте каждый новый сокет: передавайте токен через query или вызывайте authenticate() при каждом open.
darkws:error:invalid-requestВ запросе нет action или используется зарезервированный id, либо payload отсутствует для non-nullable параметра или имеет неверный тип. Сверьте имена JSON-свойств с политикой именования сервера.
darkws:error:request-failedОбработчик выбросил непредвиденное исключение. Исключение есть в логе сервера.
Таймаут без ответаОбработчик медленный, или сокет полуоткрыт. Сервер также не отвечает, если сообщение не является JSON или не содержит строкового id, либо если обработчик вернул null или результат, который не удаётся сериализовать (в логе сервера есть предупреждение). Проверьте requestTimeout и настройки heartbeat.

Соединения обрываются​

Код закрытия или симптомПричина и решение
1009Сообщение превысило MaxMessageSizeBytes (сервер) или MaxMessageSizeBytes (.NET-клиент). Отправляйте меньше или увеличьте лимит.
1003 от .NET-клиентаСервер отправил бинарный фрейм.
На .NET 8 простаивающие соединения закрываются примерно через 2 минутыКлиент не отправляет трафик. Клиенты DarkWS отправляют ping каждые 30 секунд; собственные клиенты должны отправлять ping.
.NET-клиент сообщает, что сервер не подтвердил heartbeat, и переподключаетсяpong не пришёл в пределах PongTimeout. Прокси может отбрасывать текстовые фреймы, или соединение находится на пределе числа запросов, и сервер перестал читать.
Соединения закрываются во время деплояПри остановке обработчики отменяются, а сокеты закрываются в пределах ShutdownTimeout. Клиенты переподключаются автоматически.

Рассылки не доходят​

  • Сессия получателя не содержит группу. Группы читаются при подключении и повторной аутентификации; после их изменения вызовите ConnectionStorage.Add(connection).
  • При нескольких инстансах Redis не настроен, инстансы используют разные имена каналов, или инстанс был отключён от Redis в момент публикации сообщения.
  • В браузере action, с которым сравнивает ваш обработчик message, отличается регистром; имена действий чувствительны к регистру.
  • В .NET типизированная подписка On<T> требует data; для рассылок без данных используйте On(action, () => …). Рассылка со значением null тоже приходит без data.

Сессии выглядят неправильно​

  • HandlerBase.Session выбрасывает исключение для анонимных соединений. Для проверки на null используйте Connection.Session.
  • HandlerBase<TSession>.Session выбрасывает исключение, если сессия не является TSession, например когда всё ещё активен аутентификатор ASP.NET по умолчанию. Зарегистрируйте AddAuthenticator<TAuthenticator, TSession>().
  • После неудачной auth: сессия очищается.
  • После переподключения серверная сессия новая. Браузерный клиент восстанавливает её только через query для upgrade или повторный вызов authenticate(); .NET-клиент — только через AuthenticationTokenProvider.

Ошибки при запуске​

InvalidOperationException при запуске указывает обработчик, метод и причину. Частые причины:

  • [Authorize] или атрибут политики на обработчике или действии; см. Обработчики и действия.
  • Действие, которое не является публичным методом экземпляра, возвращает что-то кроме IResponse или Task<IResponse>, имеет более одного параметра или является generic.
  • Два действия с одинаковым именем handler:action.
  • Повторный вызов AddDarkWs().

OptionsValidationException означает, что значение параметра вне допустимого диапазона, например нулевой таймаут.