Erlang和Cowboy用于实时web通信

Erlang和Cowboy用于实时web通信,erlang,elixir,cowboy,Erlang,Elixir,Cowboy,Cowboy将为每个请求生成进程(在本例中是websocket连接、事件源请求或通过ajax的长轮询) 在用户之间发送消息只需将消息发送到表示与该用户连接的相应进程即可解决问题(如果您有两个用户并且都支持websocket,则有两个进程,每个进程表示websocket连接) 假设我有两个用户(Foo、Bar)。 Foo希望将消息发送到Bar,因此,Foo进程必须以某种方式获得与代表到用户Bar的连接的cowboy进程相关联的pid(这样他就可以向他发送常规erlang消息-消息在内部发送给用户w

Cowboy将为每个请求生成进程(在本例中是websocket连接、事件源请求或通过ajax的长轮询)

在用户之间发送消息只需将消息发送到表示与该用户连接的相应进程即可解决问题(如果您有两个用户并且都支持websocket,则有两个进程,每个进程表示websocket连接)

假设我有两个用户(Foo、Bar)。

Foo希望将消息发送到Bar因此,Foo进程必须以某种方式获得与代表到用户Bar的连接的cowboy进程相关联的pid(这样他就可以向他发送常规erlang消息-消息在内部发送给用户webbrowser)

但是当Foo获得pid时发生了什么,pid将变得无效,因为用户Bar将同时重新连接(重新连接意味着与Bar关联的进程已终止,并且由于Bar再次连接,他将获得新进程)?

由于网络问题,Bar已重新连接

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

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


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

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


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

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

您可以使用lib。它确实使用ETS来注册、监视、发送消息和其他过程。您可以使用属性、唯一名称甚至计数器注册进程,并使用ETS查询功能查询它们。API真的很完整


我认为,如果你想保证交付,你需要自己来做。

这是我想要避免的,因为它需要所有的客户端进程通过一个连续点(维护ets的进程)。不管怎么说,看看下面的例子,ETS似乎是直接用C实现的,而不是通过一个进程来管理的。如果直接调用ETS,则不会产生任何瓶颈影响。ETS表在公开时是全局的。任何进程都可以直接读写。@Krab-如上所述-您不需要ant进程来“维护”ets。ets可以写入和读取任何进程。您甚至可以根据您的使用情况对其进行调整以优化读并发和/或写并发。您可能希望使用RabbitMQ之类的消息传递框架。因为它是实时通信,所以您不希望以错误的顺序传递消息。以skype为例。除非所有旧消息都按顺序传递,否则不会向Foo发送新消息。时间戳在这里会有所帮助。在尝试发送之前,msg发送守护进程必须知道谁打开或关闭。然后它存储这些消息=
#msg{from,to,msg,timestamp}
。当用户重新连接时,它确保他/她首先以正确的顺序接收所有旧消息,然后再向其发送新消息。