WebSocket with .NET Core

By | 2024년 10월 13일
Table of Contents

WebSocket with .NET Core

.NET Core 애플리케이션에서 서버를 생성합니다.

서버

using System.Net;
using System.Net.WebSockets;
using System.Text;

var builder = WebApplication.CreateBuilder(args);
builder.WebHost.UseUrls("http://localhost:5050");
var app = builder.Build();
app.UseWebSockets();

var connections = new List<WebSocket>();

app.Map("/ws", async context =>
{
    if (context.WebSockets.IsWebSocketRequest)
    {
        var curName = context.Request.Query["name"];

        using var ws = await context.WebSockets.AcceptWebSocketAsync();

        connections.Add(ws);
        Console.WriteLine("Connected");

        await ReceiveMessage(ws,
            async (result, buffer) =>
            {
                if (result.MessageType == WebSocketMessageType.Text)
                {
                    string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                    Console.WriteLine("Received message : " + message);
                    await Broadcast(curName + ": " + message);
                }
                else if (result.MessageType == WebSocketMessageType.Close || ws.State == WebSocketState.Aborted)
                {
                    connections.Remove(ws);
                    Console.WriteLine("Disconnected");
                    await ws.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
                }
            });
    }
    else
    {
        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
    }
});
async Task ReceiveMessage(WebSocket socket, Action<WebSocketReceiveResult, byte[]> handleMessage)
{
    var buffer = new byte[1024 * 4];
    while (socket.State == WebSocketState.Open)
    {
        var result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
        handleMessage(result, buffer);
    }
}

async Task Broadcast(string message)
{
    var bytes = Encoding.UTF8.GetBytes(message);
    foreach (var socket in connections)
    {
        if (socket.State == WebSocketState.Open)
        {
            var arraySegment = new ArraySegment<byte>(bytes, 0, bytes.Length);
            await socket.SendAsync(arraySegment, WebSocketMessageType.Text, true, CancellationToken.None);
        }
    }
}

await app.RunAsync();

클라이언트

클라이언트는 JavaScript 로 생성합니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>웹소켓</title>
</head>
<body>
<h1>웹소켓 테스트</h1>

<button id="btn_send">메시지 전송</button>
<button id="btn_close">연결 끊기</button>
</body>
<script>
    // ====================================================
    // connect
    const webSocket = new WebSocket("ws://localhost:8080/ws");

    // ====================================================
    // on open
    webSocket.onopen = () => {
        console.log("웹소켓서버와 연결 성공");
    };

    // ====================================================
    // receive message
    webSocket.onmessage = function (event) {
        console.log(`서버 웹소켓에게 받은 데이터: ${event.data}`);
    }

    // ====================================================
    // on close
    webSocket.onclose = function() {
        console.log("서버 웹소켓 연결 종료");
    }

    // ====================================================
    // on error
    webSocket.onerror = function(event) {
        console.log(event)
    }

    let count = 1;
    document.getElementById("btn_send").onclick = function() {
        if(webSocket.readyState === webSocket.OPEN) {
            // ============================================
            // send
            webSocket.send(`증가하는 숫자를 보냅니다 => ${count}`);
            count++;
        }else{
            alert("연결된 웹소켓 서버가 없습니다.");
        }
    }

    document.getElementById("btn_close").onclick = function() {
        if(webSocket.readyState === webSocket.OPEN) {
            // ============================================
            // close
            webSocket.close();
        }else{
            alert("연결된 웹소켓 서버가 없습니다.");
        }
    }
</script>
</html>

답글 남기기