WebSocket推送数据库更新

时间:2014-04-23 11:26:59

标签: heroku architecture websocket redis playframework-2.2

Web上处理WebSockets的大多数文章都是关于内存聊天的 我对那种不那么即时的聊天感兴趣,这是持久的,就像博客的帖子评论一样。

我有两个服务器处理客户端请求的集群 我想知道什么是处理将数据库更新推送到相应客户端的最佳策略。

由于我使用Heroku来处理这个群集(2个网络dynos),我显然是阅读this tutorial,旨在建立一个在所有客户端之间共享的聊天室。

它使用Redis来集中即将发送的消息;每个服务器通过websocket连接侦听新消息传播到Web客户端。

我的用例不同之处在于我拥有一个Neo4j数据库,每个客户端写入的每条消息都会持续存在。
我的目标是通知特定房间的每个客户,客户刚刚保留了新的消息/评论。

使用类似于上面链接的教程的架构,我如何只过滤新消息以传播给用户?有没有一种简单有效的方法来告诉Redis:

"(WebSocket说)当我的客户端启动websocket连接时,我会小心查询所有持久消息并将它们发送到客户端,但我希望你(Redis)能够为我提供我没有发送给客户的所有新消息,以便我能够提供这些消息。"

如何在每次进行websocket连接时阻止Redis发布整个会话?由于数据库查询此时已经提供了现有内容,因此会导致重复。

1 个答案:

答案 0 :(得分:1)

这实际上是一种非常常见的情况,你有三个组成部分:

  1. 无状态Web服务器集群,与所有客户端保持开放连接(显然,在集群中负载均衡)
  2. 持久主数据存储 - 您的案例中的Neo4j
  3. 跨渠道广播消息的消息传递/排队后端(因此跨服务器群集) - Redis
  4. 您的要求是新客户端实时接收最近消息的初始提要以及任何后续消息。所有这些都在您的连接处理程序中实现。

    基本上,这就是你的(伪)代码应该是这样的:

    class ConnectionHandler:
    
        redis = redis.get_connection()
    
        def on_init():
            self.send("hello, here are all the recent messages")
            recent_msgs = fetch_msgs_from_neo4j()
            self.send(recent_msgs)
            redis.add_listener(on_msg)
            self.send("now listening on new messages")
    
        def on_msg(msg):
            self.send("new message: ")
            self.send(msg)
    

    确切的实现实际上取决于您的环境,但这是一般情况。