【问题标题】:Phoenix websocket socket.disconnect() vs. channel.leave()Phoenix websocket socket.disconnect() 与 channel.leave()
【发布时间】:2023-04-05 11:49:01
【问题描述】:

我正在阅读phoenix docs 关于断开套接字或离开频道的方法。

我的幼稚理解是channel#leave

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

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

所以,我的问题是何时使用一个与另一个。

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

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

我是否正确地考虑了这一点?如果我们选择使用#disconnect-only 滚动,我们是否应该执行定期清理任务来杀死长时间运行的“死”通道?

谢谢!

【问题讨论】:

    标签: websocket elixir phoenix-framework


    【解决方案1】:

    Phoenix 的实时接口建立在两个默认的公共抽象之上,一个套接字接口,客户端通过它连接 - 这通常是一个 websocket(尽管它可以回退到长轮询或使用其他传输),这是“线" 在客户端和您的服务器之间创建。通常,您通过令牌调解此连接,以决定客户端是否能够打开该套接字连接。它在user_socket.ex 中指定。

    然后你就有了通道接口,它是一个带有特定句柄 (api) 的 gen_server,用于通过“电线”接收传入的消息。您还可以拥有允许订阅频道(“加入”)的授权逻辑,并且它可能因频道(甚至主题)而异。

    每个客户端可以连接到 1 个套接字和 0 到 N 个通道。在下面,连接到通道的客户端只是(简化)将给定的套接字注册到发布者订阅者接口(Phoenix 的 PubSub),并为订阅该特定组合的每个套接字拥有一个处理这些“通道:房间”的过程。

    如果您从iex shell 启动:observer.start,然后转到Processes 选项卡,然后从两个不同的客户端加入完全相同的“频道:主题”,您将看到两个渠道进程,不是一个。如果您从 Elixir.YourWeb.PubSub.Local0 看到应用程序树,您还会看到 2 个进程“连接”到/从它。

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

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

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

    tldr;回答你的问题:

    • 1) 没有

    • 2) 没有

    但是,如果您有长时间运行的进程,这些进程是从频道本身产生的,那么当没有客户端连接到该特定频道:主题时,应该关闭该进程,那么您当然需要确保清理它们。除了 Erlang 的常规监控功能外,Phoenix 还有一个 Presence 界面,让您也可以对其进行跟踪。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多