Turbo::Train
Real-time page updates for your Rails app over SSE with Mercure, Fanout Cloud or AnyCable and Hotwire Turbo.
- Uses SSE. No more websockets, client libraries, JS code and handling reconnects. Just an HTTP connection. Let the browser do the work.
-
Seamless Hotwire integration. Use it exactly like ActionCable. Drop-in replacement for
broadcast_action_to
and usual helpers. - Simple. Get running in minutes, scale easily in production 🚀
Before your proceed
Using this gem requires some knowledge of ActionCable and broadcasting turbo streams. Turbo::Train is designed to mimic those, so it is highly recommended to first try the original to understand the concept.
You can start here and proceed with the Turbo Handbook. One of its chapters will be covering Turbo Streams. Specifically this section would be the main prerequisite to understanding what this gem is about: it covers Broadcastable and the overall idea of working with Mercure or Fanout Cloud.
Prerequisites
- Rails 7+
- Mercure server (setup instructions below)
This should also work for Rails 6, but you will also need to install turbo-rails manually before this gem.
Installation
Step 1. Turbo::Train
Instructions for Rails 7+
- Add the turbo-train gem to your Gemfile:
gem 'turbo-train'
- Run
bundle install
- Run
rails turbo_train:install
Instructions for Rails 6
- Install turbo-rails
- Repeat steps for Rails 7 above
Step 2. Server
Mercure
Mercure is installed as a plugin to Caddy server. For mac users everything is pretty easy:
brew install caddy
caddy add-package github.com/dunglas/mercure/caddy
Now you are ready to run 🚀
caddy run
Fanout Cloud
We only support the cloud version today. To use Fanout you must purchase a paid account with a contract for Fastly's services.
Fanout self-hosted (Pushpin)
Coming soon.
AnyCable
anycable-go --host=localhost --port=8080 --sse --broadcast_adapter=http --broadcast_key=test --public_streams --noauth
Coming soon.
Usage
If you are familiar with broadcasting from ActionCable, usage would be extremely familiar:
<%# app/views/chat_messages/index.html.erb %>
<%= turbo_train_from "chat_messages" %>
<div id="append_new_messages_here"></div>
And then you can send portions of HTML from your Rails backend to deliver live to all currently open browsers:
Turbo::Train.broadcast_action_to(
'chat_messages',
action: :append,
target:'append_new_messages_here',
html: '<span>Test!</span>'
)
or in real world you'd probably have something like
# app/models/chat_message.rb
after_create_commit do
Turbo::Train.broadcast_action_to(
'chat_messages',
action: :append,
target: 'append_new_messages_here',
partial: 'somepath/message'
)
end
You have the same options as original Rails Turbo helpers: rendering partials, pure html, same actions.
Configuration
To specify different Mercure or Fanout server settings, please adjust the generated config/initializers/turbo_train.rb
file:
Turbo::Train.configure do |config|
config.skip_ssl_verification = true # Development only; don't do this in production
config.default_server = :fanout # Default value is :mercure
config.server :mercure do |mercure|
mercure.mercure_domain = ...
mercure.publisher_key = ...
mercure.subscriber_key = ...
end
config.server :fanout do |fanout|
fanout.service_url = ...
fanout.service_id = ...
fanout.fastly_key = ...
end
config.server :anycable do |fanout|
ac.anycable_url = 'http://0.0.0.0:8080'
ac.broadcast_key = 'test'
end
end
Mercure
- Your SSE will connect to
https://#{configuration.mercure_domain}/.well-known
. - The publisher/subscriber key correspond to the configuration or your Mercure server.
By default, these are set to localhost
/test
/testing
to match the configuration of the local development server from the installation instructions above.
License
The gem is available as open source under the terms of the MIT License.