Running SignalR on Mono
Posted by Filip Ekberg on December 10 2012 15 Comments
Posted by Filip Ekberg on December 10 2012 15 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:
- clone https://github.com/SignalR/SignalR.git
- cd SignalR
- git checkout dev
- git submodule init
- git submodule update
- 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 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.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:
<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:
with
Finally if you haven’t already, force long polling for the time being:
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?
?>
Filip Ekberg is a Senior Software Engineer working in the country with all the polar bears, author of a self-published C# programming book and overall in love with programming.





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…
I haven’t tried but I think it will. Let me know if it works!
Hi,
That is very interested post, but how do you deploy this application on Ubuntu ? Do you copy “bin” directory directly to Linux ?
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!
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.
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!
@Epstone Can you get the full exception (that’s the target invocation exception, we need the inner exception)?
@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 :/
Pingback: Dew Drop – December 11, 2012 (#1,460) | Alvin Ashcraft's Morning Dew
Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1252
Pingback: Distributed Weekly 185 — Scott Banwart's Blog
Pingback: Creating a Windows 8 Store Game with MonoGame (XAML) and SignalR
Pingback: 2012 was an amazing year, here's a summary!
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!
Zelma, Thank you for your kind words! The only place that I can think of is the very interesting discussions on JabbR.