PlatformsRuby
Ruby
Implement the Aelio SDK in Ruby using the wire protocol — community guide.
Status: No official Ruby SDK yet. This guide shows how to implement the SDK yourself using the wire protocol. Estimated ~250 lines of Ruby.
Ruby backends (Rails, Sinatra, Rack) can connect to Aelio by implementing the JSON-over-WebSocket wire protocol. Use the Python SDK as the canonical minimal reference.
Install dependencies
gem install faye-websocket
gem install eventmachineStep 1: Connect and register
require 'faye/websocket'
require 'json'
require 'eventmachine'
class AelioSDK
def initialize(secret:, url: 'ws://127.0.0.1:3010')
@secret = secret
@url = url.chomp('/') + '/sdk'
@handlers = {}
@functions = []
end
def expose(name, description:, params:, safety: 'read', &block)
@handlers[name] = block
@functions << {
name: name,
description: description,
params: params,
safety: safety
}
end
def listen
EM.run do
connect
end
end
private
def connect
@ws = Faye::WebSocket::Client.new(@url, [], {
headers: { 'Authorization' => "Bearer #{@secret}" }
})
@ws.on :open do
register
puts 'Aelio SDK connected (Ruby)'
end
@ws.on :message do |event|
handle_message(JSON.parse(event.data))
end
@ws.on :close do
puts 'Disconnected, reconnecting in 5s...'
EM.add_timer(5) { connect }
end
end
def register
@ws.send(JSON.generate({
type: 'register',
functions: @functions,
language: 'ruby',
sdkVersion: '0.1.0'
}))
end
endStep 2: Handle invocations
def handle_message(msg)
case msg['type']
when 'invoke'
id = msg['id']
fn = msg['function']
args = msg['args'] || {}
ctx = msg['context'] || {}
handler = @handlers[fn]
unless handler
send_result(id, ok: false, error: { code: 'FUNCTION_NOT_FOUND', message: fn })
return
end
begin
result = handler.call(args, ctx)
send_result(id, ok: true, data: result)
rescue => e
send_result(id, ok: false, error: { code: 'HANDLER_ERROR', message: e.message })
end
when 'ping'
@ws.send(JSON.generate({ type: 'pong' }))
when 'send'
# Handle outbound delivery (BYO channel)
end
end
def send_result(id, ok:, data: nil, error: nil)
payload = { type: 'result', id: id, ok: ok }
payload[:data] = data if data
payload[:error] = error if error
@ws.send(JSON.generate(payload))
endStep 3: Rails integration
# config/initializers/aelio.rb
require_relative '../../lib/aelio_sdk'
$AELIO = AelioSDK.new(
secret: ENV['AELIO_SDK_SECRET'],
url: ENV.fetch('AELIO_SERVER_URL', 'ws://127.0.0.1:3010')
)
$AELIO.expose('getOrderStatus',
description: 'Get order status',
params: { orderId: 'string' },
safety: 'read'
) do |args, ctx|
order = Order.find_by(id: args['orderId'], user_id: ctx['customerId'])
{ orderId: order.id, status: order.status }
end
# Start in a background thread
Thread.new { $AELIO.listen } if ENV['AELIO_SDK_SECRET']Step 4: Sinatra / Rack
# app.rb
require 'sinatra'
require_relative 'aelio_sdk'
aelio = AelioSDK.new(secret: ENV['AELIO_SDK_SECRET'])
aelio.expose('getOrderStatus', ...) { |args, ctx| ... }
Thread.new { aelio.listen }
get '/health' { { ok: true }.to_json }Step 5: Run
AELIO_SDK_SECRET=change-me-in-production \
AELIO_SERVER_URL=ws://127.0.0.1:3010 \
ruby app.rbProtocol reference
See SDK Wire Protocol for complete message schemas.
| Detail | Value |
|---|---|
| WebSocket path | /sdk |
| Auth | Authorization: Bearer <secret> |
| Register within | 15 seconds of connect |
| Heartbeat | Respond to ping with pong |
| Reconnect | Exponential backoff, max 30s |
Reference implementations
- Python SDK:
sdk/python/sdk.py— ~330 lines, best minimal reference - Protocol types:
packages/protocol/src/index.ts