假设我有一个包含实时数据仪表板的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_state
和presence_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
,因此每个连接的用户都将获得自己的个性化有效负载。