Running SignalR on Mono

Posted by Filip Ekberg on December 10 2012 23 Comments

If you are one of those people, just like I am, that still use Linux for hosting despite that you love and only do .NET development; this is something extremely awesome. Ever since I started using SignalR I’ve wanted to host it on my own servers but all of them run on Linux with Mono and Apache. When David Fowler tweeted a couple of days ago that he was working on getting SignalR working on Mono; I had fireworks in my belly!

When I later told him that I actually run “real” web stuff on Linux with Mono and Apache, I was asked if I wanted to try get SignalR working on Mono! I love working on Windows so ideally I want to build and test stuff on my Windows development machine and then deploy to one of the Linux servers that uses Mono and Apache. The server that I got this running on is running Apache 2.2.14 and Mono 2.11.

tl;dr: You just need to compile the SignalR dev branch and use those libraries. Upload to a host that already runs Mono and Apache!

Preparing SignalR

The first thing that David instructed me to do was to clone the git repository and grab the latest dev-branch. In the future I expect that this work flow will change a bit, but for now this is how you do it.

Fire up you Git Bash and write the following in order:

  1. clone https://github.com/SignalR/SignalR.git
  2. cd SignalR
  3. git checkout dev
  4. git submodule init
  5. git submodule update
  6. build.cmd

After a while when the project has finished building, you should see something like this:

Since this is the dev branch some things have changed from what you might have seen before. For instance Microsoft.AspNet.SignalR.Hosting.Common.dll isn’t there anymore check inside src\Microsoft.AspNet.SignalR.SystemWeb\bin\Debug for the libraries that you will need to use. The Hosting library gave you the RoutingExtensions which is now moved to SystemWeb

Getting Persistent Connection to work

Now that SignalR is compiled and ready to be tested, we can create a new empty web project for .NET 4.0. Since I tried this on Mono 2.11 I am using .NET 4.0!

Let’s get the most basic thing working; the persistent connection. The idea here is that we want to get the broadcast demo that is available on the SignalR Wiki page working. I also showed this in my latest screencast about SignalR.

First we need to add the references to the SignalR libraries that we just compiled and set them to be copied locally.

As you can see the references are from src\Microsoft.AspNet.SignalR.SystemWeb\bin\Debug.

Before we start coding, we can add the JavaScript which you can find in src\Microsoft.AspNet.SignalR.Client.JS\bin. Now we can do just as the Wiki page instructs us to do.

Add a class called MyConnection with the following content:

using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
 
public class MyConnection : PersistentConnection
{
    protected override Task OnReceivedAsync(IRequest request, string connectionId, string data)
    {
        // Broadcast data to all clients
        return Connection.Broadcast(data);
    }
}

You will also need to add a Global.asax file with a route added:

using System;
using System.Web.Routing;
using Microsoft.AspNet.SignalR;

namespace MonoTesting
{
    public class Global : System.Web.HttpApplication
    {
        protected void Application_Start(object sender, EventArgs e)
        {
            RouteTable.Routes.MapConnection<MyConnection>("echo", "echo/{*operation}");
        }
    }
}

Finally we can add a HTML file with the following content:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body>
    <script src="http://code.jquery.com/jquery-1.7.min.js" type="text/javascript"></script>
    <script src="jquery.signalR.js"></script>
    <script type="text/javascript">
        $(function () {
            var connection = $.connection('/echo');

            connection.received(function (data) {
                $('#messages').append('<li>' + data + '</li>');
            });

            connection.start().done(function () {
                $("#broadcast").click(function () {
                    connection.send($('#msg').val());
                });
            });

        });
    </script>

    <input type="text" id="msg" />
    <input type="button" id="broadcast" value="broadcast" />

    <ul id="messages">
    </ul>
</body>
</html>

Now we’re ready to compile and run it!

Running it on Apache with Mono

I’m not going to cover how to set up Apache with Mono, there are plenty of tutorials for that out there already. However, all I did was create a new virtual host that is Mono enabled and I copied the content over to that folder and it just works!

Converting a SignalR application to run on Mono and Apache

As you might have seen in my screencast on SignalR I’ve created a Tic-Tac-Toe game, which is also available on github. I downloaded the master and opened up the solution to make the changes needed to get it running on Mono and Apache.

First thing that needs to be done here is to change the Target framework to .NET Framework 4 instead of 4.5. This will cause some issues with the SignalR version that was grabbed from NuGet. So you will also need to remove those before proceeding.

Just as we did with the persistent connection, we need to add the libraries that we compiled and also add the new javascript:

Now we need to replace the SignalR script that we are using in the client HTML to the new script file that we just added to the solution. In the case of Tic-Tac-Toe we replace:

<script src="/Scripts/jquery.signalR-1.0.0-alpha2.min.js" type="text/javascript"></script>

with

<script src="Scripts/jquery.signalR.js"></script>

Finally if you haven’t already, force long polling for the time being:

$.connection.hub.start({ transport: 'longPolling' });

Compile and run it locally to test that it still works then upload to your favorite Mono hosting! There’s a live demo available at signal.fekberg.com that looks like this (and as you can see it runs on Mono + Apache!):

Need an introduction to SignalR?

Vote on HN

23 Responses to Running SignalR on Mono

  1. EpstoneNo Gravatar says:

    Thanks a lot, that is exactly what I’m going to test tomorow. Any idea if it will run on mono 2.10.2? If not I’ll try without updating…

  2. Filip EkbergNo Gravatar says:

    I haven’t tried but I think it will. Let me know if it works!

  3. MappiNo Gravatar says:

    Hi,
    That is very interested post, but how do you deploy this application on Ubuntu ? Do you copy “bin” directory directly to Linux ?

  4. Filip EkbergNo Gravatar says:

    Hi Mappi,

    I just copied all the files from the project folder:

    I use WinSCP to copy the files over to the server and then I move them to the web folder and change the permissions to correspond with what Apache wants (www-data:www-data)

    You could of course do a normal “Publish” as well.

    Hope this helps!

  5. MappiNo Gravatar says:

    Hi Filip,
    Thank you for response. So, I thougth that maybe you use other tool. I use to build and deploy Mono application from Windows . There I have configured Build System to Mono and to deploy I use . I love ST2 editor, it;s simple and has more helpful plugins.

  6. EpstoneNo Gravatar says:

    Ok good and bad news :) I’ve tried the persistent connection example only.
    It is not working on 2.10.2 where I get the following exception from the /echo/negoiate call:

     <!--
    [System.Reflection.TargetInvocationException]: Exception has been thrown by the target of an invocation.
      at Microsoft.Owin.Host.SystemWeb.CallContextAsyncResult.End (IAsyncResult result) [0x00000] in <filename unknown>:0
      at Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.EndProcessRequest (IAsyncResult result) [0x00000] in <filename unknown>:0
      at System.Web.HttpApplication.async_handler_complete_cb (IAsyncResult ar) [0x00020] in /usr/src/packages/BUILD/mono-2.10.2/mcs/class/System.Web/System.Web/HttpApplication.cs:1008
    [System.NullReferenceException]: Object reference not set to an instance of an object
      at System.Threading.Tasks.TaskHelpersExtensions.ThenImpl[Task,AsyncVoid] (System.Threading.Tasks.Task task, System.Func`2 continuation, CancellationToken cancellationToken, Boolean runSynchronously) [0x00000] in <filename unknown>:0
      at System.Threading.Tasks.TaskHelpersExtensions.Then (System.Threading.Tasks.Task task, System.Action continuation, CancellationToken cancellationToken, Boolean runSynchronously) [0x00000] in <filename unknown>:0
      at Microsoft.Owin.Host.SystemWeb.OwinCallContext.Execute () [0x00000] in <filename unknown>:0
      at Microsoft.Owin.Host.SystemWeb.OwinHttpHandler.BeginProcessRequest (System.Web.HttpContextBase httpContext, System.AsyncCallback callback, System.Object extraData) [0x00000] in <filename unknown>:0
    -->

    But on the other opensuse machine (mono 2.10.6) it runs fine. So it’s just time for a mono update I think.

    By the way please give this textarea more width and thanks again for the walkthrough!

  7. David FowlerNo Gravatar says:

    @Epstone Can you get the full exception (that’s the target invocation exception, we need the inner exception)?

  8. EpstoneNo Gravatar says:

    @David
    Sorry, I allready updated to 2.10.9 and it’s running there now. I don’t want to mess around with that system again :/

  9. Pingback: Dew Drop – December 11, 2012 (#1,460) | Alvin Ashcraft's Morning Dew

  10. Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1252

  11. Pingback: Distributed Weekly 185 — Scott Banwart's Blog

  12. Pingback: Creating a Windows 8 Store Game with MonoGame (XAML) and SignalR

  13. Pingback: 2012 was an amazing year, here's a summary!

  14. ZelmaNo Gravatar says:

    Greetings! This is my 1st comment here so I just wanted to give a quick shout out and say I truly enjoy reading your blog posts. Can you recommend any other blogs/websites/forums that cover the same topics? Many thanks!

  15. Filip EkbergNo Gravatar says:

    Zelma, Thank you for your kind words! The only place that I can think of is the very interesting discussions on JabbR.

  16. AlessandroNo Gravatar says:

    hi… i have to show a simple work about realtime with signalr and mono… but i can’t do it.

    I’ve tryed with mono 3.0:

    1 start with mvc project (I’ve got package from nuget)…(connection starts and hub or persistent cn start) but javascript always receives “internal error 500″ during polling

    2 compile dev branch on mono, (but I’cant find rigth and all dlls)… and if I catch only two mutually result: proxy hub returns error, or javascript internal error.

  17. Filip EkbergNo Gravatar says:

    That does sound odd, I’d advice you to check on JabbR (the chat) in the SignalR room: https://jabbr.net/#/rooms/signalr

    As far as I know, SignalR 2.0 has support for mono, so maybe you could try that?

  18. BradNo Gravatar says:

    I’m trying to follow this tutorial but having trouble.

    Whenever I compile SignalR on my Ubuntu box, there are two DLL’s missing that are in your Tic-Tac-Toe project. Both are the *.SystemWeb ones.

    I tried compiling SignalR dev branch as well as release1.1 and a few others, but none ever gave me those DLLs…

    Thanks for any assistance or advice.

  19. Filip EkbergNo Gravatar says:

    Hi Brad,

    There’s suppose to be support out of the box for mono in the upcoming version of SignalR. Did you try the latest release or the 2.0 RC?

  20. BradNo Gravatar says:

    I was using the 2.2Beta branch to build.

    I found this link: http://forums.asp.net/t/1924358.aspx/1?Signalr+on+mono which says SignalR doesn’t work on ASP.NET, only via self-hosting using nowin.

  21. Filip EkbergNo Gravatar says:

    I see, there might be some changes since I wrote this article. If you get it working, let me know!

  22. Guilherme CardosoNo Gravatar says:

    Brad, in that post David is saying that you need to build the last brunch from source to use signalr on mono..

  23. robNo Gravatar says:

    what we can do about web sockets support on mono?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>