Presence 没有接听用户离开事件?
Presence not picking up user leave events?
我需要在用户离开频道时执行一些操作(大多数情况下他们是自愿关闭标签页,但也可能存在连接loss/timeout等)
根据 https://elixirforum.com/t/phoenix-presence-run-some-code-when-user-leaves-the-channel/17739 and 之类的帖子,拦截来自 Presence
的 "presence_diff"
事件似乎是一种万无一失的方法,因为它还应该涵盖连接异常终止的情况.
奇怪的是,presence_diff
事件似乎只在我通过Presence.track
跟踪用户时触发,而不是在用户离开时触发。
同时,在我的频道中添加 terminate(reason, socket)
回调可以正确捕获离开事件。
我想知道我的配置有什么问题。还是我没有正确理解 Presence 的用法?
示例代码:
def join("participant:" <> participant_id, _payload, socket) do
if socket.assigns.participant_id == participant_id do
send(self(), :after_participant_join)
{:ok, socket}
else
{:error, %{reason: "unauthorized"}}
end
end
def handle_info(:after_participant_join, socket) do
experiment_id = socket.assigns.experiment_id
Presence.track(socket, experiment_id, %{
# keys to track
})
# Broadcast something
# broadcast(socket, ...)
{:noreply, socket}
end
intercept(["presence_diff"])
def handle_out("presence_diff", payload, socket) do
# Only gets triggered at Presence.track, but not when the connection is closed.
IO.puts("presence_diff triggered, payload is #{inspect(payload)}")
leaves = payload.leaves
for {experiment_id, meta} <- leaves do
IO.puts("Leave information: #{meta}")
# Do stuffs
end
end
# This works, however.
def terminate(reason, socket) do
IO.puts("terminated. #{inspect(reason)}")
# Do stuffs.
end
好的,我想我知道发生了什么:正如其名称所示,每个 "participant:" <> participant_id
主题仅由一名参与者订阅。因此,当该参与者退出时,该进程也会终止,并且没有人能够对 presence_diff
消息采取行动。
仍然需要一个单独的过程。可以从该进程调用 MyApp.Endpoint.subscribe
以订阅 "participant:" <> participant_id
主题并对 presence_diff
消息采取行动。
或者可以设置外接显示器。参见
我需要在用户离开频道时执行一些操作(大多数情况下他们是自愿关闭标签页,但也可能存在连接loss/timeout等)
根据 https://elixirforum.com/t/phoenix-presence-run-some-code-when-user-leaves-the-channel/17739 and Presence
的 "presence_diff"
事件似乎是一种万无一失的方法,因为它还应该涵盖连接异常终止的情况.
奇怪的是,presence_diff
事件似乎只在我通过Presence.track
跟踪用户时触发,而不是在用户离开时触发。
同时,在我的频道中添加 terminate(reason, socket)
回调可以正确捕获离开事件。
我想知道我的配置有什么问题。还是我没有正确理解 Presence 的用法?
示例代码:
def join("participant:" <> participant_id, _payload, socket) do
if socket.assigns.participant_id == participant_id do
send(self(), :after_participant_join)
{:ok, socket}
else
{:error, %{reason: "unauthorized"}}
end
end
def handle_info(:after_participant_join, socket) do
experiment_id = socket.assigns.experiment_id
Presence.track(socket, experiment_id, %{
# keys to track
})
# Broadcast something
# broadcast(socket, ...)
{:noreply, socket}
end
intercept(["presence_diff"])
def handle_out("presence_diff", payload, socket) do
# Only gets triggered at Presence.track, but not when the connection is closed.
IO.puts("presence_diff triggered, payload is #{inspect(payload)}")
leaves = payload.leaves
for {experiment_id, meta} <- leaves do
IO.puts("Leave information: #{meta}")
# Do stuffs
end
end
# This works, however.
def terminate(reason, socket) do
IO.puts("terminated. #{inspect(reason)}")
# Do stuffs.
end
好的,我想我知道发生了什么:正如其名称所示,每个 "participant:" <> participant_id
主题仅由一名参与者订阅。因此,当该参与者退出时,该进程也会终止,并且没有人能够对 presence_diff
消息采取行动。
仍然需要一个单独的过程。可以从该进程调用 MyApp.Endpoint.subscribe
以订阅 "participant:" <> participant_id
主题并对 presence_diff
消息采取行动。
或者可以设置外接显示器。参见