← Назад к вопросам

Что такое веб-сокеты?

2.2 Middle🔥 131 комментариев
#ASP.NET и Web API#Асинхронность и многопоточность

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое веб-сокеты?

Веб-сокеты (WebSockets) — это современный протокол связи, работающий поверх TCP, который обеспечивает полнодуплексный (full-duplex) двусторонний обмен данными между клиентом (например, веб-браузером) и сервером через одно постоянное соединение. В отличие от традиционного HTTP, который следует модели "запрос-ответ", веб-сокеты позволяют передавать данные в реальном времени без необходимости постоянных переподключений.

Ключевые особенности и преимущества

  • Двусторонняя связь: Сервер может инициировать отправку данных клиенту в любой момент, а не только в ответ на запрос. Это идеально для чатов, уведомлений, онлайн-игр.
  • Низкие задержки: После установки соединения обмен данными происходит с минимальными накладными расходами, так как не требуется передавать заголовки HTTP с каждым сообщением.
  • Постоянное соединение: Соединение устанавливается один раз по протоколу HTTP (через "рукопожатие" — handshake) и затем обновляется до протокола WebSocket. Оно остается открытым, пока одна из сторон не закроет его.
  • Эффективность: Протокол легковесный. Кадры данных (frames) имеют небольшой заголовок (от 2 байт), что снижает нагрузку на сеть по сравнению с постоянными HTTP-запросами (long-polling, polling).

Как работает установка соединения (Handshake)?

Процесс начинается с HTTP-запроса от клиента с заголовком Upgrade. Если сервер поддерживает WebSockets, он отвечает подтверждением, и соединение переключается с HTTP на протокол WebSocket.

Пример запроса от клиента:

GET /ws-chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

Пример ответа от сервера:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

После этого общение продолжается по протоколу WebSocket.

Практическое использование в C# (ASP.NET Core)

В экосистеме .NET для работы с веб-сокетами используется пространство имен System.Net.WebSockets. ASP.NET Core предоставляет удобную абстракцию через middleware.

Пример минимального middleware для обработки WebSocket-соединений:

public class WebSocketMiddleware
{
    private readonly RequestDelegate _next;

    public WebSocketMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        if (context.WebSockets.IsWebSocketRequest)
        {
            // Принимаем соединение
            using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
            await HandleWebSocketConnection(webSocket);
        }
        else
        {
            await _next(context);
        }
    }

    private async Task HandleWebSocketConnection(WebSocket webSocket)
    {
        var buffer = new byte[1024 * 4]; // Буфер для приема данных
        var receiveResult = await webSocket.ReceiveAsync(
            new ArraySegment<byte>(buffer), CancellationToken.None);

        while (!receiveResult.CloseStatus.HasValue)
        {
            // Эхо-сервер: отправляем полученное сообщение обратно
            await webSocket.SendAsync(
                new ArraySegment<byte>(buffer, 0, receiveResult.Count),
                receiveResult.MessageType,
                receiveResult.EndOfMessage,
                CancellationToken.None);

            // Ждем следующее сообщение
            receiveResult = await webSocket.ReceiveAsync(
                new ArraySegment<byte>(buffer), CancellationToken.None);
        }

        // Корректно закрываем соединение
        await webSocket.CloseAsync(
            receiveResult.CloseStatus.Value,
            receiveResult.CloseStatusDescription,
            CancellationToken.None);
    }
}

Для SignalR (высокоуровневая абстракция):
Библиотека SignalR использует WebSockets как основной транспорт, когда он доступен, автоматически предоставляя разработчику простую модель RPC (удаленный вызов методов) для обмена сообщениями.

// Пример хабара SignalR
public class ChatHub : Hub
{
    public async Task SendMessage(string user, string message)
    {
        // Вызываем метод на всех подключенных клиентах
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}

Сравнение с HTTP и сценарии использования

АспектHTTP (Request/Response)WebSockets
Модель связиОдносторонняя (клиент инициирует)Двусторонняя, асинхронная
СоединениеВременное, закрывается после ответаПостоянное
Накладные расходыВысокие (заголовки каждый раз)Низкие (после handshake)
Идеальные сценарииСтатические страницы, REST APIЧат, трейдинг, игры, коллаборация, live-дашборды

Важные аспекты для Backend-разработчика

  • Масштабируемость: Постоянные соединения потребляют ресурсы сервера (память, дескрипторы). Необходимо продумывать архитектуру для горизонтального масштабирования (использовать Redis Backplane в SignalR, sticky sessions или внешние службы обмена сообщениями).
  • Управление состоянием: В отличие от stateless HTTP, WebSocket-соединение stateful. Сервер должен отслеживать подключенных клиентов и их контекст.
  • Обработка ошибок и переподключение: Необходимо реализовывать механизмы переподключения при разрыве связи, обработку таймаутов и "пинг-понг" (keep-alive сообщения).
  • Безопасность: Всегда использовать защищенную версию протокола — WSS (WebSocket Secure), аналогично HTTPS. Это шифрует трафик и защищает от атак "человек посередине". Также важно валидировать входные данные, как и в случае с HTTP.

Веб-сокеты стали неотъемлемой частью современного веба, позволяя создавать высокоинтерактивные и отзывчивые приложения. Для C# разработчика понимание как низкоуровневого API (System.Net.WebSockets), так и высокоуровневых фреймворков (SignalR), является ключевым навыком для реализации функций реального времени.