Phoenix Websocket socket.disconnect()与channel.leave()

dai*_*no3 0 elixir websocket phoenix-framework

我正在阅读有关如何从套接字断开连接或离开通道的phoenix文档

我天真的理解是 channel#leave

取消订阅服务器事件,并指示通道在服务器上终止

socket#disconnect维护通道服务器端,以便重新连接。

因此,我的问题是何时使用一个与另一个。

听起来有两种情况需要考虑:

  1. 还有其他客户端订阅了相同的频道,因此#leave将切断他们的连接,而倾向于#disconnect
  2. 但是,如果存在用户/帐户损耗,则从不调用来leave维护服务器上的“死”通道,而对于长时间运行的进程,这可能是一个问题吗?

我在想这个吗?如果我们选择只使用#disconnect-roll,我们是否应该实施定期的清理任务以杀死长时间运行的“死”通道?

谢谢!

m3c*_*ers 7

Phoenix的实时接口基于两个默认的公共抽象,即套接字接口,客户端通过该接口进行连接-这通常是一个websocket(尽管它可以回退为longpolling或使用其他传输方式),但这是“线”在客户端和服务器之间创建。通常,您通过令牌来中介此连接,以确定客户端是否能够打开该套接字连接。在中指定user_socket.ex

然后,您具有通道接口,该接口是带有特定句柄(api)的gen_server,该句柄经过了调整,可以通过“线路”接收传入的消息。您还可以使用授权逻辑来允许订阅频道(“加入”),并且可以随频道(甚至主题)而变化。

每个客户端可以连接到1个插座和0到N个通道。连接到其下的通道的客户端只需简单地(简化)将给定的套接字注册到发布者订阅者接口(Phoenix的PubSub),并为每个订阅该特定组合的套接字具有用于“通道:房间”的进程。

如果:observer.startiex外壳启动,然后转到Processes选项卡,然后从两个不同的客户端加入相同的完全相同的“ channel:topic”,您将看到将有两个通道进程,而不是一个。如果您从Elixir.YourWeb.PubSub.Local0看到“应用程序”树,您还将看到2个与之“连接”的进程。

这意味着,当您channel.leave()从前端发出a 时,服务器会从刚刚“离开”的“通道”中取消对此客户端的订阅,并且关闭处理该客户端的进程。通道休假取消了该特定channel:topic组合的特定套接字(客户端)的订阅。这不会干扰连接到同一主题的其他客户端。在这种情况下,插座(“电线”)仍处于连接状态。您可以重新加入频道,也可以加入其他频道,而无需“询问”(协商)以再次连接到套接字。

另一方面,如果发出问题socket.disconnect(),则是“拔掉电线”,因此,从先前已预订的所有通道中取消订阅该特定的套接字(客户端)。这将使与该给定套接字相关的所有进程都关闭,但也不会干扰其他客户端的套接字/连接/订阅。

如果所有客户端都离开一个给定的通道(通过“离开”或“断开”其套接字),您将看到该给定通道将没有任何进程在运行。一旦另一个客户加入该频道,就会为该特定客户和channel:topic创建一个过程。

tldr; 回答您的问题:

  • 1)不

  • 2)没有

但是,如果您从通道本身内部产生了运行时间较长的进程,那么当没有客户端连接到该特定channel:topic时应将其关闭,那么您当然需要确保将其清理干净。除了Erlang的常规监视功能外,Phoenix还具有一个Presence界面,您也可以对其进行跟踪。