Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the simplest way to create a Websocket server in c#?

Tags:

c#

websocket

Someone is building a native chat app for us, and Websockets seem to be the way to go for synchronicity between the app and our server (which uses Web API).

We looked into SignalR, but it seems to require jQuery and thus will be cumbersome in a native app.

Is there a "pure" and simple way to use Websockets in C# that is scalable? By "easy" I mean as easy as getting started with Web API for example (I've seen examples where you have to create a TCP listener and comply with latest RFC specifications et.c. - not simple in my opinion), and by "scalable" I mean not blocking threads.

Edit: question title renamed to amplify the importance of the implementation of the websocket server

like image 811
Scarabas Avatar asked Jan 28 '23 06:01

Scarabas


2 Answers

This is not fully addressing your question, however

We looked into SignalR, but it seems to require jQuery and thus will be cumbersome in a native app

This is not correct, it actually supports self hosted and clients of various platforms

Someone is building a native chat app for us, and Websockets seem to be the way to go for synchronicity between the app and our server (which uses Web API).

SignalR and WebSocket

SignalR uses the new WebSocket transport where available, and falls back to older transports where necessary. While you could certainly write your application using WebSocket directly, using SignalR means that a lot of the extra functionality you would need to implement will already have been done for you. Most importantly, this means that you can code your application to take advantage of WebSocket without having to worry about creating a separate code path for older clients. SignalR also shields you from having to worry about updates to WebSocket, since SignalR will continue to be updated to support changes in the underlying transport, providing your application a consistent interface across versions of WebSocket.

Though just as a last thought, SignalR is not the saviour of humanity, however it is very light and robust, and suited for what it is. Though, you have mentioned you want to have a chat setup targeting 10000 uses. You should probably weigh up all the options first, including third party solutions and also traditional services like WCF.

Further Reading

SignalR Console app example

ASP.NET SignalR Hubs API Guide - .NET Client (C#)

like image 23
TheGeneral Avatar answered Jan 31 '23 09:01

TheGeneral


SignalR is great for cases where:

1) You need a fallback in case websockets aren't available

AND

2) You have control over the implementation of the client (there's a specific protocol that has to be followed by the client)

The easiest way I can think of, from what you tell us about the project (limited control of the implementation of the client, websocket server implementation only, Web API) is Microsoft.WebSockets.

You can install Microsoft.WebSockets from NuGet and be up and running with a websocket server in minutes. There a few tutorials out there (ex.: https://dejanstojanovic.net/aspnet/2014/june/database-change-notifications-in-aspnet-using-websocket/), but essentially:

1) make sure your IIS has websockets enabled

2) create a Web API controller that handles websocket requests. Ex.:

using System;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using Microsoft.Web.WebSockets;

public class SomeController : ApiController
{
    // Has to be called something starting with "Get"
    public HttpResponseMessage Get()
    {
        HttpContext.Current.AcceptWebSocketRequest(new SomeWebSocketHandler());
        return Request.CreateResponse(HttpStatusCode.SwitchingProtocols);
    }

    class SomeWebSocketHandler : WebSocketHandler
    {
        public SomeWebSocketHandler() { SetupNotifier(); }
        protected void SetupNotifier()
        {
            // Call a method to handle whichever change you want to broadcast
            var messageToBroadcast = "Hello world";
            broadcast(messageToBroadcast);
        }

        private static WebSocketCollection _someClients = new WebSocketCollection();

        public override void OnOpen()
        {
            _someClients.Add(this);
        }

        public override void OnMessage(string message)
        {

        }

        private void broadcast(string message)
        {
            _someClients.Broadcast(msg);
            SetupNotifier();
        }
    }

}

The SetupNotifier() method should contain logic that catches the change you want to react upon. broadcast(string message) (can be renamed of course) contains the logic that "returns" data to the client(s) - this example sends the same message to all clients.

Make sure to test this with a proper websocket client (there are Chrome extenstions for this, if you want the ease of use) - you can't do ws:// requests in a browser as-is.

like image 89
The_Torst Avatar answered Jan 31 '23 09:01

The_Torst