Polling request for updating Backbone Models/Views
Asked Answered
D

3

15

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

Dalston answered 12/7, 2012 at 11:4 Comment(3)
if you know asp.net you can look into SignalR, it makes client-server interaction very easy and it chooses appropriate connection model automatically depending on browser capabilitesDowling
websocket in php. old code and called a quick hack by the author... still may be worth a look. code.google.com/p/phpwebsocket/source/browse/…Postbellum
websocket in php much more promising: code.google.com/p/phpws/source/browse/#git%2FphpwsPostbellum
O
18

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);
    }
});
Osteoarthritis answered 16/7, 2012 at 15:24 Comment(7)
Scope is ambiguous on even bind this.model.on('change', this.render); //Ambiguous scope -- my case was the models scope this.model.on('change', this.render, this); //Scope of viewEchevarria
@Echevarria it is not ambiguous because I used this on initialize "_.bindAll(this);"Osteoarthritis
Is this actually long-polling, or are you just using that word? My understanding is that, in long-polling you open a single connection to the server and await a response. This just looks like you are polling continuously.Radiculitis
@Radiculitis you have a bad definition of the technologies. "Open a single connection" technology is known as "push technology". Long polling request "emulates" the "push technology" for those case where you can't use socket connection(used by push). Long polling request emulates it asking to the server any given time about updates.Osteoarthritis
@DanielAranda Thanks! So, how would you implement "polling" differently from "long-polling" in this case?Radiculitis
For the client code is the same. What make a difference between normal polling or long polling is the server code. The difference between polling and long polling is that if the answer is null, normal polling will return it asap but long polling could wait some time. In example a backend code for a chat using just polling will return an array as soon as you make the request, long polling could wait some seconds to see if a message appears. @RadiculitisOsteoarthritis
How will one stop this polling ?Knish
F
11

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!

Fruitarian answered 12/7, 2012 at 14:11 Comment(3)
thanks for your response. I did change the title of my question from Long Polling to Traditional Polling.Dalston
I added more details about my question. maybe it can help you to give me more info also about how can I use webSocket. Thanks.Dalston
Sorry, I'm not a PHP developer and I can't help you with that. Unless you are willing to learn Python or Server Side JavaScript. :] When I think about it now, it may be a bit difficult for an inexperienced developer to implement long polling and/or websockets. If you won't make a lot of requests, then normal polling should work as well. And this is really simple to implement, you just use setTimeout.Fruitarian
S
2

I know you state in your question that you are not looking to use websockets with php (due to it being not so simple), however, I have found it to be relatively straightforward.

  1. I used http://pusher.com/ which is a web sockets app with fallbacks. (I am not connected with the company by the way).
  2. include https://github.com/squeeks/Pusher-PHP on the server/api
  3. include <script src="http://js.pusherapp.com/1.12/pusher.min.js"></script> on the client side.

The client and server channel can be set up to speak with each other using web sockets.

Schematic answered 17/7, 2012 at 9:23 Comment(2)
Thanks for your response. the pusher-php seems very interesting.Dalston
the pusher-php seems very interesting but I have to pay for it!!Dalston

© 2022 - 2024 — McMap. All rights reserved.