如何显示连续的实时更新,如facebook ticker,meetup.com主页呢?

时间:2012-07-27 13:08:46

标签: php python node.js asynchronous real-time

如何在facebook ticker,meetup.com主页等浏览器中显示连续的实时更新?在python,PHP,node.js以及服务器端的性能影响是什么? 如果页面被像akamai这样的CDN缓存,我们怎么能实现相同的更新呢?

4 个答案:

答案 0 :(得分:18)

您有两种选择(其他人已在上面详述)。如果您不熟悉每个选项背后的一些概念性想法,我想我会给出一两行关于它们的内容。请注意,我将在非常非常高的层次上展示这些概念。

您的三个选择是:

  1. 短轮询
  2. Web Socket
  3. Comet / Long-Polling
  4. 短轮询

    短轮询通过强制客户端不断向表单服务器发送请求来克服Client-Server之间的单向通信:

    Client: Do you have a message for me?
    Server: No.
    Client: (wait x seconds)
    Client: Do you have a message for me?
    Server: No.
    Client: (wait x seconds)
    Client: Do you have a message for me?
    Server: Yes. Here it is!
    Client: Yay!
    Client: (update message)
    

    代表客户的持续唠叨称为轮询。为了实现此结构,您需要将服务器设置为“侦听”来自客户端的这些轮询请求。服务器还必须在某处存储这些消息,以便在消息准备就绪时,服务器可以提供它们。在非常简单的层面上,您的服务器需要:

    • 接受一般网络请求
    • 接受投票请求
    • 运行提取消息的后台作业
    • 将这些消息存储在某处,以便在轮询请求进入时,服务器可以检查它们。

    您还需要将这些轮询请求绑定到用户的某种会话ID,以便正确的消息传递给合适的人。总的来说,范式很复杂,在我看来,效率低下。

    Web套接字

    Web套接字是HTML5的新功能。它们背后的基本思想是客户端可以保持与服务器的直接连接,并且可以相互推送信息。因此,而不是通常:客户端发送GET请求>>服务器响应内容,Web套接字允许您保持持续对话。

    但是,为了进行此设置,您需要:

    • 符合WebSocket的浏览器(并非全部都是)。
    • 可以处理网络套接字的服务器(不知道如何清楚地说明这一点,但并非所有服务器都设置为这种安排)。

    设置有点复杂,虽然比长轮询更简单:

    • 客户端维护与启用Web-Socket的连接到服务器
    • 的连接
    • 服务器通过网络套接字
    • 将结果推送到客户端
    • 客户根据结果更新页面

    您会看到此模式被称为推送通知(当然,如果您拥有自己经历过iPhone的iPhone),因为服务器已被授权推送客户的“东西”(多么不礼貌!)。由于存在许多客户端和服务器的细微差别,我建议测试类似Pusher的内容,它基本上是一个Web服务来处理Web套接字的所有难点部分。在开始自己设置之前,这将是一种简单的方法,您可以测试和使用该模式。它有客户端和服务器端库。

    希望信息为您提供解决问题的基准。其他答案有关于如何解决每个场景的更直接信息。

    Comet / Long-Polling

    另一种看似跨浏览器的Web套接字方法是Long-Polling(参见Comet)。在这种情况下,您的客户端建立与服务器的连接并使其挂起,等待数据被推回。这种设置有点复杂,但它确实代表了短轮询 Web套接字之间的中间地带。

答案 1 :(得分:6)

我建议使用SockJS或Socket.io作为客户端JavaScript库实现类似连接的套接字,然后在服务器端使用Tornado将任何状态更改发布到客户端。代码非常简单。

客户端代码取决于您选择的库。 SockJS或SocketIO。或者,如果您只想直接使用Websockets,则非常简单:

update_socket = new WebSocket("ws://my_server.com/listening_url");
update_socket.onmessage = function (evt) {
    $("#my_div").html(evt);
};

服务器端代码也非常简单:

import tornado

class UpdateHandler(tornado.websocket.WebSocketHandler):

    def open(self):
        self.write_message('Hi client')
        # listen for some events that are occurring
        for message in function_that_generates_events():
            self.write(message) 

    def on_message(self, message):
        # Do something with incoming messages

    def on_close(self):
        # tidy up

app = tornado.web.Application(('r/listening_url',UpdateHandler))
app.listen(9000)

答案 2 :(得分:0)

您可以使用民意调查,长轮询或是否需要推送系统。民意调查最简单。但是,所有解决方案都需要客户端编码。

性能影响取决于您的解决方案。最容易实施的是民意调查。频率较低的民意调查每次都会有效地进行一次请求,例如100ms即可模拟实时。长期民意调查影响较小,但会在或多或少的时间内保持大量的请求。

答案 3 :(得分:0)

Jetty

Ajax Push Engine

Socket.io

这些是实施Comet的方法

我推荐Socket.io,它是用Node.js实现的

因为它利用最佳可用连接方法