Phoenix websocket socket.disconnect() 对比 channel.leave()
Phoenix websocket socket.disconnect() vs. channel.leave()
我正在通读 phoenix docs 有关断开套接字或离开频道的方法。
我天真的理解是channel#leave
Unsubscribes from server events, and instructs the channel to terminate on server
和socket#disconnect
在服务器端维护通道,允许重新连接。
所以,我的问题是何时使用一个与另一个。
听起来好像有两种情况需要考虑:
- 有其他客户端订阅了同一频道,因此
#leave
将切断他们的连接,支持 #disconnect
。
- 但是如果存在 user/account 损耗,永远不会调用
leave
在服务器上维护 "dead" 通道,并且对于长时间的 运行 进程,这可能是一个问题?
我的想法是否正确?如果我们选择滚动 #disconnect
-only,我们是否应该执行周期性清理任务来杀死 long-运行、"dead" 通道?
谢谢!
Phoenix 的实时接口建立在两个默认的 public 抽象之上,一个套接字接口,客户端通过它进行连接 - 这通常是一个 websocket(尽管它可以回退到长轮询或使用其他传输) ,这是在客户端和您的服务器之间创建的 "wire"。通常您通过令牌来调解此连接,以确定客户端是否能够打开该套接字连接。它在 user_socket.ex
.
中指定
然后是通道接口,它是一个 gen_server,带有特定句柄 (api),专为通过 "wire" 接收传入消息而设计。您还可以使用授权逻辑来允许订阅频道 ("joining"),并且它可以因频道(甚至主题)而异。
每个客户端可以连接到1个套接字和0到N个通道。在下面,连接到通道的客户端只是(简化)将给定套接字注册到发布者订阅者接口(Phoenix 的 PubSub),并为订阅该特定组合的每个套接字设置一个进程 "channel:room"。
如果您从 iex
shell 启动 :observer.start
,然后转到 Processes
选项卡,然后从两个不同的客户端加入,完全相同"channel:topic" 您会看到将有两个通道进程,而不是一个。如果您从 Elixir.YourWeb.PubSub.Local0 看到应用程序树,您还会看到 2 个进程 "connected" to/from 它。
这意味着当您从前端发出 channel.leave()
时,您的服务器取消订阅该客户端与 "channel" 您刚刚 "left" 以及正在处理它的进程被关闭。通道离开是从特定 channel:topic
组合取消订阅特定套接字(客户端)。这不会干扰连接到同一主题的其他客户端。在这种情况下,套接字 ("wire") 仍然处于连接状态。您可以重新加入频道,或加入其他频道,而无需 "ask"(协商)再次连接到套接字。
另一方面,如果您发出 socket.disconnect()
,您就是 "plugging off the wire",并因此取消订阅该特定套接字(客户端)之前订阅的所有频道。这使得与给定套接字相关的所有进程都关闭,但也不会干扰其他客户端的 sockets/connections/subscriptions.
如果所有客户端都离开给定通道(通过 "leave" 或 "disconnect" 连接他们的套接字),您会看到不会有任何进程 运行给定的频道。一旦另一个客户端加入该频道,就会为该特定客户端创建一个进程 & channel:topic。
tldr;回答你的问题:
1) 没有
2) 没有
但是如果您有从通道本身内部产生的长 运行 进程,当没有客户端连接到该特定 channel:topic 时应该关闭该进程,那么您将需要确保你当然清理它们。除了 Erlang 的常用监控功能外,Phoenix 还具有一个 Presence 界面,您也可以通过该界面对其进行跟踪。
我正在通读 phoenix docs 有关断开套接字或离开频道的方法。
我天真的理解是channel#leave
Unsubscribes from server events, and instructs the channel to terminate on server
和socket#disconnect
在服务器端维护通道,允许重新连接。
所以,我的问题是何时使用一个与另一个。
听起来好像有两种情况需要考虑:
- 有其他客户端订阅了同一频道,因此
#leave
将切断他们的连接,支持#disconnect
。 - 但是如果存在 user/account 损耗,永远不会调用
leave
在服务器上维护 "dead" 通道,并且对于长时间的 运行 进程,这可能是一个问题?
我的想法是否正确?如果我们选择滚动 #disconnect
-only,我们是否应该执行周期性清理任务来杀死 long-运行、"dead" 通道?
谢谢!
Phoenix 的实时接口建立在两个默认的 public 抽象之上,一个套接字接口,客户端通过它进行连接 - 这通常是一个 websocket(尽管它可以回退到长轮询或使用其他传输) ,这是在客户端和您的服务器之间创建的 "wire"。通常您通过令牌来调解此连接,以确定客户端是否能够打开该套接字连接。它在 user_socket.ex
.
然后是通道接口,它是一个 gen_server,带有特定句柄 (api),专为通过 "wire" 接收传入消息而设计。您还可以使用授权逻辑来允许订阅频道 ("joining"),并且它可以因频道(甚至主题)而异。
每个客户端可以连接到1个套接字和0到N个通道。在下面,连接到通道的客户端只是(简化)将给定套接字注册到发布者订阅者接口(Phoenix 的 PubSub),并为订阅该特定组合的每个套接字设置一个进程 "channel:room"。
如果您从 iex
shell 启动 :observer.start
,然后转到 Processes
选项卡,然后从两个不同的客户端加入,完全相同"channel:topic" 您会看到将有两个通道进程,而不是一个。如果您从 Elixir.YourWeb.PubSub.Local0 看到应用程序树,您还会看到 2 个进程 "connected" to/from 它。
这意味着当您从前端发出 channel.leave()
时,您的服务器取消订阅该客户端与 "channel" 您刚刚 "left" 以及正在处理它的进程被关闭。通道离开是从特定 channel:topic
组合取消订阅特定套接字(客户端)。这不会干扰连接到同一主题的其他客户端。在这种情况下,套接字 ("wire") 仍然处于连接状态。您可以重新加入频道,或加入其他频道,而无需 "ask"(协商)再次连接到套接字。
另一方面,如果您发出 socket.disconnect()
,您就是 "plugging off the wire",并因此取消订阅该特定套接字(客户端)之前订阅的所有频道。这使得与给定套接字相关的所有进程都关闭,但也不会干扰其他客户端的 sockets/connections/subscriptions.
如果所有客户端都离开给定通道(通过 "leave" 或 "disconnect" 连接他们的套接字),您会看到不会有任何进程 运行给定的频道。一旦另一个客户端加入该频道,就会为该特定客户端创建一个进程 & channel:topic。
tldr;回答你的问题:
1) 没有
2) 没有
但是如果您有从通道本身内部产生的长 运行 进程,当没有客户端连接到该特定 channel:topic 时应该关闭该进程,那么您将需要确保你当然清理它们。除了 Erlang 的常用监控功能外,Phoenix 还具有一个 Presence 界面,您也可以通过该界面对其进行跟踪。