Тиканье часов с использованием каналов Phoenix - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь создать канал Феникса, который содержит только часы, на которые пользователи могут подписаться.

defmodule MyWeb.TimeChannel do
  use Phoenix.Channel
  def join("room:time", _message, socket) do
    schedule_heartbeat()
    {:ok, socket}
  end

  def handle_info(_, socket) do
    broadcast!(socket, "update", %{time: DateTime.utc_now()})
    schedule_heartbeat()
    {:noreply, socket} 
  end

  @heartbeat_ms 1000
  defp schedule_heartbeat, do: Process.send_after(self(), :heartbeat, @heartbeat_ms)

end

Проблема, с которой я сталкиваюсь, заключается в том, что при подключении более одного клиента я планирую несколько тиков в секунду.

Как мне запланировать одно тиканье?

1 Ответ

2 голосов
/ 22 апреля 2020

Я исправил это, создав отдельный GenServer, который отправляет сообщения на канал:

defmodule MarsWeb.TimeServer do
  use GenServer

  def start_link(_) do
    GenServer.start_link(__MODULE__, %{}, name: :time_server )
  end

  def child_spec(arg) do
    %{
      id: __MODULE__,
      start: {__MODULE__, :start_link, [arg]},
      restart: :permanent,
    }
  end

  @impl true
  def init(_) do
    schedule_tick()
    {:ok, %{}}
  end

  @impl true
  def handle_info(:tick, state) do
    MarsWeb.Endpoint.broadcast!("room:time", "update", %{time: DateTime.utc_now()})
    schedule_tick()
    {:noreply, state} 
  end

  @tick_ms 1000
  defp schedule_tick, do: Process.send_after(self(), :tick, @tick_ms)

end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...