Releases: centrifugal/rubycent
v4.0.0
v4 of this gem targets the current Centrifugo HTTP API (tested against Centrifugo v6) and drops the legacy POST /api JSON-RPC-style protocol the gem used through v3.
Highlights
- Modern Centrifugo HTTP API (per-method endpoints,
X-API-Keyheader). - New client methods:
subscribe,refresh,history_remove,batch. - Richer arguments on existing methods (
publish/broadcastaccepttags,skip_history,idempotency_key,delta,version,version_epoch,b64data;historyacceptslimit,since,reverse;channelsacceptspattern;disconnectacceptsclient/session/whitelist/custom disconnect). - Typed error hierarchy —
Cent::TimeoutError,Cent::NetworkError,Cent::TransportError,Cent::UnauthorizedError,Cent::DecodeError. - Expanded
Cent::Notarycovering every standard and Centrifugo-specific JWT claim. - Supports Faraday 2, JWT 2 and 3, tested against all four combinations.
- Requires Ruby 3.0+.
- Integration test suite exercising a real Centrifugo via Docker.
Changes
Transport
- Now sends requests to per-method paths:
POST /api/publish,POST /api/broadcast, and so on — instead of a singlePOST /apiendpoint with{"method": "...", "params": {...}}body. - Sends the API key as
X-API-Key: <key>per current Centrifugo docs (previouslyAuthorization: apikey <key>). Cent::Client.newgained atimeout:keyword (default10seconds) that sets both open and read timeouts on the Faraday connection. The initializer still yields theFaraday::Connectionfor further customization.
Cent::Client — new methods
subscribe(user:, channel:, ...)— server-side subscribe a user session to a channel.refresh(user:, ...)— refresh a connection (useful for unidirectional transports).history_remove(channel:)— remove all publications from a channel's history.batch(commands:, parallel: nil)— send many commands in one HTTP request; inspect each reply individually for errors. (The batch response is shaped{ "replies" => [...] }with no top-levelresultwrapper.)
Cent::Client — expanded arguments
publish(channel:, data:, skip_history: nil, tags: nil, b64data: nil, idempotency_key: nil, delta: nil, version: nil, version_epoch: nil)broadcast(channels:, data:, skip_history: nil, tags: nil, b64data: nil, idempotency_key: nil, delta: nil, version: nil, version_epoch: nil)disconnect(user:, client: nil, session: nil, whitelist: nil, disconnect: nil)unsubscribe(user:, channel:, client: nil, session: nil)history(channel:, limit: nil, since: nil, reverse: nil)channels(pattern: nil)
Any keyword passed as nil is omitted from the request body.
Cent::Client — return values and error handling
On success every method returns the parsed Centrifugo response body — typically { "result" => { ... } }. If Centrifugo rejects the request with a top-level error, Cent::ResponseError is raised (same class, same code / message attributes as v3) — your existing rescue Cent::ResponseError blocks keep working.
Transport-level problems (network failure, timeout, non-2xx HTTP, bad JSON) raise the new typed errors described below.
batch and broadcast — per-reply errors are not raised
batch and broadcast return an array of independent sub-replies; a single partial failure shouldn't short-circuit the whole response, so their per-reply errors are not turned into exceptions.
batchresponse is{ "replies" => [...] }— note there is no top-levelresultwrapper. Each entry is either{ "<method>" => <result> }or{ "error" => {...} }.broadcastresponse has{ "result" => { "responses" => [...] } }. Each entry inresponsesis either{ "result" => {...} }or{ "error" => {...} }.
Walk the array to check for per-entry errors. Cent::ResponseError is still raised for these calls if Centrifugo rejects the whole request (e.g. malformed top-level body).
response = client.batch(commands: [...])
response['replies'].each_with_index do |reply, i|
warn "command #{i} failed: #{reply['error']['message']}" if reply['error']
endErrors
The error hierarchy has been expanded:
Cent::Error(base,StandardError)Cent::ResponseError— Centrifugo returned a top-level API error. Exposes#codeand#message. Unchanged from v3.Cent::TimeoutError— request timed out.Cent::NetworkError— could not reach Centrifugo.Cent::TransportError— non-2xx HTTP status. Exposes#status.Cent::UnauthorizedError— HTTP 401 (bad API key).
Cent::DecodeError— response body was not valid JSON.
All new errors subclass Cent::Error, so a broad rescue Cent::Error still catches everything.
Cent::Notary
Both token methods now support every standard and Centrifugo-specific JWT claim:
issue_connection_token(sub:, exp: nil, iat: nil, jti: nil, aud: nil, iss: nil, info: nil, b64info: nil, channels: nil, subs: nil, meta: nil, expire_at: nil)issue_channel_token(sub:, channel:, exp: nil, iat: nil, jti: nil, aud: nil, iss: nil, info: nil, b64info: nil, override: nil, expire_at: nil)
The client: keyword that used to be on issue_channel_token is replaced by the standard sub: claim (this was already done in v3 via #24 and is carried forward unchanged).
Dependencies
- Ruby:
>= 3.0(previously>= 2.5).
CI and testing
- GitHub Actions matrix covers the cross product of Faraday 2/3 × JWT 2/3 on Ruby 3.4, plus a
ruby-headexperimental job tracking Ruby 4. - Appraisal-based gemfiles live in
gemfiles/for reproducing any matrix cell locally (bundle exec appraisal rspec). - Integration test suite at
spec/integration/runs against a real Centrifugo instance. Unit tests continue to use WebMock.docker-compose.ymlat the repo root spins up Centrifugo v6.7.1 with history, presence, and the GRPC API enabled for local development.
Migration from v3
-
Upgrade your Centrifugo server to v4 or newer. v4 of this gem speaks the current API and no longer works with pre-v4 Centrifugo.
-
rescue Cent::ResponseErrorkeeps working. No change needed. The class, its#code, and its#messageare preserved from v3. -
Consider switching to more specific transport-error rescues. If you previously rescued
Faraday::ClientErroror a broadCent::Error, you can now target specific classes:Cent::TimeoutError,Cent::NetworkError,Cent::UnauthorizedError,Cent::TransportError,Cent::DecodeError. The broadrescue Cent::Errorstill catches all of them. -
If you use
batchorbroadcast, inspect the reply arrays. Per-reply errors inresponse["replies"](batch) orresponse["result"]["responses"](broadcast) are returned as hash entries with an"error"key — they are not raised. See the README for examples. -
Update
Cent::Notary#issue_channel_tokencalls if you are coming from v2.x: theclient:keyword is nowsub:.# Before (v2.x and earlier) notary.issue_channel_token(client: 'abc', channel: 'c') # After (v3+) notary.issue_channel_token(sub: '42', channel: 'c')
-
Bump your Ruby to 3.0 or newer if you are on 2.x. Ruby 2.7 has been end-of-life since March 2023.
-
No changes required for existing happy-path calls.
client.publish(channel:, data:),broadcast(channels:, data:),presence,presence_stats,history(channel:),channels,info,disconnect(user:),unsubscribe(channel:, user:)all keep their v3 signatures (with optional new kwargs). The response shape ({ "result" => ... }) is unchanged on success.
Thanks
Thanks to @alfonsouc (#27) and @trushkevich (#24) for the groundwork that landed ahead of this release.
- Make channel tokens be compatible with Centrifugo v4+ by @trushkevich in #24
- Faraday and jwt gems dependencies are relaxes by @AlfonsoUceda in #27
New Contributors
- @trushkevich made their first contribution in #24
- @AlfonsoUceda made their first contribution in #27
Full Changelog: v3.0.0...v4.0.0
v3.0.0
v2.2.0
v2.1.0
v2.0.2 - Loosen JWT dependency
~> 2.2 instead of ~> 2.2.1.
Weaken faraday dependency
Require faraday version >1.0.0.
Release Centrifugo V2 compatible client
v2.0.0 Update README.md
Drop support of Ruby 1.9
Dropped support of Ruby 1.9.
Little delegation refactoring.
Broadcast method
Added broadcast method to client to support latest version of Centrifugo
Javascript libs
Added javascript libraries to use with Rails assets