存在不接听用户请假事件? [英] Presence not picking up user leave events?

查看:82
本文介绍了存在不接听用户请假事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

用户离开频道时,我需要执行一些操作(在大多数情况下,他们会自愿关闭标签页,但可能还会出现连接丢失/超时等情况)

I need to perform some actions when the user leaves a channel (in most cases where they close the tab voluntarily, but there may also be a connection loss/timeout etc.)

根据类似 https://elixirforum.com/t/phoenix-presence-run-some-code-when-user-leaves-the-channel/17739 事件似乎是一种万无一失的方法,因为它还应涵盖连接异常终止的情况.

According to posts like https://elixirforum.com/t/phoenix-presence-run-some-code-when-user-leaves-the-channel/17739 and How to detect if a user left a Phoenix channel due to a network disconnect?, intercepting the "presence_diff" event from Presence seems to be a foolproof way to go, as it should also covers the cases where the connection terminates abnormally.

奇怪的是,presence_diff事件似乎仅在我通过Presence.track跟踪用户时才触发,而在用户离开时则不会触发.

Strangely, the presence_diff event seems to only be triggered when I track the user via Presence.track, but not when the user leaves.

同时,在我的频道中添加terminate(reason, socket)回调可正确捕获请假事件.

Meanwhile, adding a terminate(reason, socket) callback in my channel correctly catches the leave event.

我想知道我的配置有什么问题.还是我不正确理解在线状态的使用?

I wonder what could be wrong in my configuration. Or did I not understand the use of Presence correctly?

示例代码:

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消息采取行动.

OK I think I know what happened: Each "participant:" <> participant_id topic is, as its name suggests, only subscribed to by one participant. Therefore, when that participant quits, the process also dies and nobody is able to act on the presence_diff message.

仍然需要一个单独的过程.可以从该过程中调用MyApp.Endpoint.subscribe来订阅"participant:" <> participant_id主题并根据presence_diff消息采取行动.

A separate process is still needed. One can call MyApp.Endpoint.subscribe from that process to subscribe to the "participant:" <> participant_id topic and act on the presence_diff messages.

或者可以设置一台外接显示器.请参阅如何来检测用户是否由于网络断开而离开了Phoenix频道?

Or one can set up an external monitor. See How to detect if a user left a Phoenix channel due to a network disconnect?

这篇关于存在不接听用户请假事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆