【问题标题】:How to optimize $interval for real time notifications in Angularjs?如何在 Angularjs 中为实时通知优化 $interval?
【发布时间】:2016-01-29 18:53:32
【问题描述】:

我正在开发一个社交网站。我使用以下代码实时显示用户的通知总数。

代码:

    function load_notifications(){
        $http.get('http://localhost:3000/load').success(function(data){
            $scope.totalNotify = data.total;
        });
    };
load_pictures();
$interval(function(){
        load_notifications();
    },300);

基本上,这段代码以给定的时间间隔连续检查数据库,如果有一些变化,它会更新 $scope 值。但是当我尝试在不同的浏览器中使用两个不同的用户检查它时,它会因为轮询请求而阻塞浏览器。

有什么方法可以改进这种方法或有其他更好的选择吗? 我正在使用 PHP 和 AngularJS 构建我的应用程序。但我也对这个模块的其他选项持开放态度。

【问题讨论】:

  • 频繁轮询会导致服务器负载。可能的解决方案:减少轮询频率,改用 web-sockets,租用更好的服务器
  • 虽然 2 个用户不应该使服务器超载 - 你使用的是什么网络服务器?阿帕奇?
  • 您可以在缓存数据的同时...
  • @Steve 是的,我正在 Apache 上进行测试。如果我想使用 web sockets,我需要使用 Node.js 吗?
  • @NuttyProgrammer 不需要 Node.js,在我的回答中添加了基于 PHP 的 Web 套接字引用。

标签: javascript php angularjs node.js


【解决方案1】:

这应该使用 web sockets 来完成,而不是轮询 ajax 请求。

JS:AngularJS and WebSockets beyond

PHP:How to create websockets server in PHP

具体来说,对于使用 PHP 的 Web 套接字,我会使用 Rachet

PHP 的起点是:http://socketo.me/docs/hello-world

这个 hello world 教程向您展示了通过 Rachet 进行交互的基本 javascript 和 PHP。

【讨论】:

  • 我正在尝试 hello world 代码。但我没有得到 telnet 部分。打开三个终端并运行: 1) $ php bin/chat-server.php 2) $ telnet localhost 8080 3) $ telnet localhost 8080
  • telnet 部分仅用于测试。你不会需要它。只需运行第一个命令(类似于 php bin/chat-server.php),Web 套接字服务器就会启动并运行!该指南向您展示了如何远程登录到 8080,因为这是他们在指南中设置服务器的地方,因此您可以通过远程登录来监控端口 8080 上的 Web 套接字。您希望在端口 80 上设置服务器以进行 Web 通信,就像典型的网站一样。我建议设置一个 angularjs 页面并在运行该 php 命令后尝试连接到服务器,然后使用 $client->send($msg); 推送一些东西
【解决方案2】:
awaitingResponse = false;

function load_notifications() {
    if(!awaitingResponse) {
        awaitingResponse = true;

        $http.get('http://localhost:3000/load').then(function(response) {
            $scope.totalNotify = response.data.total;
            awaitingResponse = false;
        }, function() {
            awaitingResponse = false;
        });
    }
}

load_pictures();
$interval(load_notifications, 3000);

【讨论】:

    【解决方案3】:

    您可以在收到答复后等待 300 毫秒,如下所示:

    function load_notifications(){
        $http.get('http://localhost:3000/load').success(function(data){
            $scope.totalNotify = data.total;
            setTimeout(function() {
                load_notifications();
            }, 300);
        });
    };
    load_pictures();
    load_notifications();
    

    【讨论】:

      【解决方案4】:

      如果您只使用 websockets,您将需要每次运行查询以确定是否有任何更改。我建议,使用实时数据库。

      您可以将RethinkDBFirebaseAngularFire 一起使用。这些是实时数据库,并且会在任何这些字段有更新时通知您。 如果你使用 RethinkDB,那么你还需要实现一个 websocket 解决方案来通知浏览器。

      【讨论】:

      • 这是不正确的。每当插入或更新记录时,您都会触发 Web 套接字推送,而不是实时监控数据库。这使您无需任何监控/实时数据库功能即可实时更新前端,并且它可以实时运行而无需大量服务器负载。编辑:话虽如此,我喜欢 firebase 和 angularfire。
      • @MikelBitson 如果您不介意,您能否提供一个基本示例,如何 Web 套接字在 DB 发生变化时将数据推送到前端。
      • 如果您有多个更新数据库的节点,那么每个节点都会一直通知更改,这会变得非常混乱。
      • @fos.alex 这是真的,它可能会变得复杂。使用单个 Web 套接字服务器可以解决这个问题 - 让所有节点将其更新推送到 Web 套接字服务器,该服务器会推送到所有前端客户端。
      • @NuttyProgrammer 我在回答中添加了 Rachet(PHP Web Socket 库)的基本 hello-world 示例。
      猜你喜欢
      • 2014-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-21
      • 2014-02-28
      • 1970-01-01
      相关资源
      最近更新 更多