使用 RabbitMQ,我希望我的 (PHP) 代码仅在该特定用户当前正在收听时才向该特定客户发布消息。
原因是我连接的用户将打开一个 websocket,它将等待来自 RabbitMQ 的通知并在通知到达时更新 UI。但是当他们第一次加载页面时,所有之前的通知都会被加载,所以不需要重新加载队列中的通知。
作为消息队列的新手,我不知道是否可行,但我希望我的发布者检查用户 ID = X 当前是否正在监听(因为 websocket 将在执行时打开一个 channel ),以及是否他目前正在收听,发布一条消息。如果他不是,则不会发布该消息(但将其添加到数据库中)。
工作流程是这样的:
发布者:
- 端点正在接收事件
- 将事件保存在数据库中
- 它检查用户 ID =X 是否有一个开放的 channel ,如果是,它将事件发布到该 channel
订阅者:
- 客户连接到应用
- 前端从数据库中加载最后的事件
- 前端为该特定用户打开一个 websocket 以监听可能发布的事件
- 发布事件时,websocket 会通知前端。
也许我问的很基础,但我缺乏知识。
一个额外的问题:是为每个客户打开一个 channel 更好,还是为所有客户打开一个通用 channel ,订阅方将过滤?
谢谢你的帮助:)
最佳答案
我相信您遇到了您的问题,因为在 AMQP 中发布者和队列之间存在区别。两者之间没有一一对应关系。
如果我对你的情况的理解正确,你有一个中央发布者正在向消息代理发送消息。同时,您有许多潜在订阅者正在注册和退出代理(在本例中是通过 websockets)。其中一个订阅者是一个数据库进程,它将所有消息存档以供以后检索。
我推荐的是:
- 将这些消息发布到主题式交换
- 订阅消费者各自在订阅时创建自己的队列。这将在 Web 服务器代码中完成,并将到达的消息汇集到 websocket。
- (动态)创建订阅队列时,将队列设置为在(短)秒数后自动删除,因此连接中的小中断不会导致消息丢失。
- 为进入数据库进程的消息创建一个持久队列。
- 消费应用程序有责任删除从数据库加载的消息和通过 websocket 流入的消息之间的重复数据。为每条消息分配一个
guid
应该对此有所帮助。
要回答您的第二个问题,这取决于您的网络服务器架构。本人对PHP了解不够,但就AMQP协议(protocol)本身而言,没有影响。 channel 只是协议(protocol)级结构,因此创建它们的影响可以忽略不计。多个消费者可以共享一个 channel ,或者您可以为每个消费者创建一个 channel 。这真的没有什么区别。
关于javascript - 仅当监听器存在时才发布消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31289494/