118

I have a single page web app developed using ASP.NET. I recently converted many of the web methods to be push based, using the SignalR library. This really sped up the page considerably and reduced a lot of the server calls from the page.

At the same time, I've also been looking at the RESTful ASP.NET WebAPI for some of the server-side methods, with the real beauty being that it allows to create an API for external applications at the same time that I develop the core application (which will be important for what I'm doing).

It seems however, after looking at several articles and these two questions, that push and WebAPI methods seem like two entirely different paradigms for client-server communication. I'm sure that I can create various methods that can be accessed via either protocol, but I'm uncertain if there are pitfalls to this or if this is considered sloppy -- maybe there's a more elegant way to achieve what I'm aiming for.

There are certainly situations in which I want the RESTful WebAPI to broadcast events via a SignalR hub... The opposite (SignalR ever needing to access the WebAPI) seems less likely, but I suppose still possible.

Has anyone done this? Does anyone have any advice or tips on how to proceed? What would be the most elegant way forward here?

Community
  • 1
  • 1
mbeasley
  • 4,584
  • 4
  • 24
  • 38
  • 4
    Take a look at the video from this [blog post](http://bradwilson.typepad.com/blog/2012/07/webstack-of-love.html). It explains exactly how you can use WebAPI with SignalR. – david.s Sep 11 '12 at 11:42
  • @david.s Skimming through that vid, it looks perfect. Post it as the answer and I'll mark it. – mbeasley Sep 11 '12 at 12:04

3 Answers3

86

Take a look at the video from this blog post. It explains exactly how you can use WebAPI with SignalR.

Essentially, Web API + SignalR integration consists in this class:

public abstract class ApiControllerWithHub<THub> : ApiController
    where THub : IHub
{
    Lazy<IHubContext> hub = new Lazy<IHubContext>(
        () => GlobalHost.ConnectionManager.GetHubContext<THub>()
    );

    protected IHubContext Hub
    {
        get { return hub.Value; }
    }
}

That's all. :)

Dennis
  • 34,925
  • 9
  • 72
  • 134
david.s
  • 10,853
  • 5
  • 48
  • 80
18

SignalR is actually already incorporated into WebAPI source vNext (4.1).

If you use not the RTM build, but instead grab a build off Codeplex, you'd see there is a new project there called System.Web.Http.SignalR which you can utilize. It was added a couple of days ago with this commit - http://aspnetwebstack.codeplex.com/SourceControl/changeset/7605afebb159

Sample usage (as mentioned in the commit):

public class ToDoListController : HubController<ToDoListHub>
{
    private static List<string> _items = new List<string>();

    public IEnumerable<string> Get()
    {
        return _items;
    }

    public void Post([FromBody]string item)
    {
        _items.Add(item);
        // Call add on SignalR clients listening to the ToDoListHub
        Clients.add(item);
    }
}

If you do not want to switch to vNext for now, you could always just use that code for reference.

This implementation is very similar (a bit more polished, includes tests etc.) to what Brad Wilson showed at NDC Oslo - http://vimeo.com/43603472

Arjan Einbu
  • 12,960
  • 1
  • 53
  • 58
Filip W
  • 26,577
  • 6
  • 89
  • 80
  • 4
    I've done that on server. But can't connect client. Do you know how to connect a .NET client with the above mentioned server? – bytefire Aug 29 '13 at 16:22
  • 3
    I'm using Web API 5.2.3 and SignalR 2.2.1 and this class is nowhere to be found. Does anyone know the history? Was it yanked before RTM? Ultimately, I just copied the david.s' class definition, but I'm curious what's going on. – Colin Feb 21 '17 at 23:07
  • 1
    @40Alpha - I think we ended up just having static methods in the Hub that used GlobalHost.ConnectionManager.GetHubContext() (or the ASP.NET Core equivalent), and calling those static methods from the API Controller. – Colin Mar 06 '18 at 20:35
3

Here is a video showing an integration of the two technologies http://channel9.msdn.com/Events/TechDays/Belgium-2013/25 and here there is a NuGet package for the integration https://www.nuget.org/packages/Microsoft.AspNet.WebApi.SignalR/

NinjaCross
  • 649
  • 2
  • 8
  • 20
  • 2
    This package is broken now, when using Code Contracts with Web API application, because it requires non-generic `IHubConnectionContext`, which was replaced by `IHubConnectionContext`. Accepted answer is a way to go. – Dennis Aug 21 '15 at 07:23
  • Whilst this may theoretically answer the question, [it would be preferable](//meta.stackoverflow.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. Please edit your answer to correct this, then flag your post to request un-deletion – Matt Jun 24 '16 at 12:27