如何使用phoenix存在设置和检索在线状态(在线/忙/离线)

时间:2017-07-27 12:00:20

标签: elixir phoenix-framework

我希望获得使用凤凰框架编写的小型聊天应用程序的用户状态 状态:在线/离线/忙碌/离开

这是注释的代码段:

defmodule PhoenixChat.Presence do
  @moduledoc """
  Provides presence tracking to channels and processes.

  See the [`Phoenix.Presence`](http://hexdocs.pm/phoenix/Phoenix.Presence.html)
  docs for more details.

  ## Usage

  Presences can be tracked in your channel after joining:

      defmodule PhoenixChat.MyChannel do
        use PhoenixChat.Web, :channel
        alias PhoenixChat.Presence

        def join("some:topic", _params, socket) do
          send(self, :after_join)
          {:ok, assign(socket, :user_id, ...)}
        end

        def handle_info(:after_join, socket) do
          {:ok, _} = Presence.track(socket, socket.assigns.user_id, %{
            online_at: inspect(System.system_time(:seconds))
          })
          push socket, "presence_state", Presence.list(socket)
          {:noreply, socket}
        end
      end

  In the example above, `Presence.track` is used to register this
  channel's process as a presence for the socket's user ID, with
  a map of metadata. Next, the current presence list for
  the socket's topic is pushed to the client as a `"presence_state"` event.

  Finally, a diff of presence join and leave events will be sent to the
  client as they happen in real-time with the "presence_diff" event.
  See `Phoenix.Presence.list/2` for details on the presence datastructure.

  ## Fetching Presence Information

  The `fetch/2` callback is triggered when using `list/1`
  and serves as a mechanism to fetch presence information a single time,
  before broadcasting the information to all channel subscribers.
  This prevents N query problems and gives you a single place to group
  isolated data fetching to extend presence metadata.

  The function receives a topic and map of presences and must return a
  map of data matching the Presence datastructure:

      %{"123" => %{metas: [%{status: "away", phx_ref: ...}],
        "456" => %{metas: [%{status: "online", phx_ref: ...}]}

  The `:metas` key must be kept, but you can extend the map of information
  to include any additional information. For example:

      def fetch(_topic, entries) do
        query =
          from u in User,
            where: u.id in ^Map.keys(entries),
            select: {u.id, u}

        users = query |> Repo.all |> Enum.into(%{})

        for {key, %{metas: metas}} <- entries, into: %{} do
          {key, %{metas: metas, user: users[key]}}
        end
      end

  The function above fetches all users from the database who
  have registered presences for the given topic. The fetched
  information is then extended with a `:user` key of the user's
  information, while maintaining the required `:metas` field from the
  original presence data.
  """
  use Phoenix.Presence, otp_app: :phoenix_chat,
  pubsub_server: PhoenixChat.PubSub
end

我使用此方法获取用户状态PhoenixChat.RoomChannel

def handle_info(:after_join, socket) do
  Presence.track(socket, socket.assigns.user, %{
    online_at: :os.system_time(:millisecond)
  })
  push socket, "presence_state", Presence.list(socket)
    {:noreply, socket}
end

在此细分中 保存用户在线状态

def connect(%{"user" => user, "status" => status}, socket) do
  Redix.command(:redix, ["SET", user, status]) 
  {:ok, assign(socket, :user, user)}
end

我想得到的状态不是时间。 我该怎么做这个任务?

1 个答案:

答案 0 :(得分:0)

您将online_at作为第3个参数的地图传递给Presence.track/3。您可以在其中放置任何其他字段来跟踪状态。请注意,当您想要更改状态时,必须再次致电Presence.track/3