Emit realtime messages and manage sessions from Ruby/Rails to the Symple messaging server via Redis.
Part of the Symple ecosystem:
- symple-server - Node.js messaging server
- symple-client - JavaScript client (browser & Node.js)
The Symple server subscribes to a Redis pub/sub channel for server-side message injection. This client publishes Symple protocol messages to that channel, allowing your Ruby app to push messages directly to connected WebSocket clients without maintaining its own WebSocket connection.
Ruby/Rails --> Redis pub/sub --> Symple Server --> WebSocket Clients
Add to your Gemfile:
gem 'symple-client-ruby', git: 'https://github.com/nilstate/symple-client-ruby'Then bundle install.
Set a global Redis connection:
# config/initializers/symple.rb
Symple.redis = Redis.new(url: ENV['REDIS_URL'])
# Or if you already have a global $redis:
# Symple.redis = $redisSend messages to specific users (by their Symple user ID / room):
emitter = Symple::Emitter.new(
from: current_user.id.to_s,
rooms: recipient_ids.map(&:to_s)
)
# Chat message
emitter.emit(
type: 'message',
data: 'Hello!',
chat_id: chat.id,
sender_id: current_user.id
)
# Event
emitter.emit(
type: 'event',
name: 'chat.typing',
data: { user_id: current_user.id, typing: true }
)Symple::Emitter.new
.from(user.id.to_s)
.to(recipient.id.to_s)
.emit(type: 'message', data: 'Hi!')# Emit a message
Symple.emitter(from: user.id.to_s, rooms: ['42', '99'])
.emit(type: 'event', name: 'refresh', data: { scope: 'contacts' })
# Send presence
Symple.emitter(from: user.id.to_s)
.send_presence(user: user.username, name: user.display_name, online: true)
# Send an event
Symple.emitter(from: user.id.to_s, rooms: ['lobby'])
.send_event('video.ready', { url: video.url })The Symple server authenticates clients by looking up sessions in Redis at symple:session:<token>. Use Symple::Session to manage these from Ruby:
session = Symple::Session.new
# or: session = Symple.session
# Create a session (e.g. after user login)
session.set(api_token.token, {
user_id: user.id,
first_name: user.first_name,
last_name: user.last_name
}, ttl: 1.week.to_i)
# Read
data = session.get(api_token.token)
# Extend TTL
session.touch(api_token.token, ttl: 1.week.to_i)
# Delete on logout
session.delete(api_token.token)class ApiToken < ApplicationRecord
after_save :update_symple_session
after_destroy :remove_symple_session
private
def update_symple_session
Symple.session.set(token, {
user_id: user.id,
first_name: user.first_name,
last_name: user.last_name,
icon_url: user.icon_url
}, ttl: expires_in.to_i)
end
def remove_symple_session
Symple.session.delete(token)
end
end| Key | Purpose |
|---|---|
symple:session:<token> |
Session data (JSON) |
symple:broadcast |
Pub/sub channel for server-side message injection |
- Ruby >= 3.0
redisgem (>= 4.0)- Symple server with Redis enabled (
SYMPLE_REDIS_URL)
MIT