.Net Core + other protocols in cross platform service

I realise this question only partially touches servicestack but I suspect its likely a common question in the future. I am looking to couple a servicestack http interface with UDP/TCP Services and possibly additional protocols. Need this to work on both windows and linux

ServiceStack provides the ASP.NET Core template, but I’m wondering if this combination of services should be combined using the HostBuilder in .Net Core ?

Can you suggest best approach when running ServiceStack along side other services such as this, given that the service can’t go to sleep etc as a standard asp.net service might under IIS as needs to continue to receive UDP etc connections.

ServiceStack is just a .NET Core module when run in .NET Core, the WebHosting is being done by Kestrel which is only listening to the HTTP endpoints your .NET Core App is configured to listen to.

I don’t see how this is related to .NET Core’s host builder which starts an always running HTTP Server. You could start listening to other protocols in a background thread yourself, but this would be independent and unrelated to the .NET Core Web App.

Note .NET Core Web Apps are self hosting Console Apps, they don’t go to sleep or get recycled like ASP.NET/IIS Web Apps.

Hi Mythz thanks for the response. I am basing my question on the differences between .Net Core 1.0 vs .Net Core 2.1 as per this article:

which quotes

A new option available to developers working with .NET Core 2.1 is the new “generic” Host which enables developers to easily set up cross-cutting concerns such as logging, configuration and dependency injection for non-web focused applications.

with consideration also to the HostedService example here:

They refer to the HostBuilder using IHostBuilder (as opposed to WebHostBuilder) as the Generic Host and imply that it can be used to host background services.

Given the above, I was just wondering if ServiceStack could be instantiated under this model in a way that doesn’t appear to use Kestrel, similar to how I am currently hosting servicestack within a windows service without using IIS.

I take on board you note about .net apps not going to sleep, that is good.

That’s a way to use the host builder to run something entirely different, but the .NET Core module pipeline that MVC, Web API and ServiceStack use to handle requests are only going to be available for HTTP Requests.

You can call ServiceStack Services without a HTTP Server using a BasicAppHost which is useful for executing Services in unit tests.

The way to handle to executing on different protocols would be similar to how MQ Servers work where the MQ broker is run on a background thread and uses the AppHost’s ExecuteMessage or its other ServiceController APIs to Execute Services.

Thanks, will look into this further

Hi,

I’m just looping back on this and I am finding it does not quite work as expected. My problems appear to be with aspnet core not with servicestack, but thought I would update here as seems quite an important issue for the community.

The program.cs main function doesn’t get hit until the first http request is received. This means that any background processes are not instantiating until that point.

I have tried to switch to inproc rather than out of proc, but does not appear to be working at present.

Once I hit the webpage, then the backend services fire up.

I have now configured the IIS apppool settings not to recycle on idle, but would like to know how i can publish without need to hit the page otherwise background socket services may not be running.

Configuration is as follows:

var host = new WebHostBuilder()
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.SetBasePath(Directory.GetCurrentDirectory());
                    config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
                })
                .UseKestrel(options =>
                {
                    options.Limits.MaxConcurrentConnections = 1000;
                    options.Limits.MaxConcurrentUpgradedConnections = 1000;
                    options.Limits.MaxRequestBodySize = 100 * 1024;
                    options.Limits.MinRequestBodyDataRate =
                        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
                    options.Limits.MinResponseDataRate =
                        new MinDataRate(bytesPerSecond: 100, gracePeriod: TimeSpan.FromSeconds(10));
                })
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .UseIISIntegration()
                .Build();

            host.Run();

This is the key problem I’m facing. I can’t see how to instantiate these background threads, if the service is not being initialized until its serving an http request.

This is only in IIS mode, with dotnet service.dll it works correctly i believe.

The background threads should be started and listening at Startup not created at runtime. If you want to run the Background Thread after the AppHost starts you can start the background thread in an AfterInitCallbacks.

Hi Mythz, unless I’m mistaken, the startup code is not hit until the iis website receives the first http request ?

All Startup code is run when the App is initialized, i.e. before it starts accepting any requests.

Could it be that the problem is that I’m running this in reverse proxy mode ? i.e. out of process instead of in process ?

I don’t know what the issues are, but Startup logic always executes in a single Thread on Startup before the Request worker threads are created which handles the HTTP requests at runtime.

Yeah just to be clear, I have log lines in startup, configuration and main methods, none are written to until the first http request.

So the program is not even reaching the main method at present until the first http request is hit.

Here is a note I found:

"The AspNetCoreModule’s job is to ensure that your application gets loaded when the first request comes in and that the process stays loaded if for some reason the application crashes. You essentially get the same behavior as classic ASP.NET applications that are managed by WAS (Windows Activation Service).

Once running, incoming Http requests are handled by this module and then routed to your ASP.NET Core application."

From this site:

Right the App Domain might be down, if it is IIS/ASP.NET starts the App before handling the requests. The point is the App is startup before requests are handled.

Yes I understand this works ok in ASP.NET, appears to be a problem with Core…

Here is another thread that talks about it in detail:

Still chasing a solution though…

Just to add another note to this Mythz, what you said:

“Right the App Domain might be down, if it is IIS/ASP.NET starts the App before handling the requests. The point is the App is startup before requests are handled.”

This may be well and good for http only services, but if the micro service contains a UDP message service for example, it won’t receive messages until an HTTP request comes in, so this is problematic. This is the scenario I raised right back at the beginning of the thread

This is if the App isn’t running, if you’re running the .NET Core as a Console App it’s always running.

I assume above you mean if you ran the console app external to IIS manually (or through some startup script) ?

Under IIS, the control of running the application is handled by the AspNetCoreModule (or whatever its called). and that is the root cause of the problem as it does not automatically start the app until the http request arrives.

.NET Core Apps are self-hosting Console Apps by default, if it’s running directly or accessed via a reverse proxy then it’s an always running Console App.

Personally I prefer to host all .NET Core Apps on Linux (IMO best feature of .NET Core) which are always run as Console Apps.