rdnChoi
Continuous server to client messaging over channels. Ideas?
I am building a market scanner as a practice app and require a message to be sent to the client every 5 seconds with results from the scanner. I have chosen to do this over channels but have hit a snag. I am unsure with which is the best way to continuously send these messages. The recursive loop I created continues inevitably (until client disconnects) but therefore never returns the socket to Phoenix limiting my ability to manipulate it for other changes (ie: setting changes, etc…). See below for code:
defmodule MyApp.ScannerChannel do
def join...
def handle_in("alert", _args, socket) do
IO.puts("Starting Alert Loop...")
alert_loop(socket)
{:noreply, socket}
end
def alert_loop(%{assigns: %{user_pid: user_pid}} = socket) do
response_map =
MyApp.delta_alert?(socket.assigns[:user_pid])
|> build_trades_map(%{})
|> alert_checker(socket)
updated_socket = assign(socket, :trades_map, response_map)
push(updated_socket, "alert", response_map)
Process.sleep(5_000)
alert_loop(updated_socket)
end
def alert_loop(_socket_no_user_pid), do: nil
This approach limits me significantly and won’t work once I require more interaction with my socket.
Some other options I have thought of are as follows:
-
Send a message from the client requesting the data every 5 seconds. Issue: For multiple reasons, I would prefer to do it on the backend totally if possible. This is my last resort.
-
Process.send_after - Request the data through a delayed message. Issue: Same as my current solution. The socket would be continuously passed back and forth and therefore not be updated.
-
Broadcast/3 - Could just loop a broadcast. Issue: Each user has individual scanner settings and so this wouldn’t work as it would just send out results calculated using default settings.
Does anyone have any other ideas for how I could send a message repeatedly on a set interval?
Thanks.
Marked As Solved
dom
You don’t need a GenServer, just send the message to self() and implement handle_info directly in the channel module. There’s an example of handle_info in the doc: Phoenix.Channel — Phoenix v1.8.8
The message would not include the socket, handle_info’s second argument already provides you the socket.
Also Liked
dom
Process.send_after + implementing the handle_info callback in your channel should work fine, I’m not sure what you mean by “socket would be continuously passed back and forth”?
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









