我正在阅读phoenix docs,以了解如何与套接字断开连接或离开频道。
我天真的理解是channel#leave
取消订阅服务器事件,并指示通道在服务器上终止
和socket#disconnect
维护通道服务器端,允许重新连接。
因此,我的问题是何时使用一个与另一个。
听起来有2种情况需要考虑:
#leave
会切断他们的连接,而偏向#disconnect
。leave
来维护服务器上的“死”通道,对于长时间运行的进程,这可能是个问题吗?我是否正在正确考虑?如果我们选择只使用#disconnect
滚动,是否应该执行定期清理任务以杀死运行时间较长的“死”信道?
谢谢!
答案 0 :(得分:3)
Phoenix的实时接口基于两个默认的公共抽象,即套接字接口,客户端通过该接口进行连接-这通常是一个websocket(尽管它可以回退到longpolling或使用其他传输方式),这就是“线是在客户端和服务器之间创建的。通常,您通过令牌来中介此连接,以确定客户端是否能够打开该套接字连接。在user_socket.ex
中指定。
然后您具有通道接口,该接口是具有特定句柄(api)的gen_server,该句柄经过定制以通过“线路”接收传入消息。您还可以使用授权逻辑来允许订阅频道(“加入”),并且可以随频道(甚至主题)而变化。
每个客户端可以连接到1个套接字和0到N个通道。连接到其下方的通道的客户端只是简单地(简化了)将给定的套接字注册到发布者订阅者接口(凤凰城的PubSub),并为每个订阅该特定组合的套接字具有用于“通道:房间”的过程。>
如果您从:observer.start
外壳启动iex
,并转到Processes
标签,然后从两个不同的客户端中加入相同的“ channel:topic”,将会看到会有两个渠道流程,而不是一个。如果您从Elixir.YourWeb.PubSub.Local0看到“应用程序”树,您还将看到2个与它“连接”或从其“连接”的进程。
这意味着当您从前端发出channel.leave()
时,服务器会从刚刚“离开”的“通道”中取消订阅此客户端,并且正在处理该客户端的进程将被关闭。通道休假取消了该特定channel:topic
组合的特定套接字(客户端)的订阅。这不会干扰连接到同一主题的其他客户端。在这种情况下,插座(“电线”)仍处于连接状态。您可以重新加入频道,也可以加入其他频道,而无需“询问”(协商)以再次连接到套接字。
另一方面,如果发出socket.disconnect()
,则表示您“拔掉了电线”,因此,该特定套接字(客户端)从先前预订的所有通道中取消订阅。这样可以关闭与给定套接字相关的所有进程,但也不会干扰其他客户端的套接字/连接/订阅。
如果所有客户端都离开一个给定的通道(通过“离开”或“断开”其套接字),您将看到该给定通道将没有任何进程在运行。另一位客户加入该频道后,就会创建该特定客户&channel:topic的过程。
tldr;回答您的问题:
1)否
2)否
但是,如果您从通道本身内部产生了运行时间较长的进程,那么当没有客户端连接到该特定channel:topic时应将其关闭,那么您当然需要确保将其清理干净。除了Erlang的常规监视功能外,Phoenix还具有一个Presence界面,您也可以对其进行跟踪。