更新Backbone模型/视图的轮询请求

时间:2012-07-12 11:04:20

标签: javascript backbone.js websocket long-polling polling

我需要找到一种方法来更新使用backbone实现的网络应用。

用例如下:
我有几个视图,每个视图,或者与此视图相关的模型/集合, 需要在不同的时间向服务器发出不同的轮询请求,以发现一些变化。

我想知道最通用的方法是什么:

1)实施Traditional Polling Request
2)实施Long Polling Request
3)实现HTML5 web socket


P.S .:
1)服务器用PHP编写 2)目前我正在寻找一种不使用HTML5 WebSockets的解决方案,因为使用PHP可能并不那么简单。


这是我使用Traditional Polling Request的简单代码(1)。

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

3 个答案:

答案 0 :(得分:18)

在您的模型中实现它的轮询处理程序,请检查以下示例:

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

答案 1 :(得分:11)

我不确定你在这里问什么,但这里有一些想法:

1)您的代码似乎与您在标题中所写的内容相矛盾。使用setTimeout(或setInterval)进行连续轮询与长轮询不同。实际上这是一个(正常的)民意调查。不同之处在于,使用长轮询客户端启动AJAX请求并等待。服务器决定何时响应。它应该只在新数据可用时才响应。在响应客户端启动新的轮询请求后立即进行。

旁注:创建(相对)高效的长轮询服务器并非易事,请注意这一点。

2)只要您知道代码内部发生了什么,您如何处理客户端(即放置长轮询逻辑的位置)并不重要。当然要记住,将来你可能希望对代码进行一些更改,因此将它保持分离可能是最佳选择。这是我要选择的架构:

  • 创建全局EventManager对象的独立脚本(此脚本应作为第一个加载)。这样的对象将具有以下方法:.bind.trigger并且它将管理事件。 :)这是例如实现的样子:

Implementing events in my own object

  • 处理长轮询的独立脚本。每当从服务器接收数据时(即AJAX长轮询请求最终结束),它就会调用EventManager.trigger('long_polling_data', res);。然后,您需要在骨干视图内或任何您喜欢的地方绑定此事件。

附注:此架构的另一个好处是,如果您决定切换到WebSockets或任何其他技术(例如:JSONP轮询),那么您只需要为其他技术实现逻辑技术。主代码仅使用long_polling_data事件,因此不需要进行其他更改(您可能需要更改事件的名称:]。)。

3)虽然您说您不想使用WebSockets,但我必须对此发表评论。 :)你知道世界在不断发展。你应该忘记长期的民意调查技巧。使用WebSockets和XMLSocket(a.k.a.FlashSocket)作为后备更有效,实现服务器端要简单得多。

我希望我能帮助一下,抱歉任何语言错误,祝你的项目好运!

答案 2 :(得分:2)

我知道你在你的问题中说你不打算使用带有php的websockets(因为它不是那么简单),但是,我发现它相对简单。

  1. 我使用http://pusher.com/这是一个带有后备的网络套接字应用。 (顺便说一下,我与公司没有联系)。
  2. 在服务器上包含https://github.com/squeeks/Pusher-PHP / api
  3. 在客户端包含<script src="http://js.pusherapp.com/1.12/pusher.min.js"></script>
  4. 可以将客户端和服务器通道设置为使用Web套接字相互通信。