Как работает WebSocket в C#

WebSocket — это протокол, обеспечивающий двустороннюю связь между клиентом и сервером по постоянному соединению. Он используется для создания интерактивных веб-приложений, таких как чаты, онлайн-игры и системы мониторинга в реальном времени.

Принцип работы WebSocket

При установке соединения WebSocket использует HTTP-запрос с заголовком Upgrade, который переводит соединение в режим двустороннего взаимодействия. После успешного рукопожатия соединение остается открытым, позволяя передавать данные без необходимости повторного установления соединения.

Создание WebSocket-сервера в C#

ASP.NET Core предоставляет встроенную поддержку WebSocket. Для работы необходимо добавить WebSocket в конвейер middleware и обработать входящие соединения.

Настройка WebSocket в ASP.NET Core

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseWebSockets();
app.Use(async (context, next) =>
{
    if (context.Request.Path == "/ws" && context.WebSockets.IsWebSocketRequest)
    {
        using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
        await HandleWebSocketAsync(webSocket);
    }
    else
    {
        await next();
    }
});

app.Run();

Обработка WebSocket-сообщений

private static async Task HandleWebSocketAsync(WebSocket webSocket)
{
    var buffer = new byte[1024];
    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);
}

Создание WebSocket-клиента в C#

Клиент WebSocket можно реализовать с помощью ClientWebSocket.

using var client = new ClientWebSocket();
await client.ConnectAsync(new Uri("ws://localhost:5000/ws"), CancellationToken.None);

var message = Encoding.UTF8.GetBytes("Hello WebSocket");
await client.SendAsync(new ArraySegment<byte>(message), WebSocketMessageType.Text, true, CancellationToken.None);

var buffer = new byte[1024];
var result = await client.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

Console.WriteLine(Encoding.UTF8.GetString(buffer, 0, result.Count));

Преимущества WebSocket

  • Двусторонняя связь без накладных расходов HTTP-запросов
  • Низкая задержка и высокая производительность
  • Поддержка бинарных и текстовых данных
  • Оптимизация сетевого трафика за счет меньшего количества заголовков

Недостатки WebSocket

  • Требует поддержки со стороны серверов и прокси
  • Может блокироваться корпоративными брандмауэрами
  • Не поддерживается во всех окружениях (например, некоторых серверныхless-платформах)