turbo-replay assigns a sequence number to broadcasted messages and caches them. When a client reconnects after losing their network connectivity, the server re-sends (or replays, hence the name) missed messages in the same order they were originally sent.
▶️ If you're into videos, I have recorded a screencast showcasing this library: https://www.youtube.com/watch?v=alBat4DWbdI▶️
Important: Make sure you have hotwired/turbo-rails
installed before using this gem!
- Add this line to your application's Gemfile:
gem "turbo-replay"
- Run the following commands to install the gem and generate the initializer:
$ bin/bundle install
$ bin/rails turbo-replay:install
- Replace the import for
@hotwired/turbo-rails
in your application.js
- import "@hotwired/turbo-rails"
+ import "turbo-replay"
- Reload your server - and that's it!
// The user connected for the first time to a channel.
window.addEventListener('turbo-replay:connected', (ev) => {
console.log('connected', ev.detail.channel)
})
// The user disconnected from a channel and we're retrying to reconnect.
// It's good to show a visual 'reconnecting...' indication somewhere in your app.
window.addEventListener('turbo-replay:disconnected', (ev) => {
console.log('disconnected', ev.detail.channel)
})
// The user reconnected after being offline a little bit.
// Hide the visual 'reconnecting...' indication here.
window.addEventListener('turbo-replay:reconnected', (ev) => {
console.log('reconnected', ev.detail.channel)
})
// The user reconnected, but the latest received message was older
// than the oldest message in the cache. There's nothing we can do
// to recover the state here.
window.addEventListener('turbo-replay:unrecoverable', (ev) => {
console.log('unrecoverable', ev.detail.channel)
})
turbo-replay stores broadcasted messages in a cache. Each message is assigned a sequence number.
Because the sequence number is sequential, clients know what the next value is expected to be.
If an arrived sequence_number
doesn't match the expected value, it means the client missed a message.
When the client notices they missed an event, either by an unexpected sequence number or disconnect event, they ask the server to resend messages since the last known sequence number.
Maybe, it depends on your use case. Take a look at config/initializers/turbo_replay.rb
in your
application to tweak the cache's retention policy.
There's nothing we can do if the client's latest received message is older than the oldest message in the cache.
That said, you should handle the turbo-replay:unrecoverable
event and display a message asking the user
to reload the app. For example:
window.addEventListener('turbo-replay:unrecoverable', () => {
window.alert("You're offline for too long. Please reload the page.")
})
The gem is available as open source under the terms of the MIT License.