Your official information source from the .NET Web Development and Tools group at Microsoft.
The SignalR team has been working long hours in their team room in Building 18 for the past few months adding features, resolving issues, and cranking out code. Today the team has released the 0.5.3 release of SignalR. This post will cover some of the key items in the release and explain how you can make use of the great new features, like improved error handling, extended logging functionality, and client hubs.
The 0.5.3 release adds a new method of establishing a connection to a SignalR Hub on the server, the hubConnection object.
var connection = $.hubConnection(); connection.start(function () { $('#submitButton').removeAttr('disabled'); });
By default, hubConnection directs all traffic to the server from which the calling HTML originated. However, by providing the url parameter you can direct traffic to a secondary server if that's your preference.
var connection = $.hubConnection('http://mysite.azurewebsites.net');
The new, strongly-typed hubConnection object exposes methods recognized and supported by Visual Studio's JavaScript IntelliSense features. This feature alone makes it an attractive alternative to $.connection if you're new to SignalR coding, and eases development if you're already familiar with the original methodology.
One of the methods exposed by hubConnection, the createProxy method, will be examined in the next section. This feature brings syntax to JavaScript previously available to developers working with the native .NET SignalR clients.
Improvements have been made for JavaScript developers who plan on working with SignalR hubs. Via the hubConnection.createProxy method, an object is returned to the calling code that offers more syntactic sugar and IntelliSense support over previous releases.
Consider the ChatHub class, that provides basic chat functionality.
[HubName("chat")] public class ChatHub : Hub { public void SendMessage(dynamic message) { Clients.receiveMessage(message); } }
Connecting to this hub using the plugin is as simple as calling the hub's name. In this case, the hub has been explicitly named using the HubName attribute.
var chat = connection.createProxy('chat');
To use the chat variable in JavaScript code to call the SendMessage method on the hub, the invoke method can be executed. In the example code below, a JavaScript object is created to represent the form's current values, and the object is then transmitted to the ChatHub instance via the second parameter of the invoke method.
$(function () { var connection = $.hubConnection(), chat = connection.createProxy('chat'); connection.start(function () { $('#submitButton').removeAttr('disabled'); }); $('#submitButton').click(function () { var msg = { username: $('#username').val(), message: $('#message').val() }; chat.invoke('SendMessage', msg); }); });
The event-handling syntax available in Client Hubs has also been improved via addition of the on method. This method handles events that are fired from within the server-side hub class, and defines how those event's arguments will be used in the calling code.
chat.on('receiveMessage', function (m) { $('#messages').append('<li><b>' + m.username + '</b>:' + m.message + '</li>'); });
Windows 8 development provides HTML and JavaScript developers a familiar platform on which to develop, and all of these SignalR JavaScript features are available to Windows 8 developes who want to use HTML and JavaScript as their target development paradigm. The code for web pages is the same as it is for Windows 8 applications, and the new release of SignalR maintains this approach and makes real-time applications written in HTML and JavaScript available on both the desktop and in the browser.
The hubConnection object's logging property enables toggling the logging features on or off.
connection.logging = true;
When activated, SignalR outputs detailed logs, which make troubleshooting and debugging much easier. The screen shot below shows the nature of the output available when using the debugging tools in Internet Explorer.
Improved diagnostics was a fundamental component of the 0.5.3 release. Along with logging improvements, native exception-handling improvements in SignalR make it easier to determine the nature of errors when they arise. When code in the ChatHub is modified to support the business-logic of verifying that each message is associated with a specific username, the probability of exceptions ocurring up-stream in the communication process elevates. Using the console window available in Internet Explorer, you can observe as SignalR exceptions occur. As in this case, a username wasn't present, the application throws an exception to be handled by the client.
public void SendMessage(dynamic message) { var user = message.username; if (String.IsNullOrEmpty(message.username.ToString())) { throw new ApplicationException("No username provided!"); } Clients.receiveMessage(message); }
The console pane shows the exception handling in practice. As errors occur in the server functionality they are wrapped in SignalR exception details.
In the native .NET coding environment, the extended exceptions support will wrap exceptions that happen on a remote hub so that the nature of the exception will be made available during development. The call to Exception.GetError below shows how a SignalR call resulting with an unhandled exception can be evaluated to obtain information about the error that occurred on the remote client.
private static void Connect() { var connection = new HubConnection("http://localhost:58416/"); var chat = connection.CreateProxy("chat"); chat.On<string>("addMessage", Console.WriteLine); try { connection.Start().Wait(); string msg = null; while ((msg = Console.ReadLine()) != null) { chat.Invoke("send", msg).Wait(); } } catch (Exception ex) { using (var error = ex.GetError()) // NEW ERROR HANDLING FEATURES { Console.WriteLine(error.StatusCode); } } }
Previous verisons of the SignalR clients for Windows Phone and Silverlight only supported the Long Polling transport. 0.5.3 adds support for Server Sent Events to these clients meaning all clients are now able to receive messags over an open HTTP stream. This support is enabled by default so you don't have to change your application in any way to get the benefit.
New in 0.5.3 is the ability to reference a filtered list of the active clients as a single object instance. Referencing a group of clients using the familiar index-style nomenclature results in the return of an instance of the IClientProxy interface. Take the code below, which illustrates this new feature by segmenting a set of clients based on which group or room into which they're currently placed.
public void DynamicInvoke(string method) { IClientProxy callerProxy = Caller; IClientProxy allClientsProxy = Clients; IClientProxy groupProxy = Clients["foo"]; groupProxy.Invoke(method); }
If your architecture provides you the opportunity to host SignalR outside of ASP.NET in a self-hosting manner, new authentication functionality is provided in the 0.5.3 release. The code below demonstrates how the new AuthenticationSchemes property of the self-hosting server supports the System.Net.AuthenticationSchemes enum type.
static void Main(string[] args) { Debug.Listeners.Add(new ConsoleTraceListener()); Debug.AutoFlush = true; string url = "http://*:8081/"; var server = new Server(url); server.Configuration.DisconnectTimeout = TimeSpan.Zero; server.AuthenticationSchemes = AuthenticationSchemes.Ntlm; server.MapHubs(); server.Start(); Console.WriteLine("Server running on {0}", url); while (true) { ConsoleKeyInfo ki = Console.ReadKey(true); if (ki.Key == ConsoleKey.X) { break; } } }
A comprehensive list of the release notes for the 0.5.3 is below (cloned from the GitHub.com repository page).
Hi, This is all great stuff. I am a big fan of SignalR and use it in some serious web apps.
What is needed most now, is native web farm support like for Windows Azure.