Facebook,Gmail如何发送实时通知?

我已经阅读了关于这个主题的一些帖子,答案是彗星,反向ajax,http流媒体,服务器推送等。

Gmail上的收到邮件通知如何工作?

GMail Chat如何在没有客户端交互的情况下发出AJAX请求?

我想知道是否有任何代码引用可以用来编写一个非常简单的示例。 许多帖子或网站只是谈论这项技术。 很难找到完整的示例代码。 此外,似乎可以使用许多方法来实现彗星,例如隐藏IFrame,XMLHttpRequest。 在我看来,使用XMLHttpRequest是一个更好的选择。 你如何看待不同方法的优缺点? Gmail使用哪一个?

我知道它需要在服务器端和客户端进行。 有没有PHP和Javascript示例代码?


Facebook做这件事的方式非常有趣。

执行此类通知的常用方法是在给定时间间隔(可能每隔几秒)在服务器上轮询脚本(使用AJAX),以检查是否发生了某些事情。 然而,这可能是网络密集型的,而且你经常做出毫无意义的请求,因为什么都没有发生。

Facebook做它的方式是使用彗星方法,而不是在一个时间间隔内进行轮询,只要一次轮询完成,它就会发出另一个轮询。 但是,对服务器上脚本的每个请求都有一个非常长的超时时间,并且服务器只会在发生某些事件时才响应请求。 如果您在Facebook上显示Firebug的控制台选项卡,您可以看到发生这种情况,对脚本的请求可能需要几分钟时间。 这真的很巧妙,因为这种方法可以立即减少请求的数量,以及你必须多久发送一次。 您现在有效地拥有一个允许服务器“激发”事件的事件框架。

在这之后,从这些民意测验返回的实际内容来看,这是一个JSON响应,其中似乎是一系列事件以及有关它们的信息。 它被缩小了,所以有点难以阅读。

就实际技术而言,AJAX是这里的一种方式,因为您可以控制请求超时以及其他许多事情。 我建议(Stack overflow cliche在这里)使用jQuery来完成AJAX,它会带走很多交叉兼容性问题。 就PHP而言,您可以简单地轮询PHP脚本中的事件日志数据库表,并且只在发生问题时才返回客户端。 我期望有很多方法来实现这一点。

实现:

服务器端:

在PHP中似乎有一些彗星库的实现,但说实话,它确实非常简单,可能类似于下面的伪代码:

while(!has_event_happened()) {
   sleep(5);
}

echo json_encode(get_events());
  • has_event_happened函数只是检查事件表中是否有任何事情发生,然后get_events函数会返回表中新行的列表? 取决于问题的背景。

  • 不要忘记改变你的PHP最大执行时间,否则它会提前超时!

  • 客户端:

    看一看用于做Comet交互的jQuery插件:

  • 项目主页:http://plugins.jquery.com/project/Comet
  • Google Code:https://code.google.com/archive/p/jquerycomet/ - 在Subversion存储库中似乎有某种示例用法。
  • 也就是说,插件似乎增加了一些复杂性,它在客户端上确实非常简单,或许(使用jQuery)如下所示:

    function doPoll() {
       $.get("events.php", {}, function(result) {
          $.each(result.events, function(event) { //iterate over the events
              //do something with your event
          });
          doPoll(); 
          //this effectively causes the poll to run again as
          //soon as the response comes back
       }, 'json'); 
    }
    
    $(document).ready(function() {
        $.ajaxSetup({
           timeout: 1000*60//set a global AJAX timeout of a minute
        });
        doPoll(); // do the first poll
    });
    

    整个事情很大程度上取决于你现有的架构如何组合在一起。


    更新

    在我继续接受upvotes这个,我认为这是合理的记住,这个答案是4岁。 网络的发展速度非常快,所以请注意这个答案。


    我最近有同样的问题,并就这个问题进行了研究。

    给出的解决方案称为长轮询,为了正确使用它,你必须确保你的AJAX请求有一个“大”超时并且在当前结束(超时,错误或成功)之后总是发出这个请求。

    长轮询 - 客户端

    在这里,为了保持代码简洁,我将使用jQuery:

    function pollTask() { 
    
        $.ajax({
    
            url: '/api/Polling',
            async: true,            // by default, it's async, but...
            dataType: 'json',       // or the dataType you are working with
            timeout: 10000,          // IMPORTANT! this is a 10 seconds timeout
            cache: false
    
        }).done(function (eventList) {  
    
           // Handle your data here
           var data;
           for (var eventName in eventList) {
    
                data = eventList[eventName];
                dispatcher.handle(eventName, data); // handle the `eventName` with `data`
    
           }
    
        }).always(pollTask);
    
    }
    

    记住(来自jQuery文档)非常重要:

    在jQuery 1.4.x及以下版本中,如果请求超时,XMLHttpRequest对象将处于无效状态; 访问任何对象成员可能会抛出异常。 仅在Firefox 3.0+中,脚本和JSONP请求不能被超时取消; 脚本即使在超时时间后到达,也会运行。

    长轮询 - 服务器

    它不是用任何特定的语言,但它会是这样的:

    function handleRequest () {  
    
         while (!anythingHappened() || hasTimedOut()) { sleep(2); }
    
         return events();
    
    } 
    

    在这里, hasTimedOut将确保您的代码不会永远等待,并且发生的anythingHappened都会检查是否有任何事件发生。 sleep是释放你的线程来做其他事情,而没有任何反应。 这些events将以JSON格式(或您喜欢的任何其他方式)返回events字典(或您可能更喜欢的任何其他数据结构)。

    它肯定可以解决问题,但是,如果您担心研究时的可扩展性和性能问题,那么您可以考虑另一种解决方案。

    使用套接字!

    在客户端,为了避免任何兼容性问题,请使用socket.io。 它试图直接使用套接字,并且在套接字不可用时具有回退到其他解决方案的功能。

    在服务器端,使用NodeJS创建一个服务器(这里是示例)。 客户端将订阅由服务器创建的这个频道(观察者)。 每当必须发送通知时,都会在此频道中发布通知,并通知下标(客户端)。

    如果您不喜欢此解决方案,请尝试APE(Ajax Push Engine)。

    希望我帮助。


    根据有关Facebook消息系统的幻灯片,Facebook使用慧星技术向网络浏览器“推送”消息。 Facebook的彗星服务器建立在开源的Erlang网络服务器mochiweb上。

    在下图中,“通道簇”这个短语的意思是“彗星服务器”。

    系统总览

    许多其他大型网站都建立了自己的慧星服务器,因为每家公司的需求都存在差异。 但是在开源慧星服务器上构建自己的慧星服务器是一种好方法。

    你可以试试icomet,一个用libevent构建的C1000K C ++慧星服务器。 icomet还提供了一个JavaScript库,它很容易使用,操作简单:

    var comet = new iComet({
        sign_url: 'http://' + app_host + '/sign?obj=' + obj,
        sub_url: 'http://' + icomet_host + '/sub',
        callback: function(msg){
            // on server push
            alert(msg.content);
        }
    });
    

    icomet支持多种浏览器和操作系统,包括Safari(iOS,Mac),IE(Windows),Firefox,Chrome等。

    链接地址: http://www.djcxy.com/p/57333.html

    上一篇: How does facebook, gmail send the real time notification?

    下一篇: Convert an associative array to a simple array of its values in php