仅在侦听器存在时发布消息?

时间:2015-07-08 10:07:21

标签: javascript php rabbitmq

使用RabbitMQ,我喜欢我的(PHP)代码,只有当这个特定用户正在收听时才向特定客户发布消息。

原因是我的连接用户将打开一个websocket,它将等待来自RabbitMQ的通知并在通知到达时更新UI。但是当他们第一次加载页面时,所有先前的通知都将被加载,因此无需重新加载队列中的通知。

对于消息队列的新手,我不知道它是否可行,但我希望我的发布者检查用户ID = X当前是否正在侦听(因为websocket将打开一个正在执行的频道),如果他正在收听,则发布消息。如果他不是,那么它就不会发布该消息(但将其添加到数据库中)。

工作流程如下:

发布者:

  1. 端点正在接收事件
  2. 将事件保存在数据库中
  3. 检查用户ID = X是否有开放频道,如果是,则将该事件发布到该频道
  4. 订阅者:

    1. 客户连接到应用
    2. 前端加载数据库中的最后一个事件
    3. 前端为特定用户打开一个websocket,用于收听可能发布的事件
    4. 发布事件时,websocket会告诉前端。
    5. 也许我所问的是基本的,但我缺乏知识。

      一个红利问题:打开PER客户渠道或为所有客户打开通用渠道,订阅方会过滤是否更好?

      感谢您的帮助:)

1 个答案:

答案 0 :(得分:1)

我相信你遇到了问题,因为AMQP在发布者和队列之间存在差异。两者之间没有一对一的对应关系。

如果我正确了解您的情况,您就有一个中央发布者正在向消息代理发送消息。与此同时,您有许多潜在订阅者在代理上签名和签名(在这种情况下通过websockets)。其中一个订阅者是一个数据库进程,它将所有消息归档以供以后检索。

我建议如下:

  1. 将这些消息发布到主题式交换
  2. 订阅消费者每个人在订阅时创建自己的队列。这将在Web服务器代码中完成,它会将到达的消息汇集到websocket。
  3. 创建订阅队列(动态)时,将队列设置为在(短)秒后自动删除,因此连接中的小中断不会导致丢失消息。
  4. 为进入数据库进程的消息创建持久队列。
  5. 消费应用程序负责在从数据库加载的消息和通过websocket流入的消息之间进行重复数据删除。为guid分配每封邮件应该对此有所帮助。
  6. 要回答第二个问题,这取决于您的Web服务器架构。我对PHP知之甚少,但就AMQP协议本身而言,没有任何影响。通道只是协议级构造,因此创建它们的影响可以忽略不计。多个消费者可以共享一个频道,或者您可以为每个消费者创建一个频道。这真的没什么区别。