在线用户存储Elixir

时间:2014-08-07 03:41:23

标签: otp elixir gen-server mix

我正在使用OTP Genserver在Elixir中的一个聊天室[all to all]应用程序上工作,并在用户以其名称作为第一阶段注册时从js客户端获取消息。现在,有点不确定以某种方式将这些名称存储在我的elixir服务器上的最佳方法是什么,并将定期更新发送到客户端以及在线用户列表或数据库存储。请建议最好的方法。

2 个答案:

答案 0 :(得分:4)

我同意bitwalker的观点,即ETS非常适合。

以下是我在制作中所做的简短摘要。它不是一个聊天服务器,而是一个服务器推送,有几千个用户通过长轮询连接。推送数据分为约50个类别,用户可以选择他们想要的数据。在高峰时间,服务器每2秒推送新消息,并且处理> 2000 reqs / sec。

基本上,我为每个用户保留了gen_server,其中我保留了待处理消息和用户配置(基本上是所选通道的列表)。这对于长轮询是有益的,因为用户的数据与用户的请求分离,因此在请求是暂时的时候数据仍然存在。但是,我认为这种方法也适用于永久连接,例如websockets,因为可能偶尔会断开连接,并且保持更稳定的用户数据可以让您在重新连接后恢复。

显然,当请求到达时,您需要找到特定于用户的流程,为此,ETS非常合适,因为您没有单个流程瓶颈。我建议不要手动使用ETS,而是将gprocvia元组结合使用。基本上,在启动用户的gen_server时,您可以根据内部用户的ID(name: {:via, :gproc, {:n, :l, key}}key提供:n其中:l是您自定义密钥(任意字词)的位置表示本地节点上的唯一名称)。然后,您可以在发出调用/强制转换时使用相同的via元组,gen_server将使用gproc来查找相应的进程。

最后,您需要使用一些超时/断开逻辑来清理用户进程。在我的情况下,如果没有来自Web层的活动,我只是终止了用户的进程(在一段时间内没有最终用户来获取数据)。 Gproc将自动从其内部ETS表中删除已终止进程的条目。最好在temporary策略下监督用户流程。

我意识到所有这一切仍然有点模糊,但我希望它有一定道理。请记住,这不是最终的模式(当然没有这样的事情),但我认为这是合理的第一次尝试。

您可能还想查看具有Topics形式的有趣pub-sub工具的Phoenix web framework。我自己还没有尝试过,但它似乎很有趣,甚至可以简化我上面讨论的一些内容,或者至少有助于将聊天室的通知推送给所有用户。

答案 1 :(得分:2)

听起来像是ETS的一个很好的用例。

更简单的方法可能是使用代理来存储在线用户信息,但它很大程度上依赖于您所选择的存储机制所需的内容。