Skip to content

Instantly share code, notes, and snippets.

@siketyan
Last active December 31, 2019 08:12
Show Gist options
  • Save siketyan/3d6771bc02f49a06dd322f4c82e86985 to your computer and use it in GitHub Desktop.
Save siketyan/3d6771bc02f49a06dd322f4c82e86985 to your computer and use it in GitHub Desktop.
Event-driven WebSocket Client on .NET
using System;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
namespace WebSocketClient
{
public class WebSocketClient : IDisposable
{
private const int MessageBufferSize = 256;
public event EventHandler<string> MessageReceived;
public event EventHandler Disconnected;
private readonly Uri _uri;
private readonly ClientWebSocket _socket;
public WebSocketClient(string uri) : this(new Uri(uri)) { }
public WebSocketClient(Uri uri)
{
_uri = uri;
_socket = new ClientWebSocket();
}
public void Connect()
{
ConnectAsync();
}
private async void ConnectAsync()
{
if (_socket.State == WebSocketState.Open)
{
throw new InvalidOperationException("Already opened connection.");
}
await _socket.ConnectAsync(_uri, CancellationToken.None);
while (_socket.State == WebSocketState.Open)
{
var buff = new ArraySegment<byte>(new byte[MessageBufferSize]);
var ret = await _socket.ReceiveAsync(buff, CancellationToken.None);
var str = new UTF8Encoding().GetString(buff.Take(ret.Count).ToArray());
MessageReceived?.Invoke(this, str);
}
Disconnected?.Invoke(this, null);
}
public void Disconnect()
{
if (_socket.State != WebSocketState.Open)
{
throw new InvalidOperationException("No connection opened.");
}
_socket.CloseAsync(
WebSocketCloseStatus.NormalClosure,
string.Empty,
CancellationToken.None
);
}
public void Dispose()
{
Disconnect();
_socket?.Dispose();
}
}
public class Example
{
public static void Main()
{
using (var client = new WebSocketClient("ws://localhost/"))
{
client.MessageReceived += (s, a) => Console.WriteLine("Received: " + a);
client.Disconnected += (s, a) => Console.WriteLine("Disconnected!");
client.Connect();
}
Console.ReadKey();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment