SignalR is a library for .NET to help build real time web applications, in a way it is quite similar to Socket.IO on Node.js. It consists of three main parts:
- SignalR.Server – .NET code running on IIS
- SignalR.Js – A SignalR client in javascript
- SignalR.Client – A SignalR client in .NET. Useful for communicating with a SignalR server from, for example, a Windows Phone application.
SignalR is using long polling as a method to keep its http connections open. In the future support for WebSockets is going to be added as well (a guess would be when .NET 4.5/IIS8 is released, it will have support for WebSockets).
Let me show you how simple it is to create a chat server. First start Visual Studio and create a ASP.NET MVC3 application. When you have created your project you want to add SignalR from NuGet, so open up the NuGet manager and search for SignalR. You need the SignalR.Server and SignalR.Js packages.
When SignalR has installed we need to create the actual server, so lets add a new class, MyConnection. This class will handle the asynchronous communication with the clients:
-
-
using System;
-
using System.Web.Script.Serialization;
-
using SignalR;
-
using System.Threading.Tasks;
-
-
namespace SignalRTest
-
{
-
public class MyConnection : PersistentConnection
-
{
-
protected override Task OnReceivedAsync(string clientId, string jsonData)
-
{
-
// Deserialize json string
-
var data = new JavaScriptSerializer()
-
.Deserialize(jsonData, typeof(EventData)) as EventData;
-
-
// Broadcast data to all clients
-
return Connection.Broadcast(string.Format("{0} {1}: {2}",
-
DateTime.Now.ToShortTimeString(), data.ClientName, data.Message));
-
}
-
}
-
-
public class EventData
-
{
-
public string ClientName { get; set; }
-
public string Message { get; set; }
-
}
-
}
-
To route the traffic to MyConnection we need to modify Global.asax slightly:
-
-
public static void RegisterRoutes(RouteCollection routes)
-
{
-
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
-
-
routes.MapConnection<MyConnection>("echo", "echo/{*operation}");
-
-
routes.MapRoute(
-
"Default", // Route name
-
"{controller}/{action}/{id}", // URL with parameters
-
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
-
);
-
}
-
And the last part, the UI. Put this into your Home/Index.cshtml view:
-
-
<h2 id="subtitle">Join the chat</h2>
-
<div>
-
<script type="text/javascript">
-
$(function () {
-
var connection = $.connection(‘echo’);
-
var clientName = ”;
-
-
var send = function () {
-
if ($(‘#msg’).val() !== ”) {
-
connection.send("{Message: ‘"
-
+ $(‘#msg’).val()
-
+ "’, ClientName: ‘"
-
+ clientName + "’}");
-
$("#msg").val(”);
-
}
-
};
-
-
var startChatting = function () {
-
if ($(‘#name’).val() !== ”) {
-
clientName = $(‘#name’).val();
-
$("#info").toggle();
-
$("#chat").toggle();
-
$(‘#msg’).focus();
-
$(‘#subtitle’).html("Now chatting");
-
}
-
};
-
-
$("#chat").toggle();
-
$(‘#name’).focus();
-
-
connection.received(function (data) {
-
$(‘#messages’).append(‘<li>’ + data + ‘</li>’);
-
});
-
-
$("#broadcast").click(function () {
-
send();
-
});
-
-
$("#start").click(function () {
-
startChatting();
-
});
-
-
$(‘#chatform’).submit(function () {
-
send();
-
return false;
-
});
-
-
$(‘#startform’).submit(function () {
-
startChatting();
-
return false;
-
});
-
-
connection.start();
-
});
-
</script>
-
-
<div id="info">
-
<form id="startform">
-
Enter your name:
-
<input type="text" id="name" />
-
<input type="button" id="start" value="Start chatting" />
-
</form>
-
</div>
-
-
-
<div id="chat">
-
<form id="chatform">
-
<ul id="messages"></ul>
-
<input type="text" id="msg" />
-
<input type="button" id="broadcast" value="Send" />
-
</form>
-
</div>
-
</div>
-
Alright, that should be all. Compile and run it! You can test out my chat live over at AppHarbor: