我计划重新设计现有系统以使用 Akka、Play 和 Websockets。
我目前的系统是基于 Jetty 和 Websockets 的。
我有一个发布到 Redis channel 的快速消息流。在我的 Web 应用程序层中,我使用 Jedis 订阅者订阅这些消息,然后将这些消息推送到 Websocket,然后显示在浏览器上。
我想做两个转变的两个主要原因 - a) 由于使用 Actors,容错性更好、更简单 b) 使用不同的参与者连接到多个流的能力
在我目前的设计中,我有一个主管为每个新 channel 创建一个新的 child Actor 。子 Actor 然后订阅 Redis channel 。我的问题是将消息(从 Redis channel 收到)推送到 Play Websocket 的最佳方式是什么?
最佳答案
我将从一个基于三层 Actor 的解决方案开始。从 Redis 提要到 Websockets:
- ChannelDispatcherActor
- ChannelActor
- WebsocketActor
ChannelDispatcherActor 是一个单例,它从 Redis 提要接收 Publish(Channel, Content) 流,并使用惰性创建语义维护 Channel 到 ChannelActor 的私有(private)映射。它接受消息
- Subscribe(Channel, WebsocketActor) - 为 Channel 查找 ChannelActor,必要时创建,转发给 ChannelActor
- 取消订阅(Channel,WebsocketActor) - 相同 - 查找和转发
- 发布( channel ,内容) - 相同 - 查找和转发
ChannelActor 每个 channel 一个,并维护一组监听其 channel 的 WebsocketActor。它接受消息
- Subscribe(Channel, WebsocketActor) - 添加 WebsocketActor 到监听器,还有 context.watch(actorref)
- Unsubscribe(Channel, WebsocketActor) - 从监听器中移除
- Terminated(WebsocketActor) - 从监听器中移除
- Publish() - 发送给每个听众
WebsocketActor 是每个 websocket 一个,维护一个 websocket 订阅的 channel 列表,并将它从 ChannelActor 接收的流量发布到它的 websocket。为了管理 Channels,它发送 ChannelDispatcherActor 订阅/取消订阅。它在 websocket 关闭时自行终止,WebsocketActor 通过 then watch() 清理它们的监听器列表。
需要进行大量优化,这对容错没有任何作用,但这些是单独的帖子。
Hakking 快乐!!
关于scala - 将订户建模为 Akka Actor 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22569664/