Skip to content

LadislavBohm/socket.io-client-core

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

  • Fully async and non-blocking flexible API
  • Emit events and receive optional callbacks
  • Subscribe/Unsubscribe to events
  • Monitor socket state
    • React to various socket high/low-level events

Changelog

  • 1.1.0
    • moved from Utf8Json to System.Text.Json (breaking change)
    • fixed parsing of multiple arguments where some of them were not JSON serialized
  • 1.2.0
    • added support for event message acknowledgements

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

  • Binary data (no support yet)
  • Implement automatic reconnection (you can do it by yourself using currently available events)
  • Document source code

Inspiration and Thanks

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