PersistentConnection

davidfowl edited this page Feb 21, 2013 · 49 revisions

Persistent Connections (Server)

A PersistentConnection is the base class that has an api for exposing a SignalR service over http.

To create a new endpoint. Create a new class that derives from PersistentConnection.

public class MyEndPoint : PersistentConnection 
{
}

To make this endpoint accessible, add a route to Application_Start (or something similar):

using System;
using System.Web.Routing;

namespace WebApplication1
{
    public class Global : System.Web.HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            RouteTable.Routes.MapConnection<MyEndPoint>("echo", "/echo");
        }
    }
}

This will expose /echo as a SignalR endpoint.

PersistentConnection API

Task OnConnected(IRequest request, string connectionId)

Called when a new connection is made.

  • request - The request associated with this connection.
  • connectionId - The id of the new connection.

Example

public class MyEndPoint : PersistentConnection 
{
    protected override Task OnConnected(IRequest request, string connectionId)
    {
        return Connection.Broadcast("Connection " + connectionId + " connected");
    }
}

Task OnReconnected(IRequest request, IEnumerable groups, string connectionId)

Called when a connection is restored.

  • request - The request associated with this connection.
  • connectionId - The id of the new connection.

Example

public class MyEndPoint : PersistentConnection 
{
    protected override Task OnReconnected(IRequest request, string connectionId)
    {
        return Connection.Broadcast("Client " + connectionId + " re-connected");
    }
}

IList OnRejoiningGroups(IRequest request, IList groups, string connectionId)

Called when a connection is restored.

  • request - The request associated with this connection.
  • groups - The groups the connection are a part of.
  • connectionId - The id of the new connection.

Example

public class MyEndPoint : PersistentConnection 
{
    protected override IList<string> OnRejoiningGroups(IRequest request, IList<string> groups, string connectionId)
    {
        return groups;
    }
}

Task OnReceived(IRequest request, string connectionId, string data)

Called when data is received on the connection.

  • request - The request associated with the connection that sent the data.
  • connectionId - The id of the connection that sent the data.
  • data - The payload received from the client.

Example

public class MyEndPoint : PersistentConnection 
{
    protected override Task OnReceived(IRequest request, string connectionId, string data) 
    {
        return Connection.Broadcast("Connection " + connectionId+ " sent " + data);   
    }
}

Task OnDisconnected(IRequest request, string connectionId)

Called when a connection goes away (client is no longer connected, e.g. browser close).

  • connectionId - The id of the client that disconnected

Example

public class MyEndPoint : PersistentConnection 
{
    protected override Task OnDisconnected(IRequest request, string connectionId) 
    {
        return Connection.Broadcast("Connection " + connectionId + " disconncted");   
    }
}

IConnection Connection

  • Gets the IConnection for this PersistentConnection.

IConnection API

Task Broadcast(object value)

Broadcasts a message to all on this connection.

Task Send(string signal, object value)

Sends a value to the specified signal (e.g. the connection Id).

  • NOTE: the value is JSON serialized

Sending to a specific connection

public class MyEndPoint : PersistentConnection 
{
    protected override Task OnReceived(IRequest request, string connectionId, string data) 
    {
        return Connection.Send(connectionId, "Connection " + connectionId+ " sent " + data);   
    }
}

Managing Groups

You can add connections to groups and send messages to particular groups. Groups are not persisted on the server so applications are responsible for keeping track of what connections are in what groups so things like group count can be achieved.

public class MyConnection : PersistentConnection
{
    protected override Task OnConnected(IRequest request, string connectionId)
    {
        return Groups.Add(connectionId, "foo");
    }

    protected override Task OnReceived(IRequest request, string connectionId, string data)
    {
        // Messages are sent with the following format
        // group:message
        string[] decoded = data.Split(':');
        string groupName = decoded[0];
        string message = decoded[1];

        // Send a message to the specified
        return Groups.Send(groupName, message);
    }

    protected override Task OnDisconnect(string connectionId)
    {
        return Groups.Remove(connectionId, "foo");
    }

    protected override IList<string> OnRejoiningGroups(IRequest request, IList<string> groups, string connectionId)
    {
        return groups;
    }
}

Broadcasting over a connection from outside of a PersistentConnection

Sometimes you have some arbitrary code in an application that you want to be able to notify all clients connected when some event occurs. An example of this might be a background task that sends data at a certain interval.

You can use the dependency resolver for the current host to resolve the IConnectionManager interface which allows you to get ahold of the connection object.

In these scenarios, you can get an IConnection for a specific persistent connection by calling connectionManager.GetConnectionContext<T>:

using System;
using System.Web.Routing;
using Microsoft.AspNet.SignalR;

namespace WebApplication1
{
    public class Notifier
    {
        public void Notify(string message)
        {
            var context = GlobalHost.ConnectionManager.GetConnectionContext<MyEndPoint>();
            context.Connection.Broadcast(message);
        }
    }
}

Once you have the context, you can call Broadcast to send a message to all connections, or groups of connections:

using System;
using System.Web.Routing;
using Microsoft.AspNet.SignalR;

namespace WebApplication1
{
    public class Notifier
    {
        public static void GroupNotify(string group, string message)
        {
            var context = GlobalHost.ConnectionManager.GetConnectionContext<MyEndPoint>();
            context.Groups.Send(group, message);
        }
    }
}