Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

2.0.0-rc1

@davidfowl davidfowl released this · 675 commits to master since this release

Overview

Renamed OWIN methods

To be more compatible with OWIN standards we've renamed MapHubs and MapConnection to MapSignalR. This gives you a single entry point for configuring SignalR into the OWIN pipeline. We've also introduced RunSignalR for more advanced scenarios (there's an example in the cross domain document).

Before

using Microsoft.Owin;
using Owin;

namespace MyWebApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Map all hubs to "/signalr"
            app.MapHubs();

            // Map the Echo PersistentConnection to "/echo"
            app.MapConnection<EchoConnection>("/echo");
        }
    }
}

After

using Microsoft.Owin;
using Owin;

namespace MyWebApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Map all hubs to "/signalr"
            app.MapSignalR();

            // Map the Echo PersistentConnection to "/echo"
            app.MapSignalR<EchoConnection>("/echo");
        }
    }
}

Cross domain support

In SignalR 1.x cross domain requests were controlled by a single EnableCrossDomain flag. This flag controlled both JSONP and CORS requests. For greater fleixibility, we've removed all CORS support from SignalR and have made new OWIN middleware available to support these scenarios. To add support for CORS requests, install Microsoft.Owin.Cors and call UseCors before your SignalR middleware:

Before

using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Owin;

namespace MyWebApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapHubs(new HubConfiguration { EnableCrossDomain = true });
        }
    }
}

After

using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Owin;

namespace MyWebApplication
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Branch the pipeline here for requests that start with "/signalr"
            app.Map("/signalr", map =>
            {
                // Setup the cors middleware to run before SignalR.
                // By default this will allow all origins. You can 
                // configure the set of origins and/or http verbs by
                // providing a cors options with a different policy.
                map.UseCors(CorsOptions.AllowAll);

                var hubConfiguration = new HubConfiguration 
                {
                    // You can enable JSONP by uncommenting line below.
                    // JSONP requests are insecure but some older browsers (and some
                    // versions of IE) require JSONP to work cross domain
                    // EnableJSONP = true
                };

                // Run the SignalR pipeline. We're not using MapSignalR
                // since this branch is already runs under the "/signalr"
                // path.
                map.RunSignalR(hubConfiguration);
            });
        }
    }
}

The new CORS middleware also allows you to specify a CorsPolicy which lets you lock down which origins you want to allow requests from.

JSONP is now a separate flag on ConnectionConfiguration and HubConfiguration and can be enabled if there is a need to support older browsers (and some versions of IE).

Sending a single message to multiple clients and groups

You can now send to multiple groups or multiple connections easily and efficiently.

Persistent Connection

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;

namespace MyApplication
{
    public class ChatConnection : PersistentConnection
    {
        protected override Task OnReceived(IRequest request, string connectionId, string data)
        {
            IList<string> connectionIds = DB.GetConnections(request.User.Identity.Name);

            return Connection.Send(connectionIds, data);
        }
    }
}

Hubs

using System;
using System.Collections.Generic;
using Microsoft.AspNet.SignalR;

namespace MyApplication
{
    public class Chat : Hub
    {
        public void Send(string message)
        {
            IList<string> connectionIds = DB.GetConnections(Context.User.Identity.Name);
            Clients.Clients(connectionIds).send(message);
        }
    }
}

Easier unit testing of Hubs

We've introduced an interface IHubCallerConnectionContext on Hubs that makes it easier to mock client side invocations. Here's an example using xunit and Moq.

[Fact]
public void HubsAreMockableViaDynamic()
{
    bool sendCalled = false;
    var hub = new MyHub();
    var mockClients = new Mock<IHubCallerConnectionContext>();

    hub.Clients = mockClients.Object;

    dynamic all = new ExpandoObject();
    all.send = new Action<string>(message =>
    {
        sendCalled = true;
    });

    mockClients.Setup(m => m.All).Returns((ExpandoObject)all);
    hub.Send("foo");

    Assert.True(sendCalled);
}

[Fact]
public void HubsAreMockableViaType()
{
    var hub = new MyHub();
    var mockClients = new Mock<IHubCallerConnectionContext>();
    var all = new Mock<IClientContract>();

    hub.Clients = mockClients.Object;
    all.Setup(m => m.send(It.IsAny<string>())).Verifiable();
    mockClients.Setup(m => m.All).Returns(all.Object);
    hub.Send("foo");

    all.VerifyAll();
}

public interface IClientContract
{
    void send(string message);
}

JavaScript error handling

All JavaScript error handling callbacks flow JavaScript error objects instead of raw strings. This allows us to flow richer information to your error handlers. You can get the inner exception from the source property of the error.

connection.start().fail(function(e) {
    console.log('The error is: ' + e.message);
});

Features

  • Add EnableJSONP flag to ConnectionConfiguration (#2328)
  • Using the host-provided "host.TraceOutput" writer on OWIN hosts (#2260)
  • Create advanced CORS middleware for specific CORS policy support (#2072)
  • Make it easier (or possible) to mock Clients.Group, Clients.OthersInGroup, etc (#1899)
  • Create method Client(string array) in IHubConnectionContext / HubContext (#1789)
  • Unable to send complex datatype from JS using PersistentConnection (#327)

Bugs Fixed

  • JS client fails in IE8 due to use of "undefined" keyword (#2377)
  • Improve logging on the JS client (#2366)
  • Have PingInterval stop the connection on 401's and 403's. (#2360)
  • Latest firefox not firing clean disconnect on browser refresh (#2357)
  • JS client longPolling not raise reconnected event for reconnect when server process stop and re-start (#2353)
  • JS client should pass an error object to connection.error handlers (#2345)
  • Aborting the connection while negotiating should reject the deferred (#2340)
  • Consider removing the parameter excludeConnectionIds for API that connection send to specified connecitonId (#2330)
  • Reconnect fires on .NET client after connection timeout (#2323)
  • JS Client OnError should be invoked with non-empty error messages (#2317)
  • SignalR intermittently stalls (MessageBroker workers all busy) (#2302)
  • Make our self host depend on owin self host package (#2291)
  • longPolling does not trigger start().fail when authorization fails (#2288)
  • Hub invocation callbacks are not cleaned up in C# client if no response is received causing a memory leak (#2273)
  • Hub invocation callbacks are not cleaned up in JS client if no response is received causing a memory leak (#2271)
  • JS client foreverFrame run into script error : Unable to get property 'contentWindow' of undefined or null reference (#2249)
  • WebSocket message limit should only apply to server logic (#2247)
  • Expose underlying owin headers, form and query string via new abstractions on IRequest (#2243)
  • JS Client - Window unload is deprecated as of jQuery 1.8 (#2240)
  • Have long and short running HttpClients use different connection groups (#2227)
  • Make HttpClientException.ToString more useful (#2224)
  • C# Client - WebSockets transport shifts into Connected state when exception thrown in hubs OnConnected (#2219)
  • When the app domain restarts, and the client reconnects with the previous group token in querystring, sometimes the group is not added on the server (#2207)
  • Use unique connection groups in .NET 4 client for long running and short running requests (#2204)
  • Relax conditions under which errors are thrown for invoking callback methods on the client (#2203)
  • In JS client when transport falls back, OnConnected can be called twice for same connection id (#2195)
  • .NET client Stop() takes 30 secs to complete (#2191)
  • JavaScript Client does not cause OnReconnected event to fire when using longPolling transport (#2188)
  • When scaleout backplane is not up, .Net client webSockets connection becomes connected after start (#2186)
  • Remove portable .NET http client and use in box version for .NET 4.5 (#2177)
  • Don't capture the execution context when registering cancellation token callbacks. (#2167)
  • Failing to connect when IIS enables both Anonymous and Basic (#2145)
  • Update Header in the .Net client even if connection is connected (#2142)
  • Performance problem using long polling with many clients (#2125)
  • Hub calls should fail if request's response is 3xx redirect (#2106)
  • The user identity cannot change during an active SignalR connection (#1998)
  • Reconnect does not work with Chrome/serverSentEvents transport when server disappears/reappears (#1946)
  • Possible confusion in SignalR.Client.Transports.AutoTransport when overriding the default transport order (#1884)
  • JS client with $.ajaxSetup can cause SignalR ajaxSend work unexpectedly (#1773)
  • Set the crossdomain flag for cors ajax request (#1735)
  • Reconnect can be raised after Disconnect for websocket connections (#1231)
  • Improve logging to show when no hub subscriptions are made. (#1151)
  • With several connections connected, after server restart and clients reconnected, sometimes the connections can't receive message however still can send message (#1124)

Downloads

Something went wrong with that request. Please try again.