Cowboy将为每个请求生成进程(在这种情况下,它是websocket连接,事件源请求或通过ajax进行长轮询)。
在用户之间发送消息通过发送消息到相应的进程来解决(如果你有两个用户并且都有websocket支持,那么就有2个进程,每个进程代表websocket连接)。
假设我有两个用户(Foo, Bar)
Foo想要发送消息给Bar, 因此Foo进程必须以某种方式获取pid,该pid与代表与用户Bar连接的cowboy进程相关联(因此他可以向他发送常规的erlang消息-消息在内部发送给用户webbrowser)。
但是当Foo获得pid并且pid无效时,会发生什么,因为用户Bar将在此期间重新连接(重新连接意味着与Bar相关的进程被终止,并且因为Bar再次连接,他获得新进程)?
酒吧因网络问题重新连接。
这意味着如果Foo将发送消息给Bar (Foo有进程的pid,该进程已经终止),消息将永远不会被传递。
第一个解决方案是,因为消息应该是持久的(例如facebook上的消息),所以在发送给用户之前,您总是将其保存到DB。当用户连接时,必须进行一些同步,因为即使他99%的时间在线,也可能有他没有的消息。因此,当重新连接后同步时,Bar将从Foo获得消息(消息将从DB中提取)。
现在真正的问题是:如果Foo的无效PID太长,即使Bar重新连接并执行同步,他也会发送一些消息,该怎么办?Bar的消息将存储在数据库中,但由于它是在Bar执行同步后存储的,因此不会被传递。
正如您已经确定的那样,将PID作为用户标识符不是一个好的解决方案,因为它本质上是短暂的。我认为更好的解决方案是让用户Foo持有一些持久的用户ID,无论用户Bar是否连接,它都将识别用户Bar。
您可以使用ETS或DETS(支持持久化)保持从用户ID到PID的映射,并向当前注册到永久用户ID的PID发送消息。
所以foo和bar应该互相监视。如果一个进程死亡,另一个进程将获得消息{'DOWN', Ref, process, Pid2, Reason}
。正如Uri所说,您可以将一个进程专门用于维护路由表。
您可以使用gproc库。它确实使用ETS来注册、监控、发送消息和其他过程。您可以使用属性、唯一名称甚至计数器来注册进程,并使用ETS查询的功能对它们进行查询。api是真正完整的。
我认为如果你想要交货的保证,你需要自己做。