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

Конфигурация и ограничения

Настраивайте DarkWsOptions через AddDarkWs, services.Configure<DarkWsOptions>, привязку конфигурации или PostConfigure; они применяются в стандартном порядке Options:

builder.Services.AddDarkWs(options => {
options.MaxMessageSizeBytes = 256 * 1024;
options.MaxConcurrentRequestsPerConnection = 8;
options.ShutdownTimeout = TimeSpan.FromSeconds(5);
});

builder.Services.Configure<DarkWsOptions>(builder.Configuration.GetSection("DarkWs"));

Опции валидируются при первом разрешении и при запуске хоста; недопустимые значения приводят к OptionsValidationException. DarkWS читает их через IOptions<DarkWsOptions>, поэтому значения фиксируются при первом разрешении; изменение конфигурации во время работы не перенастраивает DarkWS.

Опции​

ОпцияПо умолчаниюЗначение
MaxMessageSizeBytes1 MiBМаксимальный размер полного входящего сообщения с учётом всех фрагментов
JsonOptionsJsonSerializerDefaults.WebСериализация конвертов и payload
MaxConcurrentRequestsPerConnection16Число одновременно выполняемых действий на одном подключении
KeepAliveInterval30 sИнтервал keep-alive транспорта
KeepAliveTimeout30 sДедлайн PONG на уровне транспорта (.NET 9 и новее)
ReceiveIdleTimeout2 minДедлайн ожидающего чтения (.NET 8)
SendTimeout30 sОжидание блокировки отправки плюс запись в сокет
BroadcastSendTimeout10 sДедлайн записи рассылки для каждого получателя
ShutdownTimeout10 sОбработчики, хуки закрытия middleware и close handshake при остановке
AuthenticationQueryParametertokenПараметр запроса, передаваемый аутентификатору при upgrade
InvalidActionErrordarkws:error:invalid-actionКод для неизвестных действий
InvalidRequestErrordarkws:error:invalid-requestКод для некорректных запросов и payload
AuthorizationRequiredErrordarkws:error:authorization-requiredКод для анонимных вызовов защищённых действий
RequestFailedErrordarkws:error:request-failedКод для непредвиденных сбоев
AuthenticationFailedErrordarkws:error:authentication-failedСохранена для совместимости исходного кода; не используется, поскольку auth: всегда отвечает auth:failed

Все таймауты должны быть положительными и не превышать 4294967294 миллисекунды. MaxMessageSizeBytes и MaxConcurrentRequestsPerConnection должны быть положительными, JsonOptions не может быть null, а AuthenticationQueryParameter и коды ошибок не могут быть пустыми.

Размер сообщения​

MaxMessageSizeBytes проверяется до разбора JSON и охватывает все фрагменты сообщения, включая команды аутентификации. Сообщение, размер которого ровно равен лимиту, принимается. Более крупное сообщение закрывает подключение со статусом 1009 (Message Too Big), и частично полученное сообщение не обрабатывается. Повышайте лимит, только если приложение действительно отправляет большие сообщения: вместе с ним растёт память на подключение.

Конкурентность запросов и backpressure​

Каждое подключение одновременно выполняет до MaxConcurrentRequestsPerConnection запросов. Когда столько запросов уже выполняется, подключение перестаёт читать, пока один из них не завершится. Ни один запрос не отклоняется, и ошибка занятости не отправляется; вместо этого сообщения клиента ждут в буферах сокета и сети.

  • Текстовые ping, auth: и logout читаются тем же циклом, поэтому они тоже ждут. При длительной нагрузке может истечь таймаут pong на клиенте.
  • auth: и logout обрабатываются в порядке чтения, не дожидаясь выполняющихся запросов.

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

DarkWS ограничивает работу только внутри одного подключения. Общее число подключений и лимиты на пользователя или IP задавайте в хосте или reverse proxy.

Проверка активности​

DarkWS обнаруживает «мёртвые» пиры по-разному в зависимости от рантайма:

  • .NET 9 и 10: сервер отправляет транспортные PING каждые KeepAliveInterval и обрывает подключение, если PONG не пришёл в течение KeepAliveTimeout.
  • .NET 8: каждое ожидающее чтение из сокета ограничено ReceiveIdleTimeout, который сбрасывается при получении каждого фрагмента. Простаивающие клиенты должны отправлять трафик приложения в пределах этого времени. Клиенты DarkWS по умолчанию отправляют текстовый ping каждые 30 секунд. Транспортные PONG не учитываются. Таймер работает только во время ожидающего чтения, поэтому он приостановлен, пока перегруженное подключение не читает.

.NET-клиент также обнаруживает «мёртвый» сервер с помощью собственного таймаута pong.

Отправка и остановка​

  • SendTimeout охватывает ожидание блокировки отправки подключения и запись в сокет. По истечении сокет обрывается.
  • Рассылки используют более короткий BroadcastSendTimeout для каждого получателя, поэтому медленный клиент не может надолго задержать рассылку.
  • При остановке подключение сразу удаляется из хранилища, а токены обработчиков отменяются. ShutdownTimeout — единый общий дедлайн для незавершённых обработчиков, хуков закрытия middleware и close handshake; если close handshake не завершился вовремя, сокет обрывается.

JSON​

JsonOptions общий для всех обработчиков. По умолчанию свойства прикладных DTO используют camelCase, а чтение не учитывает регистр. Имена полей конверта id, action, data и error закреплены атрибутами JsonPropertyName и не меняются от политики именования. Клиенты должны соблюдать схему DTO внутри data. Конверт Redis использует независимые настройки сериализации.

Логирование​

  • Успешные действия и некорректные запросы клиентов логируются на уровне Debug.
  • Непредвиденные сбои обработчиков и исключения, выброшенные аутентификатором во время auth:, логируются как предупреждения.
  • Сообщения исключений обработчиков попадают в лог, но никогда не отправляются клиентам.