LadislavBohm / socket.io-client-core

High-Performance Socket.IO client in C#
MIT License
73 stars 11 forks source link
socket socket-io socket-io-client socket-io-net socketio socketio-client

socket.io client written in C#

High-performance C# client for socket.io. Flexibility achieved via Reactive Extensions and optional configurations. Built on top of .NET Standard 2.1.

Installation

PM> Install-Package Socket.Io.Client.Core

Features

Changelog

Examples

For more examples see test project.

Real-world example can be found in my other repository - Crypto Compare streamer API client: https://github.com/LadislavBohm/cryptocompare-streamer

Open/Close Connection

//socket is disposed using new "using" syntax, don't forget to dispose it!
using var client = new SocketIoClient();
//optionally supply additional parameters using OpenOptions
var options = new SocketIoOpenOptions("custom-path");

await client.OpenAsync(new Uri("http://localhost:3000"), options);
await client.CloseAsync();

Subscribe to built-in events

Events are implemented using Reactive Extensions, for more information see here or a very nice tutorial. However a very basic usage will be shown here.

Basic subscriptions

using var client = new SocketIoClient();

//no need to hold reference to subscription as it
//will be automatically unsubscribed once client is disposed
client.Events.OnOpen.Subscribe((_) =>
{
    Console.WriteLine("Socket has been opened");
});

//subscribe to event with data
client.Events.OnPacket.Subscribe(packet =>
{
    Console.WriteLine($"Received packet: {packet}");
});

await client.OpenAsync(new Uri("http://localhost:3000"));

Time-based subscriptions

using var client = new SocketIoClient();

//in reality you shouldn't need to work directly with packets
var subscription = client.Events.OnPacket.Subscribe(packet =>
{
    Console.WriteLine($"Received packet: {packet}");
});

await client.OpenAsync(new Uri("http://localhost:3000"));
//let the subscription live for 500 milliseconds
await Task.Delay(500);
//unsubscribe from this event (socket and other subscriptions are still running)
subscription.Dispose();

Subscribe/Unsubscribe to custom events

Event data from socket.io are received as an array. In event data object you can access the whole array or for convenience just the first item (if available).

using var client = new SocketIoClient();

//in this example we throttle event messages to 1 second
var someEventSubscription = client.On("some-event")
    .Throttle(TimeSpan.FromSeconds(1)) //optional
    .Subscribe(message =>
{
    Console.WriteLine($"Received event: {message.EventName}. Data: {message.FirstData}");
});

await client.OpenAsync(new Uri("http://localhost:3000"));

//optionally unsubscribe (equivalent to off() from socket.io)
someEventSubscription.Dispose();

Acknowledgements

You can optionally send ACK to server when you receive a message. There is also option to send any data back to server.

using var client = new SocketIoClient();

client.On("messages").Subscribe(e =>
{
    //always check before calling acknowledgement
    if (e.SupportsAcknowledge)
    {
        //without any data
        e.Acknowledge();

        //OR with any optional serializable data
        e.Acknowledge("message has been processed");
    }
});

Emit message to server

All emitted messages have an optional callback (acknowledgement) possible via subscribing to the result of Emit method. All operations are non-blocking and asynchronously handled by underlying Channel library.

using var client = new SocketIoClient();

client.Emit("some-event"); //no data emitted
client.Emit("some-event", "some-data"); //string data
client.Emit("some-event", new {data = "some-data"}); //object data

//with callback (acknowledgement)
//it is always called only once, no need to unsubscribe/dispose
client.Emit("some-event", "some-data").Subscribe(ack =>
{
    Console.WriteLine($"Callback with data: {ack.Data[0]}.");
});

Configuration

//optionally supply your own implementation of ILogger (default is NullLogger)
var options = new SocketIoClientOptions()
    .With(logger: new NullLogger<SocketIoClient>());

using var client = new SocketIoClient(options);

To-do

Inspiration and Thanks

Thanks to following people and libraries that I used as an inspiration or help during development.