【问题标题】:Polling request for updating Backbone Models/Views更新主干模型/视图的轮询请求
【发布时间】:2012-07-12 02:55:59
【问题描述】:

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

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

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

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


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

【问题讨论】:

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


【解决方案1】:

在你的模型中实现它的轮询处理程序,检查这个例子:

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

【讨论】:

  • 即使绑定 this.model.on('change', this.render); 范围也是模棱两可的。 //模棱两可的范围——我的例子是模型范围 this.model.on('change', this.render, this); //视野范围
  • @hharnisc 这并不模棱两可,因为我在初始化“_.bindAll(this);”时使用了它
  • 这实际上是长轮询,还是您只是使用这个词?我的理解是,在长轮询中,您打开到服务器的单个连接并等待响应。这看起来就像你在不断地轮询。
  • @Ziggy 你对技术的定义不好。 “打开单一连接”技术被称为“推送技术”。对于无法使用套接字连接(由推送使用)的情况,长轮询请求“模拟”了“推送技术”。长轮询请求模拟它在任何给定时间向服务器询问更新。
  • 对于客户端代码是一样的。正常轮询或长轮询之间的区别在于服务器代码。轮询和长轮询的区别在于,如果答案为空,正常轮询会尽快返回,但长轮询可能会等待一段时间。在示例中,仅使用轮询的聊天后端代码将在您发出请求后立即返回一个数组,长轮询可能会等待几秒钟以查看是否出现消息。 @Ziggy
【解决方案2】:

我知道你在你的问题中说你不希望将 websockets 与 php 一起使用(因为它不是那么简单),但是,我发现它相对简单。

  1. 我使用了http://pusher.com/,这是一个带有后备功能的网络套接字应用程序。 (顺便说一下,我与公司没有联系)。
  2. 在服务器/api上包含https://github.com/squeeks/Pusher-PHP
  3. 在客户端包含<script src="http://js.pusherapp.com/1.12/pusher.min.js"></script>

客户端和服务器通道可以设置为使用 Web 套接字相互通信。

【讨论】:

  • 感谢您的回复。 pusher-php 看起来很有趣。
  • pusher-php 看起来很有趣,但我必须付费!!
【解决方案3】:

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

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(又名 FlashSocket)作为后备方案效率更高,实现服务器端也更简单。

希望对我有所帮助,对于任何语言错误深表歉意,祝您的项目好运!

【讨论】:

  • 感谢您的回复。我确实将问题的标题从 Long Polling 更改为 Traditional Polling。
  • 我添加了有关我的问题的更多详细信息。也许它可以帮助你给我更多关于如何使用 webSocket 的信息。谢谢。
  • 抱歉,我不是 PHP 开发人员,对此我无能为力。除非你愿意学习 Python 或服务器端 JavaScript。 :] 现在想想,对于没有经验的开发人员来说,实现长轮询和/或 websocket 可能有点困难。如果您不会提出很多请求,那么正常的轮询也应该可以工作。而且这实现起来非常简单,只需使用setTimeout
猜你喜欢
  • 2023-03-13
  • 2014-09-18
  • 1970-01-01
  • 1970-01-01
  • 2013-09-11
  • 1970-01-01
  • 2012-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多