62

Is there a c# client that follows the socket.io protocol? I have a socket.io server that is communicating with a socket.io javascript client via a website, but i also need to connect a c# piece to it that can send and receive messages. Is there a clean way to do this currently or will I have to write my own client.

Dested
  • 6,294
  • 12
  • 51
  • 73
  • 3
    @jgauffin, not really, as socket.io mixes in it's own secret sauce too. – Teo Klestrup Röijezon Jun 28 '11 at 22:36
  • Seems that at least some part of socket.io.js would have to be re-written in .NET for this to work. I tried fiddling with WebSocket4Net as a starting point, but it seems that there is still a ways to go. – tofutim Jan 24 '12 at 07:57
  • Perhaps this helps? http://groups.google.com/group/socket_io/browse_thread/thread/995602259ffc371a?pli=1 – tofutim Jan 24 '12 at 08:09
  • 1
    Incomplete implementation abandoned Feb 2011: https://github.com/jouz/socket.io-unity-client – tofutim Jan 24 '12 at 08:43
  • 1
    2012 attempt: http://socketiowebsockets.codeplex.com/releases/view/80290 – tofutim Jan 24 '12 at 08:58

6 Answers6

49

There is a project on codeplex ( NuGet as well ) that is a C# client for socket.io. (I am the author of this project - so I'm biased) I couldn't find exactly what I needed in a client, so I built it and released it back into the open.

Example client style:

socket.On("news", (data) =>    {
Console.WriteLine(data);
});
Jim Stott
  • 810
  • 8
  • 10
  • I can't wait to give it a try. Thanks – Dested May 09 '12 at 07:23
  • Wahooo! Thanks Jim, I'm going to give this a whirl tonight! Saturday Evening Planned I'm too cool. Is this on github? Also would this run find on client profile 4.0? – mike james Aug 03 '13 at 15:02
  • Jim, your library simply rocks! This solved a lot of issues I was having to connect a local printer with a cloud node app. – coffekid Nov 13 '13 at 02:13
  • Hi Jim I couldn't find any comment in this code, could n't understand the flow, can you tell me how can I use your code to connect to pre-existing node. I have node which I am using to connect to my driver app in (Android), a taxi system. – Syed Muhammad Mubashir Jan 23 '15 at 05:25
  • 4
    I'm pretty sure this client is incompatible with a socket.io server > v1.0. – Landon Poch Aug 04 '15 at 06:48
  • 21
    Downvote: this project has not been maintained in years. The websocket-sharp answer should be accepted. – benthehutt Feb 20 '18 at 00:39
46

Use the following library: https://github.com/sta/websocket-sharp It is available via NuGet:

PM> Install-Package WebSocketSharp -Pre

To connect to a Socket.IO 1.0 + server, use the following syntax:

using (var ws = new WebSocket("ws://127.0.0.1:1337/socket.io/?EIO=2&transport=websocket"))
{
    ws.OnMessage += (sender, e) =>
      Console.WriteLine("New message from controller: " + e.Data);

    ws.Connect();
    Console.ReadKey(true);
}

In other words, append this to the localhost:port - "socket.io/?EIO=2&transport=websocket".

My full server code: https://gist.github.com/anonymous/574133a15f7faf39fdb5

Jared Beach
  • 2,635
  • 34
  • 38
  • how would you do this if didn't know the port ahead of time? – prestonsmith Jan 17 '19 at 22:20
  • I don't think that would be possible. Do you have access to the computer where the socket server runs? – Jared Beach Jan 18 '19 at 13:25
  • I do but in production it's hosted on machine that will set the port dynamically. – prestonsmith Jan 18 '19 at 14:34
  • 2
    I just realized that it doesn't matter though because the site address will actually direct it to the right port on the server side – prestonsmith Jan 18 '19 at 14:35
  • 1
    How can connect to a room and read a particular message using this ? and how can i have retries on disconnection ? – mrid Mar 09 '19 at 12:00
  • 1
    How can I achieve this, io.emit('chat message', message); I tried ws.send("some string") but that closes the current socket connection and message isn't received on server moreover 'chat message' how to pass this event name. – Aniket Bhansali May 22 '19 at 10:46
  • 1
    @AniketBhansali for using things like io.emit, you need to create your own wrapper. Or best you need to pass ws.send with a JSON string and deserialize at client side to find out the message room. – Prakhar Londhe Feb 13 '20 at 05:49
  • Thank you! In my case - add in your code: ws.Send("42[\"chat message\",\"HELLO !\"]"); and it works ! – Ruslan Novikov Mar 22 '20 at 10:44
11

This package supports the latest protocol.
Github - https://github.com/HavenDV/H.Socket.IO/
C# Live Example - https://dotnetfiddle.net/FWMpQ3/
VB.NET Live Example - https://dotnetfiddle.net/WzIdnG/
Nuget:

Install-Package H.Socket.IO
using System;
using System.Threading.Tasks;
using H.Socket.IO;

#nullable enable

public class ChatMessage
{
    public string? Username { get; set; }
    public string? Message { get; set; }
    public long NumUsers { get; set; }
}
    
public async Task ConnectToChatNowShTest()
{
    await using var client = new SocketIoClient();

    client.Connected += (sender, args) => Console.WriteLine($"Connected: {args.Namespace}");
    client.Disconnected += (sender, args) => Console.WriteLine($"Disconnected. Reason: {args.Reason}, Status: {args.Status:G}");
    client.EventReceived += (sender, args) => Console.WriteLine($"EventReceived: Namespace: {args.Namespace}, Value: {args.Value}, IsHandled: {args.IsHandled}");
    client.HandledEventReceived += (sender, args) => Console.WriteLine($"HandledEventReceived: Namespace: {args.Namespace}, Value: {args.Value}");
    client.UnhandledEventReceived += (sender, args) => Console.WriteLine($"UnhandledEventReceived: Namespace: {args.Namespace}, Value: {args.Value}");
    client.ErrorReceived += (sender, args) => Console.WriteLine($"ErrorReceived: Namespace: {args.Namespace}, Value: {args.Value}");
    client.ExceptionOccurred += (sender, args) => Console.WriteLine($"ExceptionOccurred: {args.Value}");
    
    client.On("login", () =>
    {
        Console.WriteLine("You are logged in.");
    });
    client.On("login", json =>
    {
        Console.WriteLine($"You are logged in. Json: \"{json}\"");
    });
    client.On<ChatMessage>("login", message =>
    {
        Console.WriteLine($"You are logged in. Total number of users: {message.NumUsers}");
    });
    client.On<ChatMessage>("user joined", message =>
    {
        Console.WriteLine($"User joined: {message.Username}. Total number of users: {message.NumUsers}");
    });
    client.On<ChatMessage>("user left", message =>
    {
        Console.WriteLine($"User left: {message.Username}. Total number of users: {message.NumUsers}");
    });
    client.On<ChatMessage>("typing", message =>
    {
        Console.WriteLine($"User typing: {message.Username}");
    });
    client.On<ChatMessage>("stop typing", message =>
    {
        Console.WriteLine($"User stop typing: {message.Username}");
    });
    client.On<ChatMessage>("new message", message =>
    {
        Console.WriteLine($"New message from user \"{message.Username}\": {message.Message}");
    });
    
    await client.ConnectAsync(new Uri("wss://socketio-chat-h9jt.herokuapp.com/"));

    await client.Emit("add user", "C# H.Socket.IO Test User");

    await Task.Delay(TimeSpan.FromMilliseconds(200));

    await client.Emit("typing");

    await Task.Delay(TimeSpan.FromMilliseconds(200));

    await client.Emit("new message", "hello");

    await Task.Delay(TimeSpan.FromMilliseconds(200));

    await client.Emit("stop typing");

    await Task.Delay(TimeSpan.FromSeconds(2));

    await client.DisconnectAsync();
}

It also supports namespaces:

// Will be sent with all messages(Unless otherwise stated).
// Also automatically connects to it.
client.DefaultNamespace = "my";

// or

// Connects to "my" namespace.
await client.ConnectAsync(new Uri(LocalCharServerUrl), cancellationToken, "my");
// Sends message to "my" namespace.
await client.Emit("message", "hello", "my", cancellationToken);

Konstantin S.
  • 1,307
  • 14
  • 19
6

Well, I found another .Net library which works great with socket.io. It is the most updated too. Follow the below link,

Quobject/SocketIoClientDotNet

using Quobject.SocketIoClientDotNet.Client;

var socket = IO.Socket("http://localhost");
socket.On(Socket.EVENT_CONNECT, () =>
{
    socket.Emit("hi");
});

socket.On("hi", (data) =>
{
    Console.WriteLine(data);
    socket.Disconnect();
});
Console.ReadLine();

Hope, it helps someone.

pgcan
  • 1,199
  • 14
  • 24
0

I tried all of the above but somehow they doesn't talk with the service I am integrating with (maybe the service is bugged, I don't know which). So I wrote my own.

https://github.com/it9gamelog/socketio-with-ws-client

A minimalistic, single-file client implementation. Since socket-io is a dying technology, and the specification is quite complicated, bugs on either side might just never get fixed at any time. A single file approach is at least easier to tune, expand and debug.

HelloSam
  • 2,225
  • 1
  • 20
  • 21
-3

This depends on how your webserver looks. In some cases it might be applicable to make a listener for regular sockets too.
Otherwise, you will probably have to make your own client. However, you will probably only need to implement the WebSocket transport so it should be fairly straightforward anyway.

For what it's worth I'd suggest looking at the question "Is there a WebSocket client implemented for .NET?" and my (fairly simple) WebSocket Socket.IO transport client implementation for Java.

Community
  • 1
  • 1
Teo Klestrup Röijezon
  • 5,097
  • 3
  • 29
  • 37