GitXplorerGitXplorer
B

backbone.signalr

public
25 stars
4 forks
2 issues

Commits

List of commits on branch master.
Unverified
d9587aa3579b6f99fe2945010f66d99ad5038cbc

updating the documentation to use SignalR 1.0.0

BBrianGenisio committed 12 years ago
Unverified
5e09393b6d31c6a57cd46d41eed514fd9b6b01f4

moving out of pre-release and supporting the release version of SignalR

BBrianGenisio committed 12 years ago
Unverified
1fe16188a95557952f30a6cb766c0bd1fe0953be

update to the document that says we are using SignalR-pre2

BBrianGenisio committed 12 years ago
Unverified
9e15f4ebb1871538cc41734025619a6f14cb4227

upgrading to SignalR-pre2

BBrianGenisio committed 12 years ago
Unverified
7a5b355ec6a570ce63c5b07eab3da3d97271e976

Merge pull request #1 from brycekahle/patch-1

BBrianGenisio committed 12 years ago
Unverified
bb55cef3a3dfe4fef0324d4ee3c9690ba5fba866

Add support for different idAttribute

bbrycekahle committed 12 years ago

README

The README file for this repository.

backbone.signalr

Welcome to Backbone.SignalR, the sync layer for BackboneJS that lets you talk to a SignalR Server Hub.

Backbone.js has a powerful model abstraction that allows you to synchronize your data with any data source (via Backbone.sync). By default, Backbone models "sync" with REST services, but the Backbone.sync layer is replacable. Backbone.signalr allows your models to "sync" with a real-time SignalR hub very easily. In addition, all models on all clients will get updated in real-time!

Backbone.SignalR works with SignalR 1.0. Looking for SignalR 0.5 support? We've tagged it for you: (https://github.com/SrtSolutions/backbone.signalr/tags)

Getting Started

There are two simple ways to use Backbone.SignalR:

Installing the Nuget Package

You can search for it with the name Backbone.SignalR or you can install it directly via the Package Manager Console:

PM> Install-Package Backbone.SignalR

This will bring in the dependencies of SignalR and Backbone.js if you don't already have it. It will put backbone.signalr.js in your Scripts folder and it will put BackboneModelHub.cs into your Hubs folder

Include the files manually

If you don't want to use the Nuget package, you can simply include the client/backbone.signalr.js file in your project and then copy server/BackboneModelHub.cs somewhere in your project and that is all you need.

Using the Backbone Model Hub

You need to create a Model Hub in order to synchronize with the Backbone Frontend. The base class handles the communication and updates, but you have control over how the data is managed. Let's say, for instance, that you have a model called Person:

public class Person
{
    public int ID { get; set; }
    public string First { get; set; }
    public string Last { get; set; }
}

public class PersonDBContext : DbContext
{
    public DbSet<Person> Person { get; set; }
}

You can create a PersonHub which stores models in a collection for demonstration. Override the actions that you want to support:

public class PersonHub : BackboneModelHub<PersonHub, Person>
{
    private readonly PersonDBContext _db = new PersonDBContext();

    protected override Person CreateModel(Person model)
    {
        _db.Person.Add(model);
        _db.SaveChanges();

        return model;
    }

    protected override IEnumerable<Person> FindModels()
    {
        return _db.Person.AsEnumerable();
    }
}

Of course, the actual mechanism to store and retrieve your data is up to you. You might be talking to a service layer or annother ORM. This Entity Framework example is just to get you started.

Important: The PersonHub is responsible for creating a unique identifier of some sort. This might happen in your ORM, or you might add it here. It is all up to you.

More overrides on the BackboneModelHub include:

  • UpdateModel
  • FindModel
  • DeleteModel
    protected override Person FindModel(Person model)
    {
        return _db.Person.Find(model.ID);
    }

    protected override Person UpdateModel(Person model)
    {
        _db.Entry(model).State = EntityState.Modified;
        _db.SaveChanges();
        return model;
    }

    protected override Person DeleteModel(Person model)
    {
        Person person = _db.Person.Find(model.ID);
        if (person == null)
        {
            return null;
        }

        _db.Person.Remove(person);
        _db.SaveChanges();

        return person;
    }

SignalR requires you to register the hubs via inspection. In Global.asax.cs, add this line as the first inside of Application_Start().

RouteTable.Routes.MapHubs();

Using the Client-Side Sync Layer

You will need to include SignalR (version to change as it progresses), the Hubs, and Backbone.signalr.js

<script src="~/Scripts/jquery.signalR-1.0.0.js"></script>
<script src="signalr/hubs" type="text/javascript"></script>

<script src="~/Scripts/underscore.js"></script>
<script src="~/Scripts/backbone.js"></script>

<script src="~/Scripts/backbone.signalr.js"></script>

Then, you can tell your collection to synchronize with the backend:

var Person = Backbone.Model.extend({});
var People = Backbone.Collection.extend({
	model: Person,
	signalRHub: new Backbone.SignalR("personHub")
});

Now, after you start your SignalR connection, you can fetch, create, update and destroy data via SignalR:

var people = new People();

$.connection.hub.start().done(function() {
   people.fetch();
});

If you want it to listen to real-time changes that are pushed from the server, simply tell it to do so. All clients who are listening will get model updates automatically:

initialize: function() {
	this.signalRHub.syncUpdates(this);
}

Optional: Hybrid approach

If you already have existing controller that you want to use and you don't want to duplicate your efforts in the hub, it is pretty easy. This is a hybrid approach and allows you to maintain a standard REST api for traditional communication but allows your clients to synchronize changes when they happen.

In this case, you can create your hub without any persistence details:

public class PersonHub : BackboneModelHub<PersonHub, Person>
{
}

The hub exposes several static methods that can be called from anywhere:

  • BroadcastModelCreated
  • BroadcastModelUpdated
  • BroadcastModelDestroyed
  • BroadcastCollectionReset

The last one (BroadcastCollectionReset) is used when your entire back-end collection has changed enough so that you want to tell all of the clients that they need to reset. The synchronization on the client will call Collection.reset with the collection you send it.

So, imagine you have a WebAPI controller that manages people. You just need to call the Hub's static methods:

public class PersonController : ApiController
{
    private readonly PersonDBContext _db = new PersonDBContext();

    public IEnumerable<Person> GetPeople()
    {
        return _db.Person.AsEnumerable();
    }

    public Person GetPerson(int id)
    {
        return _db.Person.Find(id);
    }

    public Person PutPerson(int id, Person person)
    {
        _db.Entry(person).State = EntityState.Modified;
        _db.SaveChanges();
            
        PersonHub.BroadcastModelUpdated(person);
            
        return person;
    }

    public Person PostPerson(Person person)
    {
        _db.Person.Add(person);
        _db.SaveChanges();

        PersonHub.BroadcastModelCreated(person);

        return person;
    }

    public Person DeletePerson(int id)
    {
        Person person = _db.Person.Find(id);
        if (person == null)
        {
            return null;
        }

        _db.Person.Remove(person);
        _db.SaveChanges();
                
        PersonHub.BroadcastModelDestroyed(person);

        return person;
    }

    protected override void Dispose(bool disposing)
    {
        _db.Dispose();
        base.Dispose(disposing);
    }
}

The Client-side javascript collection would synchronize with the REST service like it normally would:

var Person = Backbone.Model.extend({});
var People = Backbone.Collection.extend({
	model: Person,
	url: "/api/person"
});

But when you create your collection, you sync updates that come from SignalR:

var people = new People();
new Backbone.SignalR("personHub").syncUpdates(people);
people.fetch();

$.connection.hub.start();

Contributions

If you can think of any way to make this integration better, please let me know. I will consider all pull requests as wel as recommendations.