【问题标题】:How to exclude some users when broadcast?广播时如何排除部分用户?
【发布时间】:2016-09-13 18:28:01
【问题描述】:

由于broadcast! 将向所有订阅主题的用户发送消息,除了发件人,是否可以排除某些用户?还是发送给特定用户?

我需要用户将事件推送到频道,但只有管理员用户会收到消息,其他用户不会收到消息,而只会发送消息。

我可以在客户端解决这个问题,只需让用户忽略他们通过broadcast! 收到的消息,并且只有管理员用户处理收到的消息,但是如何在服务器端解决这个问题?

简而言之,加入一个频道,但只能读取,还是只能发送?

【问题讨论】:

    标签: phoenix-framework


    【解决方案1】:

    如果您按照https://hexdocs.pm/phoenix/Phoenix.Token.html 中的说明将用户存储在套接字上

    defmodule MyApp.UserSocket do
      use Phoenix.Socket
    
      def connect(%{"token" => token}, socket) do
        case Phoenix.Token.verify(socket, "user", token, max_age: 1209600) do
          {:ok, user_id} ->
            socket = assign(socket, :user, Repo.get!(User, user_id))
            {:ok, socket}
          {:error, _} -> #...
        end
      end
    end
    

    然后您可以在您的频道documented herehandle_out 函数中检查用户管理员状态:

    defmodule HelloPhoenix.RoomChannel do
      intercept ["new_msg"]
      ...
      def handle_out("new_msg", payload, socket) do
        if socket.assigns.user.admin do
          push socket, "new_msg", payload
        end
        {:noreply, socket}
      end
    end
    

    根据您的消息量和管理员数量,您可以考虑为这些事件设置一个特定于管理员的频道。这将防止消息被发送到非管理员用户的进程,而不是简单地忽略它们。

    【讨论】:

    • 即使我为 admin 指定了一个频道,其他用户也会加入它来向 admin 发送消息,然后我将不得不忽略 handle_out 的非 admin 用户.. 所以它是一样的.. 对?
    • 您可以拥有一个只有管理员才能加入的频道。无论消息是如何发送的,都可以广播消息。因此,您将保留现有频道,然后使用 MyApp.Endpoint.broadcast 从那里广播到管理员频道。 hexdocs.pm/phoenix/Phoenix.Endpoint.html
    • 谢谢,这正是我需要的,在没有套接字上下文的情况下推送消息。
    • 你为什么不在你的答案中使用handle_in?相反,你使用了handle_out,为什么?
    • handle_in 用于发送到频道的消息。 handle_out 为每个连接的客户端调用,允许您忽略消息。您仍然可以使用handle_in 来接收消息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    相关资源
    最近更新 更多