August 22nd, 2012

Announcing the Release of SignalR 0.5.3

Brady Gaster
Principal Program Manager

SignalR 0.5.3 Release Notes

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.

New Connection Syntax, Simpler Cross-Domain Connections

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.

Client Hubs

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>');
});

Parity with Windows 8 HTML/JavaScript

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.

Improved Logging

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 Exception Support

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);
        }
    }
}

Server Sent Events in All Clients

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.

Typed Representations of Client Subsets

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);
}

Self-hosting Authentication Improvements

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;
        }
    }
}

Summary

A comprehensive list of the release notes for the 0.5.3 is below (cloned from the GitHub.com repository page).

  • Improve logging for hubs in js client. (#505)
  • Can’t pass querystring when creating HubConnection. (#581)
  • Improve errors for .NET client. (#515)
  • Make http streaming work with Win8 client. (a61ee958ed)
  • Fix bugs related to forever loading indicators on various browsers (#215), (#383), (#491)
  • Force shut down a client, server execution flow didn’t go into IDisconnect.Disconnect () at all. (#511)
  • Transport fallback should fail if onFailed called and there’s no good fallback. (#485)
  • Turn ReadStreamBuffering off for WP7 and Silverlight to enable SSE support. (18cb087037)
  • Connect/Disconnect events not firing in IE (#501)
  • Make dictionaries in bus case in sensitive. (5916a588f9)
  • Groups.Add within persistent connection fails under high crank load. (#388)
  • Use the HttpClient stack in silverlight. (b51a4144db)
  • Made reconnect timeout configurable on SSE transport. (6b869a4cd9)
  • Fix race condition when client sends immediately after connecting (#552)
  • Make access to the state thread safe in the .NET client. (8464514a8d)
  • Abort the request before calling close on the request in the .NET client. (50ee2b9b6c)
  • Throw if CreateProxy called after the connection is started. (89eb8e492c)
  • Fix caching negotiate response in Silverlight client (#522)
  • Serve silverlight’s cross domain policy file for self hosted server. (eaec182fee)
  • Expose underlying AuthenticationSchemes property (52dbfbef12)
  • Made exception handling fixes to SSE stream reader (C# client) (7f0fd4ddc7)
  • Make event names and proxy names case insensitive. (#508)
  • Added hub events support to JavaScript client (using hubs without proxy) (97c984754f)
  • Made websocket implementation for self host on .NET 4.5. (e94d091100)
  • LongPolling broken on ASP.NET 4.5 (#496)
  • Prevented caching ajax requests on reconnect. (fbfc65371d)
  • Added consistent way to get a strongly typed representation of the connected clients (fa6d0b533e)
Category
ASP.NET
Topics
SignalR

Author

Brady Gaster
Principal Program Manager

Brady Gaster is a program manager in the ASP.NET team at Microsoft, where he works on SignalR, microservices and APIs, and integration with Azure service teams in hopes to make it exciting for developers who work on .NET apps to party in the cloud. You can find Brady on Twitter or Twitch at @bradygaster when he's not learning with (or from) his 2 sons, tinkering with code, or making music in his basement using various synthesizers and guitars.

0 comments

Discussion are closed.