如何让 Phoenix 在客户端连接时自动加入频道?

How can I get Phoenix to join channels automatically when a client connects?

我在 Phoenix Channels 中使用 websocket 传输,但我试图为没有 Phoenix.Socket 客户端的消费者提供一个干净的 API 来仅使用 websockets。

为简单起见,我想在用户打开会话时自动订阅各种频道。

目前我有类似的东西:

defmodule MyWeb.UserSocket do
  require Logger
  use Phoenix.Socket
  alias Exchange.{Account, ApiKey}

  channel "room:time", MyWeb.TimeChannel
  channel "alpha:*", MyWeb.AlphaChannel
  channel "beta:*", MyWeb.BetaChannel

  def connect(%{"api-key" => _} = params, socket, connect_info) do
    with %{"api-key" => api_key, "api-expires" => api_expires, "api-signature" => api_signature} <-
           params,
         {:ok, %ApiKey{} = key} <- ApiKey.fetch(api_key),
         {:ok, %Account{} = account} <-ApiKey.authorize(...)) do
      Logger.info("Authorized account #{account.account_id} via API key on websocket")

      #JOIN CHANNELS HERE

      {:ok, assign(socket, :account, account)}
    else
      {:error, e} ->
        Logger.error("Websocket auth error #{inspect(e)}")
        {:ok, socket}
    end
  end

end

我需要在“在此加入频道”中输入什么才能订阅?

这可能太简单了,但是你试过了吗

Phoenix.PubSub.subscribe(MyApp.PubSub, "topic")

?

文档 - https://hexdocs.pm/phoenix_pubsub/Phoenix.PubSub.html

这个问题的答案不是在界面上使用 Phoenix Channels,而是编写一个单独的 Transport 订阅 Phoenix 的实现。

我通过定义一个新模块创建了一个新的套接字传输:

@behaviour Phoenix.Socket.Transport

并提供了袜子 endpoint.ex:

socket "/realtime", MyWeb.MyCustomSocket, websocket: true

此模式遵循 GenServer 类型布局。我在 init 订阅了我想要的凤凰频道,然后将这些事件重新发送到套接字。

这创建了一种单向网络套接字,不需要任何 Socket 知识即可连接和收听。