2

Cowboy 将为每个请求生成进程(在这种情况下,它是 websocket 连接、事件源请求或通过 ajax 进行的长轮询)。

只需将消息发送到代表与该用户的连接的适当进程即可解决用户之间的发送消息(如果您有两个用户并且都支持 websockets,则有 2 个进程,每个代表 websocket 连接)。

假设我有 2 个用户(Foo,Bar)。

Foo 想向 Bar 发送消息因此 Foo 进程必须以某种方式获取与表示与用户 Bar 的连接的牛仔进程相关联的 pid(这样他就可以向他发送常规的 erlang 消息 - 消息在内部发送给用户 webbrowser)。

但是 Foo 获取 pid 后 pid 会失效,因为此时用户 Bar 会重新连接(重新连接意味着与 Bar 关联的进程已终止,因为 Bar 再次连接,所以他得到了新进程)?

由于网络问题,重新连接吧。

这意味着如果 Foo 将向 Bar 发送消息(Foo 具有进程的 pid,该进程已经终止),则消息将永远不会被传递。

第一个解决方案是,因为消息应该是持久的(例如 facebook 上的消息),所以在将其发送给用户之前,您将始终将其保存到 DB。 当用户连接时,必须进行一些同步,因为即使他有 99% 的时间在线,也可能有他没有的按摩。因此,Bar 会在重新连接后同步时从 Foo 获取消息(消息将从 DB 中提取)。

现在真正的问题是: 如果 Foo 的无效 PID 太长,他会在 Bar 重新连接并执行同步后发送一些消息怎么办?Bar 的消息将存储在数据库中,但由于它是在 Bar 同步后存储的,因此不会传递。

4

3 回答 3

1

正如您所确定的 - 将 PID 作为用户标识符并不是一个好的解决方案,因为它本质上是短暂的。我认为更好的解决方案是让用户 Foo 持有一些持久的用户 ID,这将识别用户 Bar,无论他是否连接。

您可以使用ETS或 DETS(支持持久性)保留从 User ID 到 PID 的映射,并向当前注册到永久 User ID 的 PID 发送消息。

于 2014-08-11T14:08:58.670 回答
0

所以 foo 和 bar 应该互相监控。如果一个进程死亡,另一个进程将收到消息{'DOWN', Ref, process, Pid2, Reason}。正如 Uri 所说,您可以将一个进程专门用于维护路由表。

于 2014-08-11T14:11:28.850 回答
0

您可以使用gproc库。它确实使用 ETS 来注册、监控、发送消息和其他过程。您可以使用属性、唯一名称甚至计数器注册流程,并使用 ETS 查询的强大功能进行查询。API 真的很齐全。

我认为如果你想要一些交货保证,你需要自己做。

于 2014-08-12T09:40:08.943 回答