railsmechanic

railsmechanic

How to build server sent events with Phoenix?

Hi alchemists!

Currently we’re using server sent events (SSE/Eventsource) to notify client applications (written in Go) about model changes/updates in a web application. Each client application consumes the stream which is provided by Rails and its “Live::SSE” feature. As our company plans to (slowly) migrate existing Rails Apps to Phoenix, we also want to replace this Rails API with Phoenix.

While I’ve found many examples of using Phoenix channels, I haven’t found useful documentations or examples for building the server sent events functionality. Our Rails application currently uses Redis PUB/SUB to communicate model changes/updates. Every time a model changes, an event is published to Redis. This event is then consumed on the Rails side and “transformed” to server sent events and streamed to the connected client applications.

We’re not bound to Redis as an internal message dispatcher. I think Phoenix offers a better approach with using channels internally. The only thing we want to keep is the use of server sent events. How would an implementation for server sent events look with Phoenix? Can you provide some (links with) examples?

Many thanks.

Most Liked

OvermindDL1

OvermindDL1

As far as I’ve seen yet there is no built-in way to do SSE in Phoenix, and as the Phoenix channel API covers that use-case and more via websocket/longpolling, most have not seen a need.

However, there is a good use-case for SSE and it still can be done in Phoenix/Plug.

First, you will want to add the mimetype of "text/event-stream" as an acceptable mimetype at whatever router paths you want.

Second, you will need to send data via normal HTTP chunked encoding if I remember right. I know how to do this in Cowboy, and I know Phoenix/Plug does it via longpolling channels, but I’ve not done it in Phoenix/Plug itself so maybe @josevalim can elaborate on how it is done as a quick googling failed me? ^.^

And the above might not even be necessary if Phoenix Channels already have a built-in way to emulate Server-Side Events, I’ve not checked yet. :slight_smile:

Edit: Just as I send this I find a plug way to send chunked data, apparently it is just the chunk/2 call: A super simple Elixir server for sending Server Sent Events to the browser. · GitHub ^.^

Some kind of one-way channel interface would be a better way if it exists already though. :slight_smile:

hubertlepicki

hubertlepicki

yes, it is doable. Check out the source code for the official phoenix.js client library for reference, here’s direct link to the class/object/whatever responsible for establishing and handling websocket connection:

https://github.com/phoenixframework/phoenix/blob/master/priv/static/phoenix.js#L649

Basically you connect to a websocket by URL and listen to onMessage, where you get a JSON payload to deserialize and interpret. For 1-way connection that could be all you need.

Where Next?

Popular in Questions Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
vac
Hi, I’m quite new in Elixir and I’m trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and I...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 43487 311
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31013 112
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43757 214
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement