README.md
[![Code Climate](https://codeclimate.com/github/centrifugal/centrifuge-ruby/badges/gpa.svg)](https://codeclimate.com/github/centrifugal/centrifuge-ruby)
![Build Status](https://github.com/centrifugal/rubycent/actions/workflows/main.yml/badge.svg)
[Centrifugo HTTP API](https://centrifugal.dev/docs/server/server_api) client in Ruby.
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'cent'
```
And then execute:
$ bundle
Or install it yourself as:
$ gem install cent
## Usage
Functionality is split between two classes:
- `Cent::Client` to call API methods
- `Cent::Notary` to generate tokens
### Token Generation
```ruby
notary = Cent::Notary.new(secret: 'secret')
```
By default it uses HS256 to generate tokens, but you can set it to one of the HMAC, RSA or ECDSA family.
#### RSA
```ruby
secret = OpenSSL::PKey::RSA.new(File.read('./rsa_secret.pem'))
notary = Cent::Notary.new(secret: secret, algorithm: 'RS256')
```
#### ECDSA
```ruby
secret = OpenSSL::PKey::EC.new(File.read('./ecdsa_secret.pem'))
notary = Cent::Notary.new(secret: secret, algorithm: 'ES256')
```
#### Connection token
When connecting to Centrifugo client [must provide connection JWT token](https://centrifugal.github.io/centrifugo/server/authentication/) with several predefined credential claims.
```ruby
notary.issue_connection_token(sub: '42')
#=> "eyJhbGciOiJIUzI1NiJ9..."
```
`info` and `exp` are supported as well:
```ruby
notary.issue_connection_token(sub: '42', info: { scope: 'admin' }, exp: 1629050099)
#=> "eyJhbGciOiJIUzI1NiJ9..."
```
### Private channel token
All channels starting with $ considered private and require a **channel token** to subscribe.
Private channel subscription token is also JWT([see the claims](https://centrifugal.github.io/centrifugo/server/private_channels/))
```ruby
notary.issue_channel_token(client: 'client', channel: 'channel', exp: 1629050099, info: { scope: 'admin' })
#=> "eyJhbGciOiJIUzI1NiJ9..."
```
### API Client
A client requires your Centrifugo API key to execute all requests.
```ruby
client = Cent::Client.new(api_key: 'key')
```
you can customize your connection as you wish, just remember it's a [Faraday::Connection](https://lostisland.github.io/faraday/usage/#customizing-faradayconnection) instance:
```ruby
client = Cent::Client.new(api_key: 'key', endpoint: 'https://centrifu.go/api') do |connection|
connection.headers['User-Agent'] = 'Centrifugo Ruby Client'
connection.options.open_timeout = 3
connection.options.timeout = 7
connection.adapter :typhoeus
end
```
#### Publish
Send data to the channel.
[publish](https://centrifugal.dev/docs/server/server_api#publish)
```ruby
client.publish(channel: 'chat', data: 'hello') # => {}
```
#### Broadcast
Sends data to multiple channels.
[broadcast](https://centrifugal.dev/docs/server/server_api#broadcast)
```ruby
client.broadcast(channels: ["clients", "staff"], data: 'hello') # => {}
```
#### Unsubscribe
Unsubscribe user from channel. Receives to arguments: channel and user (user ID you want to unsubscribe)
[unsubscribe](https://centrifugal.dev/docs/server/server_api#unsubscribe)
```ruby
client.unsubscribe(channel: 'chat', user: '1') # => {}
```
#### Disconnect
Allows to disconnect user by it's ID. Receives user ID as an argument.
[disconnect](https://centrifugal.dev/docs/server/server_api#disconnect)
```ruby
# Disconnect user with `id = 1`
#
client.disconnect(user: '1') # => {}
```
#### Presence
Get channel presence information(all clients currently subscribed on this channel).
[presence](https://centrifugal.dev/docs/server/server_api#presence)
```ruby
client.presence(channel: 'chat')
# {
# 'result' => {
# 'presence' => {
# 'c54313b2-0442-499a-a70c-051f8588020f' => {
# 'client' => 'c54313b2-0442-499a-a70c-051f8588020f',
# 'user' => '42'
# },
# 'adad13b1-0442-499a-a70c-051f858802da' => {
# 'client' => 'adad13b1-0442-499a-a70c-051f858802da',
# 'user' => '42'
# }
# }
# }
# }
```
#### Presence stats
Get short channel presence information.
[presence_stats](https://centrifugal.dev/docs/server/server_api#presence_stats)
```ruby
client.presence_stats(channel: 'chat')
# {
# "result" => {
# "num_clients" => 0,
# "num_users" => 0
# }
# }
```
#### History
Get channel history information (list of last messages published into channel).
[history](https://centrifugal.dev/docs/server/server_api#history)
```ruby
client.history(channel: 'chat')
# {
# 'result' => {
# 'publications' => [
# {
# 'data' => {
# 'text' => 'hello'
# }
# },
# {
# 'data' => {
# 'text' => 'hi!'
# }
# }
# ]
# }
# }
```
#### Channels
Get list of active(with one or more subscribers) channels.
[channels](https://centrifugal.dev/docs/server/server_api#channels)
```ruby
client.channels
# {
# 'result' => {
# 'channels' => [
# 'chat'
# ]
# }
# }
```
#### Info
Get running Centrifugo nodes information.
[info](https://centrifugal.dev/docs/server/server_api#info)
```ruby
client.info
# {
# 'result' => {
# 'nodes' => [
# {
# 'name' => 'Alexanders-MacBook-Pro.local_8000',
# 'num_channels' => 0,
# 'num_clients' => 0,
# 'num_users' => 0,
# 'uid' => 'f844a2ed-5edf-4815-b83c-271974003db9',
# 'uptime' => 0,
# 'version' => ''
# }
# ]
# }
# }
```
### Errors
Network errors are not wrapped and will raise `Faraday::ClientError`.
In cases when Centrifugo returns 200 with `error` key in the body we wrap it and return custom error:
```ruby
# Raised when response from Centrifugo contains any error as result of API command execution.
#
begin
client.publish(channel: 'channel', data: { foo: :bar })
rescue Cent::ResponseError => ex
ex.message # => "Invalid format"
end
```
## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/centrifugal/rubycent. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
## License
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).