Question

I'm building an app that uses ServiceStack for restful api. I'm attempting to integrate SignalR for real time features, as this app will run on the client desktop. Long polling or any such work around is not an option. The requirements are Console App, ServiceStack, SignalR. Is it possible to have SignalR and ServiceStack self hosted together?

Consider the following (all in one console app):

StartUp.cs >>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin;
using Microsoft.Owin.Cors;
using Owin;

namespace RazorRockstars.SelfHost
{
    public class StartUp
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(CorsOptions.AllowAll);
            app.MapSignalR();
        }
    }
}

AppHost.cs >>

namespace RazorRockstars.SelfHost
{
    public class AppHost : AppHostHttpListenerBase
    {
        public AppHost() : base("Test Razor", typeof(AppHost).Assembly) { }

        public override void Configure(Container container)
        {
            LogManager.LogFactory = new ConsoleLogFactory();

            Plugins.Add(new RazorFormat());

            container.Register<IDbConnectionFactory>(
                new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider));

            using (var db = container.Resolve<IDbConnectionFactory>().OpenDbConnection())
            {
                db.CreateTableIfNotExists<Rockstar>();
                db.InsertAll(RockstarsService.SeedData);
            }

            this.CustomErrorHttpHandlers[HttpStatusCode.NotFound] = new RazorHandler("/notfound");
            this.CustomErrorHttpHandlers[HttpStatusCode.Unauthorized] = new RazorHandler("/login");
        }
    }
}

Program.cs >>

    using System.Threading;
    using Microsoft.Owin.Hosting;
    using ServiceStack.Logging;
    using ServiceStack.Text;

    namespace RazorRockstars.SelfHost
    {
        class Program
        {
            static void Main(string[] args)
            {
                string listingUrl = "http://*:2001/";
                string listingUrl2 = "http://*:2002/";
                LogManager.LogFactory = new ConsoleLogFactory();

                var appHost = new AppHost();
                appHost.Init();

                appHost.Start(listingUrl);
// the next line will result in error: "The process cannot access the file because it is being used by another process"

                WebApp.Start<StartUp>(listingUrl2);

                "\n\nListening on http://*:2001/..".Print();
                "Type Ctrl+C to quit..".Print();
                Thread.Sleep(Timeout.Infinite);
            }
        }
    }

If you would like to try this challenge yourself, just grab a copy of https://github.com/ServiceStack/RazorRockstars/tree/master/src/RazorRockstars.SelfHost and try to get it to work.

Any assistance with this brain teaser would help greatly.

Most importantly, I'm looking to know if this is possible, or not.

Was it helpful?

Solution

Based on that Rock Star project. I installed the following NuGet package:

Install-Package Microsoft.AspNet.SignalR.SelfHost

Optional if you want CORS:

Install-Package Microsoft.Owin.Cors

Here is my Program.cs file:

class Program
{
    static void Main(string[] args)
    {
        LogManager.LogFactory = new ConsoleLogFactory();

        var appHost = new AppHost();
        appHost.Init();
        appHost.Start("http://*:2001/");

        using (WebApp.Start<Startup>("http://*:2002/"))
        {
            "\n\nListening on http://*:2001/..".Print();
            "SignalR listening on http://*:2002/".Print();
            "\n\nType Ctrl+C to quit..".Print();
            Thread.Sleep(Timeout.Infinite);
        }
    }
}

class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.Map("/signalr", map =>
        {
            map.UseCors(CorsOptions.AllowAll);

            var hubConfiguration = new HubConfiguration
            {
                EnableDetailedErrors = true,
                EnableJSONP = true
            };

            map.RunSignalR(hubConfiguration);
        });
    }
}

enter image description here

I enabled CORS and allowed JSONP, that's upto you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top