Phoenix Presence:迭代连接的用户以响应事件



假设我有一个包含实时数据仪表板的Phoenix应用程序。

我有一个名为MyApp.DashboardChannel的频道,其主题为dashboard

MyApp.DashboardChannel中,我有一个函数:

def send_update do
  MyApp.Endpoint.broadcast(
    "dashboard",
    "update",
    %{data: MyApp.get_dashboard_data}
  )
end

无论何时发生修改仪表板中显示的数据的事情,我都可以调用此函数以推出更新版本。例如,在MyApp.TransactionController.create中,在保存事务之后,我可以调用DashboardChannel.send_update,以便每个人都可以看到新的事务。

现在,假设我想修改它,以便每个仪表板用户都获得自定义数据。实际上,我想说的是:"对于每个连接的用户,使用他们的user_id运行一个查询,并将结果数据推送给他们。"

我该怎么做?

我很确定答案将涉及Phoenix.Presence。我已经添加了它作为文档显示,并成功地在浏览器中获得presence_statepresence_diff事件。

然而:

  • 在调用send_update时我不能使用Presence.list(socket),因为我从无法访问socket的控制器调用它
  • 当我调用Presence.list(MyApp.DashboardChannel, "dashboard")时,我从GenServer获得** (EXIT) no process。我是不是误解了这个词的用法?

如果您需要向通道上的每个连接的套接字广播不同的数据,我所知道的最好方法是下拉到PubSub:

Phoenix.PubSub.broadcast(
  MyApp.PubSub,
  # Could be any channel ID
  "dashboard",
  # Could be an atom or a tuple with some data attached,
  # of the sort you would pass to a GenServer's `handle_info/2`
  :update
)

然后,在您的通道模块中,您需要一个新的handle_info/2回调来处理该事件。比如:

def handle_info(:update, socket) do
  payload = make_update_payload(socket.assigns.user_id)
  push(socket, "update", payload)
end

由于这里使用的是Phoenix.Channel.push/3而不是broadcast/3,因此每个连接的用户都将获得自己的个性化有效负载。

相关内容

  • 没有找到相关文章

最新更新