Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to create multiple Kestrel instances inside 1 process?

We are building an orchestrator within a micro-service architecture. We chose websockets as the RPC protocol, to set up a streaming pipeline which can be scaled by a websocket capable server like Kestrel. This orchestrator will primarily be running on Linux servers (dockerized).

For admin and monitoring purposes, we plan to use http://dotnetify.net/ to build a reactive Web Admin portal (which could show the number of calculations and clients in semi-realtime, with push notify).

DotNetify uses SignalR, and we can't use the SignalR layer on top of Websockets. We require minimal overhead on top of the TCP protocol. Websocket in itself is a beautiful standard, and lightweight enough, but SignalR adds support for things we don't really need for this (LAN, microservices). We do consider WAMP, but in the proof of concept we will use a plain and simple custom handshake within the websocket bus. Another reason is: our main backend is IBM AIX, and the RDBMS process engine is a commercial prebuild binary, so it's very cumbersome (near impossible) to implement the SignalR protocol over there. But we don't have to, because we don't want to.

A possible solution to having [A] "pure" and [B] "signalR" websocket servers within 1 process, is starting multiple Kestrels. I tried this (on windows and ubuntu) and it seems to run without problems. I simply used a Task.Run() array, followed by Task.WaitAll(backgroundTasks). One Kestrel with SignalR, one without, running on separate ports. Note: I could not find a proper way to use multiple ports in one Kestrel, and exclude SignalR from one port

My question is: Although this seems to run just fine, can anybody confirm that this is safe? Especially with libuv and os signal handling?

like image 687
Tw Bert Avatar asked Sep 04 '17 17:09

Tw Bert


1 Answers

You can use SignalR as normal, and just listen for Websocket connections on a specific path for talking with your AIX (and other back end) boxes. Just do something like this (Taken from Microsoft Docs ):

app.Use(async (context, next) =>
{
    if (context.Request.Path == "/ws")
    {
        if (context.WebSockets.IsWebSocketRequest)
        {
            WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
            await Echo(context, webSocket);
        }
        else
        {
            context.Response.StatusCode = 400;
        }
    }
    else
    {
        await next();
    }

});

I don't see any reason why you would need to start two Kestrel instances. Obviously replace the /ws portion of the path above with whatever endpoint you want to use for hooking up your WebSockets for your backend service.

like image 159
wllmsaccnt Avatar answered Oct 15 '22 09:10

wllmsaccnt