首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计数current_visitors和current_users

计数current_visitors和current_users
EN

Stack Overflow用户
提问于 2021-03-06 17:15:54
回答 1查看 313关注 0票数 0

我的菲尼克斯1.5.8 LiveView应用程序使用身份验证进行用户身份验证。

  • 我将当前登录的用户分配给@current_user
  • 我将当前访问者的数量(无论是否登录)分配给@current_visitors_count

现在,我想使用@current_users_count来显示以用户身份登录的访问者数量。但我不知道如何在handle_info中处理这个问题。计算这两个数字的最佳方法是什么?

lib/example_web/live/page_live.ex

代码语言:javascript
复制
defmodule ExampleWeb.PageLive do
  use ExampleWeb, :live_view

  @impl true
  def mount(_params, session, socket) do
    socket =
      socket
      |> assign_current_user(session)
      |> assign_current_visitors_count()

    {:ok, socket}
  end

  @impl true
  def handle_info(
        %{event: "presence_diff", payload: %{joins: joins, leaves: leaves}},
        %{assigns: %{current_visitors_count: count}} = socket
      ) do
    current_visitors_count = count + map_size(joins) - map_size(leaves)

    {:noreply, assign(socket, :current_visitors_count, current_visitors_count)}
  end
end

lib/example_web/live/live_helpers.ex

代码语言:javascript
复制
defmodule ExampleWeb.LiveHelpers do
  import Phoenix.LiveView

  alias Example.Accounts
  alias Example.Presence

  def assign_current_user(socket, session) do
    assign_new(
      socket,
      :current_user,
      fn ->
        case session["user_token"] do
          nil -> nil
          user_token -> Accounts.get_user_by_session_token(user_token)
        end
      end
    )
  end

  def assign_current_visitors_count(socket) do
    topic = "current_visitors"
    initial_count = Presence.list(topic) |> map_size

    ExampleWeb.Endpoint.subscribe(topic)

    Presence.track(
      self(),
      topic,
      socket.id,
      %{}
    )

    assign(socket, :current_visitors_count, initial_count)
  end
end
EN

回答 1

Stack Overflow用户

发布于 2021-03-08 15:11:31

lib/example_web/live/page_live.ex

代码语言:javascript
复制
defmodule ExampleWeb.PageLive do
  use ExampleWeb, :live_view

  alias Example.Presence
  alias Example.Accounts
  alias Phoenix.Socket.Broadcast

  @impl true
  def mount(_params, session, socket) do
    current_user = get_current_user(session)

    [chat_user_id, user_status] =
      case current_user do
        nil -> [UUID.uuid4(), "guest"]
        user -> [user.id, "user"]
      end

    Phoenix.PubSub.subscribe(Example.PubSub, "room:lobby")
    {:ok, _} = Presence.track(self(), "room:lobby", chat_user_id, %{status: user_status})

    socket =
      socket
      |> assign_user_count()
      |> assign(:current_user, current_user)
      |> assign(:chat_user_id, chat_user_id)
      |> assign(:current_users_count, 0)
      |> assign(:guests_count, 0)

    {:ok, socket}
  end

  @impl true
  def handle_info(%Broadcast{event: "presence_diff"}, socket) do
    socket =
      socket
      |> assign(:current_users_count, length(current_user_ids(socket)))
      |> assign(:guests_count, length(current_guests_ids(socket)))

    {:noreply, socket}
  end

  defp current_user_ids(socket) do
    Presence.list("room:lobby")
    |> Enum.filter(fn {id, x} -> hd(x.metas).status == "user" end)
    |> Enum.map(fn {k, _} -> k end)
  end

  defp current_guests_ids(socket) do
    Presence.list("room:lobby")
    |> Enum.filter(fn {id, x} -> hd(x.metas).status == "guest" end)
    |> Enum.map(fn {k, _} -> k end)
  end
end

lib/example_web/live/live_helpers.ex

代码语言:javascript
复制
defmodule ExampleWeb.LiveHelpers do
  import Phoenix.LiveView

  alias Example.Accounts
  alias Example.Repo
  alias Example.Presence
  import Ecto.Query, only: [from: 2]

  def get_current_user(session) do
    case session["user_token"] do
      nil -> nil
      user_token -> Accounts.get_user_by_session_token(user_token)
    end
  end

end
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66508466

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档