Language: EN

csharp-websockets

How to use websockets in C# without libraries

Let’s see how to use WebSockets in C# without using libraries, only with the code and standard functionalities available in .NET.

WebSockets are a technology that allows bidirectional real-time communication between a server and a client through a single TCP/IP channel.

Unlike HTTP requests, WebSockets maintain a persistent connection between the client and the server. This allows for faster and bidirectional communication.

C# provides native support for WebSockets through the System.Net.WebSockets namespace. Although it is possible to use native C# WebSockets, using them “bare” is a real pain.

But, in case anyone needs it, here is an example of code. As an explanatory exercise of how it works, it’s not bad. Even if it’s just to appreciate the libraries we will see in future posts (you have the links below).

Examples of native Websockets in .NET

Let’s look at the necessary code to create a WebSocket communication in C# between a server and client.

Server Example

This would be the server code.

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

var httpListener = new HttpListener();
httpListener.Prefixes.Add("http://localhost:9006/");
httpListener.Start();

Console.WriteLine("Listening for WebSocket connections...");

while (true)
{
    var context = await httpListener.GetContextAsync();
    if (context.Request.IsWebSocketRequest)
    {
        var webSocketContext = await context.AcceptWebSocketAsync(subProtocol: null);
        var webSocket = webSocketContext.WebSocket;

        Console.WriteLine("Client connected");

        var receiveBuffer = new byte[1024];
        if (webSocket.State == WebSocketState.Open)
        {
            var receiveResult = await webSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
            if (receiveResult.MessageType == WebSocketMessageType.Text)
            {
                var receivedMessage = Encoding.UTF8.GetString(receiveBuffer, 0, receiveResult.Count);
                Console.WriteLine($"Received message: {receivedMessage}");

                var buffer = Encoding.UTF8.GetBytes($"Hello from server");
                await webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, CancellationToken.None);
            }
            else if (receiveResult.MessageType == WebSocketMessageType.Close)
            {
                await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None);
                Console.WriteLine("WebSocket closed.");
            }
        }
    }
    else
    {
        context.Response.StatusCode = 400;
        context.Response.Close();
    }
}

Client Example

And this is the client code.

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

using var ws = new ClientWebSocket();

var uri = new Uri("ws://localhost:9006");
await ws.ConnectAsync(uri, CancellationToken.None);

Console.WriteLine("Connected");

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

var receiveBuffer = new byte[1024];
var receiveResult = await ws.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), CancellationToken.None);
var receivedMessage = Encoding.UTF8.GetString(receiveBuffer, 0, receiveResult.Count);

Console.WriteLine($"Received message: {receivedMessage}");

As we can see, making a WebSocket by hand is a real pain. Usually, we would use a library. Here are some tutorials on the WebSocketSharp library and tutorials on the WatsonWebsocket library to simplify the use of WebSockets in C#.