I am currently trying to replace actioncable with a small phoenix app. What I need to do is get information from a redis channel and stream it to an ember client. I have been attempting to use Redis.PuSub and the Phoenix Redis adapter, but haven't been able to fully cover the functionality we currently have.
The current functionality works like this:
Our server receives a request from a user and logs some output to a Redis channel. That channel's name is a combination of a string and a key. The Ember client then makes a request to action-cable with the same key. Action-cable then streams the logged information from the Redis channel with the same name. What I need to know is how to start listening to a Redis channel with a given name when the user makes a request & stream that information continuously to the client. I've managed to get one or the other but not both.
I've been banging my head of this for over a day now so any help at all is massively appreciated.
Cheers
So in order to solve this issue I did the following.
Firstly I setup Redix.PubSub as a dependency as per the docs. Then in the channel I did :
defmodule MyApp.ChannelName do
use Phoenix.Channel
def join(stream_name, _message, socket) do
# Open a link to the redis server
{:ok, pubsub} = Redix.PubSub.start_link()
# Subscribe to the users stream
Redix.PubSub.subscribe(pubsub, stream_name, self())
{:ok, socket}
end
# Avoid throwing an error when a subscribed message enters the channel
def handle_info({:redix_pubsub, redix_pid, :subscribed, _}, socket) do
{:noreply, socket}
end
# Handle the message coming from the Redis PubSub channel
def handle_info({:redix_pubsub, redix_pid, :message, %{channel: channel, payload: message}}, socket) do
# Push the message back to the user
push socket, "#{channel}", %{message: message}
{:noreply, socket}
end
end
In my case I required the user to sign up with a channel with some name e.g. channel_my_api_key
. I would then start listening on the redis channel channel_my_api_key
and stream the information back to the user via the push
function. Note broadcast can be substituted for push.
Credit also to Alex Garibay from the Elixir forums that helped me get to the solution. You can find the thread here.