Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polling request for updating Backbone Models/Views

I need to find a way to update a web App implemented with backbone.

The use case will be the following:
I have several Views, and each View, or maybe model/collection related to this view, needs to make different polling request to the server at different time for discovering some change.

I am wondering what is the most general way to:

1) implement the Traditional Polling Request
2) implement the Long Polling Request
3) implement the HTML5 web socket


P.S.:
1) The server is written in PHP.
2) For now I am looking for a solution without using HTML5 WebSockets because maybe with PHP is not so simple.


Here's my simple code (1) using Traditional Polling Request.

(1)

// MyModel
var MyModel = Backbone.View.extend({
    urlRoot: 'backendUrl'
});

// MyView
var MyView = Backbone.View.extend({

    initialize: function () {
        this.model = new MyModel();
        this.model.fetch();
        this.model.on('change', this.render);
        setTimeout(function () {
            this.model.fetch();
        }, 1000 * 60 * 2); // in order to update the view each two minutes
    }
});

like image 860
Lorraine Bernard Avatar asked Jul 12 '12 11:07

Lorraine Bernard


2 Answers

Implement it in your Model the polling handler, check this example:

// MyModel
var MyModel = Backbone.Model.extend({
  urlRoot: 'backendUrl',

  //Add this to your model:
  longPolling : false,
  intervalMinutes : 2,
  initialize : function(){
    _.bindAll(this);
  },
  startLongPolling : function(intervalMinutes){
    this.longPolling = true;
    if( intervalMinutes ){
      this.intervalMinutes = intervalMinutes;
    }
    this.executeLongPolling();
  },
  stopLongPolling : function(){
    this.longPolling = false;
  },
  executeLongPolling : function(){
    this.fetch({success : this.onFetch});
  },
  onFetch : function () {
    if( this.longPolling ){
      setTimeout(this.executeLongPolling, 1000 * 60 * this.intervalMinutes); // in order to update the view each N minutes
    }
  }
});

// MyView
var MyView = Backbone.View.extend({

    initialize: function () {
        this.model = new MyModel();
        this.model.startLongPolling();
        this.model.on('change', this.render);
    }
});
like image 189
Daniel Aranda Avatar answered Sep 21 '22 02:09

Daniel Aranda


I'm not sure what you are asking here, but here's some thoughts:

1) Your code seems to contradict what you've written in the title. Using setTimeout (or setInterval) for continuous polling is something different then long polling. Actually it is a (normal) polling. The difference is that with long polling client starts an AJAX request and he waits. The server decides when to respond. And it should respond only when new data is available. And immediatly after the respond client starts a new polling request.

Side note: creating (relatively) efficient long polling server is not an easy task, be aware of that.

2) How you handle client side (i.e. where you put long polling logic) doesn't really matter as long as you know what's going on inside your code. Of course keep in mind that maybe in a future you would like to make some changes to the code, so keeping it separate would probably be a best choice. Here's the architecture that I would choose:

  • Independent script which creates global EventManager object (this script should load as the first one). Such object will have the following methods: .bind and .trigger and it will, erm... manage events. :) Here's for example how the implementation may look like:

Implementing events in my own object

  • Independent script which handles long polling. Whenever the data is received from the server (i.e. the AJAX long polling request finally ends) it calls EventManager.trigger('long_polling_data', res);. Then you need to bind to this event inside your backbone view or wherever you like.

Side note: additional bonus with this architecture is that if you decide to switch to WebSockets or any other technique (for example: JSONP polling) then you will only have to implement the logic for the other technique. The main code will only use long_polling_data event, so no additional changes will be required (you may want to change the name of the event :] ).

3) Although you say that you don't want to use WebSockets I have to comment on this. :) You know that world is constantly evolving. You should forget about long polling techniquesl. Using WebSockets and XMLSocket (a.k.a. FlashSocket) as a fallback is much more efficient and it is a lot simplier to implement the server side.

I hope I helped a bit, sorry for any language mistakes and good luck with your project!

like image 41
freakish Avatar answered Sep 23 '22 02:09

freakish