我正在尝试在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}]}
消息被发布到websocket和长轮询通道的通用路由,消息结构看起来像
{:from "userid1" :to "userid2" :message "message content"}
服务器在:from和:to用户ID中找到原子中的所有通道,并将消息发送到各个用户的连接通道,同时它在Redis服务器上发布消息,连接节点在其中查找存储在其节点中的通道拥有原子并将消息传递给各个用户。
因此,我遇到的问题是如何正确实现状态。基本上,当通道断开连接时,http-kit会向您发送状态,状态可以是“服务器关闭”或“客户端关闭”,而我可以处理服务器断开连接(客户端将自动重新连接),但是断开连接时我遇到了问题从客户端发生,例如。用户导航到另一个页面,几秒钟后将连接。当客户端断开连接时,如何确定用户已脱机。我也担心长轮询模式下消息到达黑白会重新连接(我的长轮询超时是30秒)。
还请为上述架构建议一个良好的存在机制。谢谢。
如果您需要更多信息,请发表评论。谢谢
编辑#1:
您能推荐有关在聊天服务器中实现在线状态的良好教程/ Material 吗,我似乎什么也找不到。
我当前的解决方案->我当前正在维护特定用户ID的已连接通道的全局计数和最后连接的时间戳,当用户断开连接时,计数会减少,并且实施10秒钟的超时将检查用户是否具有再次重新连接(即,最后连接的戳记已存在10秒钟且计数仍为零),如果不是,则认为用户已脱机,您是否会推荐此解决方案?如果不是,则建议使用任何改进或更好的方法。
还请注意,我正在使用http-kit中的timer / scheduled-task,这些超时是否会对性能产生重大影响?
最佳答案
客户端有两种不同的情况。
这是否回答你的问题?
关于clojure - Clojure中的可扩展聊天服务器。存在和消息到达的问题黑白重新连接,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22147317/