Могу ли я выбрать определенные процессы / сокеты, отслеживаемые с помощью Phoenix Presence? - PullRequest
0 голосов
/ 01 декабря 2018

Мой вариант использования заключается в подключении нескольких пользователей к лобби / комнате ожидания, но только два из них будут выбраны из лобби для начала разговора, после чего они должны быть удалены из лобби.Как я могу это реализовать?Обратите внимание, что в этой системе пользователи не зарегистрированы и не имеют имен пользователей.Они должны напрямую входить с веб-страницы.

По-видимому, функции track и untrack также имеют варианты, которые принимают pid в качестве аргумента.Однако я не уверен, как я могу получить pids процессов в первую очередь, когда нужно начать диалог.

Является ли функция self() правильной для использования в этом случае?то есть, возможно, я могу написать

def handle_info(:after_lobby_join, socket) do
  Presence.track(socket, "lobby", %{
    pid: self()
  })

  {:noreply, socket}
end

def handle_info(:start, socket) do
  pid1 = hd(Presence.list(socket)["lobby"][:metas])[:pid]
  # Start the conversation by sending messages individually to pid1 and pid2
  ...
  untrack(pid1, "my_app:lobby", "lobby")
  {:ok, socket}
end

Или я слишком усложняю проблему / неправильно понимаю Присутствие?

Есть также поле phx_ref, но я не могу использоватьэто для этой цели.

Кроме того, по-видимому, я хотел бы только отправить "start_conversation" сообщений двум выбранным пользователям, но не другим в лобби.Я вижу, что функция push отправляет сообщения в назначенный сокет.Но если я отслеживаю pid, можно ли определить соответствующие гнезда из pid?

1 Ответ

0 голосов
/ 06 декабря 2018

Я решил свой первоначальный вопрос, используя отдельные каналы пользователя.Я просто позволю веб-интерфейсу генерировать случайные идентификаторы пользователей.

Решение без использования пользовательских каналов предлагается на форуме Elixir .Хотя он не использует Присутствие.

def handle_info({:new_user, socket}, [{us1, ref1}, {us2, ref2}]) do
  # we had 2 users, a new one joined, so that's 3
  user_sockets = [socket, us1, us2]
  # we can create a room for them now
  create_new_room(user_sockets)
  # and clean the state
  Enum.each([ref1, ref2], fn ref ->
    Process.demonitor(ref)
  end)
  {:noreply, []}
end

def handle_info({:new_user, socket}, waiting_user_sockets) do
  # otherwise just add the new users to the waiting users list
  ref = Process.monitor(socket)
  {:noreply, [{socket, ref} | waiting_user_sockets]}
end

def handle_info({:DOWN, ref, :process, _object, _reason}, waiting_user_sockets) do
  # remove the disconnected socket
end
...