我正在尝试在Clojure中构建可扩展的聊天服务器.我正在使用http-kit,compojure和redis pub / sub在不同节点之间进行通信(扇出方法).服务器将使用websockets连接黑白客户端-服务器,并回退到长时间轮询.单个用户可以具有多个连接,以与浏览器中每个选项卡的一个连接聊天,并且应该将消息传递给所有连接.
所以基本上,当用户连接时,我将通道存储在具有随机uuid的原子中
{:userid1 [{:socketuuid "random uuid#1 for uerid1" :socket "channel#1 for userid1"}
{:socketuuid "random uuid#2" :socket "channel#2"}]
:userid2 [{:socketuuid "random uuid#1 for userid2" :socket "channel#1 for userid2}]}
消息被发布到websockets和长轮询通道的通用路由,消息结构看起来像
{:from "userid1" :to "userid2" :message "message content"}
服务器在:from和:to用户ID中找到原子中的所有通道,并将消息发送到各个用户的连接通道,同时还在Redis服务器上发布消息,连接节点在其中查找存储在其节点中的通道拥有原子并将消息传递给各个用户.
因此,我遇到的问题是如何正确实现状态.基本上,当通道断开连接时,http-kit会向您发送状态,状态可以是“服务器关闭”或“客户端关闭”,而我可以处理服务器断开连接(客户端将自动重新连接),但是断开连接时我遇到了问题从客户端发生,例如.用户导航到另一个页面,几秒钟后将连接.当客户端断开连接时,如何确定用户已脱机.我也担心长轮询模式下的消息到达黑白会重新连接(我的长轮询超时是30秒).
另外,请为上述架构提出一个良好的呈现机制.谢谢.
如果您需要更多信息,请发表评论.谢谢
编辑#1:
您能推荐有关在聊天服务器中实现在线状态的良好教程/材料吗,我似乎什么也找不到.
我当前的解决方案->我目前正在维护一个特定用户ID的已连接通道的全局计数和最后连接的时间戳,当用户断开连接时,计数会减少,并且会实施10秒钟的超时,这将检查用户是否已重新连接(即上次连接的戳记的使用时间为10秒,计数仍然为零),如果不是,则认为用户已脱机,您是否会推荐此解决方案?如果不是,则建议您采取任何改进或更好的方法.
另外请注意,我正在使用http-kit中的timer / scheduled-task,这些超时是否会对性能产生重大影响?