Class: Ably::Realtime::Client

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Modules::AsyncWrapper
Defined in:
lib/ably/realtime/client.rb,
lib/ably/realtime/client/incoming_message_dispatcher.rb,
lib/ably/realtime/client/outgoing_message_dispatcher.rb

Overview

Client for the Ably Realtime API

Defined Under Namespace

Classes: IncomingMessageDispatcher, OutgoingMessageDispatcher

Constant Summary collapse

DOMAIN =
'realtime.ably.io'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ Ably::Realtime::Client

Creates a Realtime Client and configures the Auth object for the connection.

Examples:

# create a new client authenticating with basic auth
client = Ably::Realtime::Client.new('key.id:secret')

# create a new client and configure a client ID used for presence
client = Ably::Realtime::Client.new(key: 'key.id:secret', client_id: 'john')

Options Hash (options):

  • :queue_messages (Boolean)

    If false, this disables the default behaviour whereby the library queues messages on a connection in the disconnected or connecting states

  • :echo_messages (Boolean)

    If false, prevents messages originating from this connection being echoed back on the same connection

  • :recover (String)

    When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery

  • :auto_connect (Boolean)

    By default as soon as the client library is instantiated it will connect to Ably. You can optionally set this to false and explicitly connect.

  • :tls (Boolean)

    TLS is used by default, providing a value of false disables TLS. Please note Basic Auth is disallowed without TLS as secrets cannot be transmitted over unsecured connections.

  • :key (String)

    API key comprising the key name and key secret in a single string

  • :token (String)

    Token string or Models::TokenDetails used to authenticate requests

  • :token_details (String)

    Models::TokenDetails used to authenticate requests

  • :use_token_auth (Boolean)

    Will force Basic Auth if set to false, and Token auth if set to true

  • :environment (String)

    Specify ‘sandbox’ when testing the client library against an alternate Ably environment

  • :protocol (Symbol)

    Protocol used to communicate with Ably, :json and :msgpack currently supported. Defaults to :msgpack

  • :use_binary_protocol (Boolean)

    Protocol used to communicate with Ably, defaults to true and uses MessagePack protocol. This option will overide :protocol option

  • :log_level (Logger::Severity, Symbol)

    Log level for the standard Logger that outputs to STDOUT. Defaults to Logger::ERROR, can be set to :fatal (Logger::FATAL), :error (Logger::ERROR), :warn (Logger::WARN), :info (Logger::INFO), :debug (Logger::DEBUG) or :none

  • :logger (Logger)

    A custom logger can be used however it must adhere to the Ruby Logger interface, see www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html

  • :key (String)

    API key comprising the key name and key secret in a single string

  • :force (Boolean)

    obtains a new token even if the current token is valid

  • :key (String)

    complete API key for the designated application

  • :client_id (String)

    client ID identifying this connection to other clients (defaults to client client_id if configured)

  • :auth_url (String)

    a URL to be used to GET or POST a set of token request params, to obtain a signed token request.

  • :auth_headers (Hash)

    a set of application-specific headers to be added to any request made to the authUrl

  • :auth_params (Hash)

    a set of application-specific query params to be added to any request made to the authUrl

  • :auth_method (Symbol)

    HTTP method to use with auth_url, must be either :get or :post (defaults to :get)

  • :auth_callback (Proc)

    this Proc / block will be called with the Auth#auth_options Hash as the first argument whenever a new token is required. The Proc should return a token string, Models::TokenDetails or JSON equivalent, Models::TokenRequest or JSON equivalent

  • :ttl (Integer)

    validity time in seconds for the requested Models::TokenDetails. Limits may apply, see https://www.ably.io/documentation/other/authentication

  • :capability (Hash)

    canonicalised representation of the resource paths and associated operations

  • :query_time (Boolean)

    when true will query the Ably system for the current time instead of using the local time

  • :timestamp (Time)

    the time of the of the request

  • :nonce (String)

    an unquoted, unescaped random string of at least 16 characters

Raises:

  • (ArgumentError)


76
77
78
79
80
81
82
83
84
85
86
# File 'lib/ably/realtime/client.rb', line 76

def initialize(options)
  @rest_client           = Ably::Rest::Client.new(options)
  @auth                  = @rest_client.auth
  @channels              = Ably::Realtime::Channels.new(self)
  @echo_messages         = @rest_client.options.fetch(:echo_messages, true) == false ? false : true
  @custom_realtime_host  = @rest_client.options[:realtime_host] || @rest_client.options[:ws_host]
  @auto_connect          = @rest_client.options.fetch(:auto_connect, true) == false ? false : true
  @recover               = @rest_client.options[:recover]

  raise ArgumentError, "Recovery key is invalid" if @recover && !@recover.match(Connection::RECOVER_REGEX)
end

Instance Attribute Details

#authAbly::Auth (readonly)

Auth authentication object configured for this connection



31
32
33
# File 'lib/ably/realtime/client.rb', line 31

def auth
  @auth
end

#auth_optionsHash (readonly)



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/ably/realtime/client.rb', line 20

class Client
  include Ably::Modules::AsyncWrapper
  extend Forwardable

  DOMAIN = 'realtime.ably.io'

  # The collection of {Ably::Realtime::Channel}s that have been created
  # @return [Aby::Realtime::Channels]
  attr_reader :channels

  # (see Ably::Rest::Client#auth)
  attr_reader :auth

  # The {Ably::Rest::Client REST client} instantiated with the same credentials and configuration that is used for all REST operations such as authentication
  # @return [Ably::Rest::Client]
  attr_reader :rest_client

  # When false the client suppresses messages originating from this connection being echoed back on the same connection.  Defaults to true
  # @return [Boolean]
  attr_reader :echo_messages

  # The custom realtime websocket host that is being used if it was provided with the option `:ws_host` when the {Client} was created
  # @return [String,Nil]
  attr_reader :custom_realtime_host

  # When true, as soon as the client library is instantiated it will connect to Ably.  If this attribute is false, a connection must be opened explicitly
  # @return [Boolean]
  attr_reader :auto_connect

  # When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @return [String,Nil]
  attr_reader :recover

  def_delegators :auth, :client_id, :auth_options
  def_delegators :@rest_client, :encoders
  def_delegators :@rest_client, :environment, :use_tls?, :protocol, :protocol_binary?, :custom_host
  def_delegators :@rest_client, :log_level

  # Creates a {Ably::Realtime::Client Realtime Client} and configures the {Ably::Auth} object for the connection.
  #
  # @param (see Ably::Rest::Client#initialize)
  # @option options (see Ably::Rest::Client#initialize)
  # @option options [Boolean] :queue_messages If false, this disables the default behaviour whereby the library queues messages on a connection in the disconnected or connecting states
  # @option options [Boolean] :echo_messages  If false, prevents messages originating from this connection being echoed back on the same connection
  # @option options [String]  :recover        When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @option options [Boolean] :auto_connect   By default as soon as the client library is instantiated it will connect to Ably. You can optionally set this to false and explicitly connect.
  #
  # @return [Ably::Realtime::Client]
  #
  # @example
  #    # create a new client authenticating with basic auth
  #    client = Ably::Realtime::Client.new('key.id:secret')
  #
  #    # create a new client and configure a client ID used for presence
  #    client = Ably::Realtime::Client.new(key: 'key.id:secret', client_id: 'john')
  #
  def initialize(options)
    @rest_client           = Ably::Rest::Client.new(options)
    @auth                  = @rest_client.auth
    @channels              = Ably::Realtime::Channels.new(self)
    @echo_messages         = @rest_client.options.fetch(:echo_messages, true) == false ? false : true
    @custom_realtime_host  = @rest_client.options[:realtime_host] || @rest_client.options[:ws_host]
    @auto_connect          = @rest_client.options.fetch(:auto_connect, true) == false ? false : true
    @recover               = @rest_client.options[:recover]

    raise ArgumentError, "Recovery key is invalid" if @recover && !@recover.match(Connection::RECOVER_REGEX)
  end

  # Return a {Ably::Realtime::Channel Realtime Channel} for the given name
  #
  # @param (see Ably::Realtime::Channels#get)
  # @return (see Ably::Realtime::Channels#get)
  #
  def channel(name, channel_options = {})
    channels.get(name, channel_options)
  end

  # Retrieve the Ably service time
  #
  # @yield [Time] The time as reported by the Ably service
  # @return [Ably::Util::SafeDeferrable]
  #
  def time(&success_callback)
    async_wrap(success_callback) do
      rest_client.time
    end
  end

  # Retrieve the stats for the application
  #
  # @param (see Ably::Rest::Client#stats)
  # @option options (see Ably::Rest::Client#stats)
  #
  # @yield [Ably::Models::PaginatedResult<Ably::Models::Stats>] An Array of Stats
  #
  # @return [Ably::Util::SafeDeferrable]
  #
  def stats(options = {}, &success_callback)
    async_wrap(success_callback) do
      rest_client.stats(options)
    end
  end

  # (see Ably::Realtime::Connection#close)
  def close(&block)
    connection.close(&block)
  end

  # (see Ably::Realtime::Connection#connect)
  def connect(&block)
    connection.connect(&block)
  end

  # @!attribute [r] endpoint
  # @return [URI::Generic] Default Ably Realtime endpoint used for all requests
  def endpoint
    endpoint_for_host(custom_realtime_host || [environment, DOMAIN].compact.join('-'))
  end

  # @!attribute [r] connection
  # @return [Aby::Realtime::Connection] The underlying connection for this client
  def connection
    @connection ||= Connection.new(self)
  end

  # (see Ably::Rest::Client#register_encoder)
  def register_encoder(encoder)
    rest_client.register_encoder encoder
  end

  # (see Ably::Rest::Client#logger)
  def logger
    @logger ||= Ably::Logger.new(self, log_level, rest_client.logger.custom_logger)
  end

  # Disable connection recovery, typically used after a connection has been recovered
  # @return [void]
  # @api private
  def disable_automatic_connection_recovery
    @recover = nil
  end

  # @!attribute [r] fallback_endpoint
  # @return [URI::Generic] Fallback endpoint used to connect to the realtime Ably service. Note, after each connection attempt, a new random {Ably::FALLBACK_HOSTS fallback host} is used
  # @api private
  def fallback_endpoint
    unless @fallback_endpoints
      @fallback_endpoints = Ably::FALLBACK_HOSTS.shuffle.map { |fallback_host| endpoint_for_host(fallback_host) }
    end

    fallback_endpoint_index = connection.manager.retry_count_for_state(:disconnected) + connection.manager.retry_count_for_state(:suspended)

    @fallback_endpoints[fallback_endpoint_index % @fallback_endpoints.count]
  end

  private
  def endpoint_for_host(host)
    URI::Generic.build(
      scheme: use_tls? ? 'wss' : 'ws',
      host:   host
    )
  end
end

#auto_connectBoolean (readonly)

When true, as soon as the client library is instantiated it will connect to Ably. If this attribute is false, a connection must be opened explicitly



47
48
49
# File 'lib/ably/realtime/client.rb', line 47

def auto_connect
  @auto_connect
end

#channelsAby::Realtime::Channels (readonly)

The collection of Ably::Realtime::Channels that have been created



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/ably/realtime/client.rb', line 20

class Client
  include Ably::Modules::AsyncWrapper
  extend Forwardable

  DOMAIN = 'realtime.ably.io'

  # The collection of {Ably::Realtime::Channel}s that have been created
  # @return [Aby::Realtime::Channels]
  attr_reader :channels

  # (see Ably::Rest::Client#auth)
  attr_reader :auth

  # The {Ably::Rest::Client REST client} instantiated with the same credentials and configuration that is used for all REST operations such as authentication
  # @return [Ably::Rest::Client]
  attr_reader :rest_client

  # When false the client suppresses messages originating from this connection being echoed back on the same connection.  Defaults to true
  # @return [Boolean]
  attr_reader :echo_messages

  # The custom realtime websocket host that is being used if it was provided with the option `:ws_host` when the {Client} was created
  # @return [String,Nil]
  attr_reader :custom_realtime_host

  # When true, as soon as the client library is instantiated it will connect to Ably.  If this attribute is false, a connection must be opened explicitly
  # @return [Boolean]
  attr_reader :auto_connect

  # When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @return [String,Nil]
  attr_reader :recover

  def_delegators :auth, :client_id, :auth_options
  def_delegators :@rest_client, :encoders
  def_delegators :@rest_client, :environment, :use_tls?, :protocol, :protocol_binary?, :custom_host
  def_delegators :@rest_client, :log_level

  # Creates a {Ably::Realtime::Client Realtime Client} and configures the {Ably::Auth} object for the connection.
  #
  # @param (see Ably::Rest::Client#initialize)
  # @option options (see Ably::Rest::Client#initialize)
  # @option options [Boolean] :queue_messages If false, this disables the default behaviour whereby the library queues messages on a connection in the disconnected or connecting states
  # @option options [Boolean] :echo_messages  If false, prevents messages originating from this connection being echoed back on the same connection
  # @option options [String]  :recover        When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @option options [Boolean] :auto_connect   By default as soon as the client library is instantiated it will connect to Ably. You can optionally set this to false and explicitly connect.
  #
  # @return [Ably::Realtime::Client]
  #
  # @example
  #    # create a new client authenticating with basic auth
  #    client = Ably::Realtime::Client.new('key.id:secret')
  #
  #    # create a new client and configure a client ID used for presence
  #    client = Ably::Realtime::Client.new(key: 'key.id:secret', client_id: 'john')
  #
  def initialize(options)
    @rest_client           = Ably::Rest::Client.new(options)
    @auth                  = @rest_client.auth
    @channels              = Ably::Realtime::Channels.new(self)
    @echo_messages         = @rest_client.options.fetch(:echo_messages, true) == false ? false : true
    @custom_realtime_host  = @rest_client.options[:realtime_host] || @rest_client.options[:ws_host]
    @auto_connect          = @rest_client.options.fetch(:auto_connect, true) == false ? false : true
    @recover               = @rest_client.options[:recover]

    raise ArgumentError, "Recovery key is invalid" if @recover && !@recover.match(Connection::RECOVER_REGEX)
  end

  # Return a {Ably::Realtime::Channel Realtime Channel} for the given name
  #
  # @param (see Ably::Realtime::Channels#get)
  # @return (see Ably::Realtime::Channels#get)
  #
  def channel(name, channel_options = {})
    channels.get(name, channel_options)
  end

  # Retrieve the Ably service time
  #
  # @yield [Time] The time as reported by the Ably service
  # @return [Ably::Util::SafeDeferrable]
  #
  def time(&success_callback)
    async_wrap(success_callback) do
      rest_client.time
    end
  end

  # Retrieve the stats for the application
  #
  # @param (see Ably::Rest::Client#stats)
  # @option options (see Ably::Rest::Client#stats)
  #
  # @yield [Ably::Models::PaginatedResult<Ably::Models::Stats>] An Array of Stats
  #
  # @return [Ably::Util::SafeDeferrable]
  #
  def stats(options = {}, &success_callback)
    async_wrap(success_callback) do
      rest_client.stats(options)
    end
  end

  # (see Ably::Realtime::Connection#close)
  def close(&block)
    connection.close(&block)
  end

  # (see Ably::Realtime::Connection#connect)
  def connect(&block)
    connection.connect(&block)
  end

  # @!attribute [r] endpoint
  # @return [URI::Generic] Default Ably Realtime endpoint used for all requests
  def endpoint
    endpoint_for_host(custom_realtime_host || [environment, DOMAIN].compact.join('-'))
  end

  # @!attribute [r] connection
  # @return [Aby::Realtime::Connection] The underlying connection for this client
  def connection
    @connection ||= Connection.new(self)
  end

  # (see Ably::Rest::Client#register_encoder)
  def register_encoder(encoder)
    rest_client.register_encoder encoder
  end

  # (see Ably::Rest::Client#logger)
  def logger
    @logger ||= Ably::Logger.new(self, log_level, rest_client.logger.custom_logger)
  end

  # Disable connection recovery, typically used after a connection has been recovered
  # @return [void]
  # @api private
  def disable_automatic_connection_recovery
    @recover = nil
  end

  # @!attribute [r] fallback_endpoint
  # @return [URI::Generic] Fallback endpoint used to connect to the realtime Ably service. Note, after each connection attempt, a new random {Ably::FALLBACK_HOSTS fallback host} is used
  # @api private
  def fallback_endpoint
    unless @fallback_endpoints
      @fallback_endpoints = Ably::FALLBACK_HOSTS.shuffle.map { |fallback_host| endpoint_for_host(fallback_host) }
    end

    fallback_endpoint_index = connection.manager.retry_count_for_state(:disconnected) + connection.manager.retry_count_for_state(:suspended)

    @fallback_endpoints[fallback_endpoint_index % @fallback_endpoints.count]
  end

  private
  def endpoint_for_host(host)
    URI::Generic.build(
      scheme: use_tls? ? 'wss' : 'ws',
      host:   host
    )
  end
end

#client_idString (readonly)



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/ably/realtime/client.rb', line 20

class Client
  include Ably::Modules::AsyncWrapper
  extend Forwardable

  DOMAIN = 'realtime.ably.io'

  # The collection of {Ably::Realtime::Channel}s that have been created
  # @return [Aby::Realtime::Channels]
  attr_reader :channels

  # (see Ably::Rest::Client#auth)
  attr_reader :auth

  # The {Ably::Rest::Client REST client} instantiated with the same credentials and configuration that is used for all REST operations such as authentication
  # @return [Ably::Rest::Client]
  attr_reader :rest_client

  # When false the client suppresses messages originating from this connection being echoed back on the same connection.  Defaults to true
  # @return [Boolean]
  attr_reader :echo_messages

  # The custom realtime websocket host that is being used if it was provided with the option `:ws_host` when the {Client} was created
  # @return [String,Nil]
  attr_reader :custom_realtime_host

  # When true, as soon as the client library is instantiated it will connect to Ably.  If this attribute is false, a connection must be opened explicitly
  # @return [Boolean]
  attr_reader :auto_connect

  # When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @return [String,Nil]
  attr_reader :recover

  def_delegators :auth, :client_id, :auth_options
  def_delegators :@rest_client, :encoders
  def_delegators :@rest_client, :environment, :use_tls?, :protocol, :protocol_binary?, :custom_host
  def_delegators :@rest_client, :log_level

  # Creates a {Ably::Realtime::Client Realtime Client} and configures the {Ably::Auth} object for the connection.
  #
  # @param (see Ably::Rest::Client#initialize)
  # @option options (see Ably::Rest::Client#initialize)
  # @option options [Boolean] :queue_messages If false, this disables the default behaviour whereby the library queues messages on a connection in the disconnected or connecting states
  # @option options [Boolean] :echo_messages  If false, prevents messages originating from this connection being echoed back on the same connection
  # @option options [String]  :recover        When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @option options [Boolean] :auto_connect   By default as soon as the client library is instantiated it will connect to Ably. You can optionally set this to false and explicitly connect.
  #
  # @return [Ably::Realtime::Client]
  #
  # @example
  #    # create a new client authenticating with basic auth
  #    client = Ably::Realtime::Client.new('key.id:secret')
  #
  #    # create a new client and configure a client ID used for presence
  #    client = Ably::Realtime::Client.new(key: 'key.id:secret', client_id: 'john')
  #
  def initialize(options)
    @rest_client           = Ably::Rest::Client.new(options)
    @auth                  = @rest_client.auth
    @channels              = Ably::Realtime::Channels.new(self)
    @echo_messages         = @rest_client.options.fetch(:echo_messages, true) == false ? false : true
    @custom_realtime_host  = @rest_client.options[:realtime_host] || @rest_client.options[:ws_host]
    @auto_connect          = @rest_client.options.fetch(:auto_connect, true) == false ? false : true
    @recover               = @rest_client.options[:recover]

    raise ArgumentError, "Recovery key is invalid" if @recover && !@recover.match(Connection::RECOVER_REGEX)
  end

  # Return a {Ably::Realtime::Channel Realtime Channel} for the given name
  #
  # @param (see Ably::Realtime::Channels#get)
  # @return (see Ably::Realtime::Channels#get)
  #
  def channel(name, channel_options = {})
    channels.get(name, channel_options)
  end

  # Retrieve the Ably service time
  #
  # @yield [Time] The time as reported by the Ably service
  # @return [Ably::Util::SafeDeferrable]
  #
  def time(&success_callback)
    async_wrap(success_callback) do
      rest_client.time
    end
  end

  # Retrieve the stats for the application
  #
  # @param (see Ably::Rest::Client#stats)
  # @option options (see Ably::Rest::Client#stats)
  #
  # @yield [Ably::Models::PaginatedResult<Ably::Models::Stats>] An Array of Stats
  #
  # @return [Ably::Util::SafeDeferrable]
  #
  def stats(options = {}, &success_callback)
    async_wrap(success_callback) do
      rest_client.stats(options)
    end
  end

  # (see Ably::Realtime::Connection#close)
  def close(&block)
    connection.close(&block)
  end

  # (see Ably::Realtime::Connection#connect)
  def connect(&block)
    connection.connect(&block)
  end

  # @!attribute [r] endpoint
  # @return [URI::Generic] Default Ably Realtime endpoint used for all requests
  def endpoint
    endpoint_for_host(custom_realtime_host || [environment, DOMAIN].compact.join('-'))
  end

  # @!attribute [r] connection
  # @return [Aby::Realtime::Connection] The underlying connection for this client
  def connection
    @connection ||= Connection.new(self)
  end

  # (see Ably::Rest::Client#register_encoder)
  def register_encoder(encoder)
    rest_client.register_encoder encoder
  end

  # (see Ably::Rest::Client#logger)
  def logger
    @logger ||= Ably::Logger.new(self, log_level, rest_client.logger.custom_logger)
  end

  # Disable connection recovery, typically used after a connection has been recovered
  # @return [void]
  # @api private
  def disable_automatic_connection_recovery
    @recover = nil
  end

  # @!attribute [r] fallback_endpoint
  # @return [URI::Generic] Fallback endpoint used to connect to the realtime Ably service. Note, after each connection attempt, a new random {Ably::FALLBACK_HOSTS fallback host} is used
  # @api private
  def fallback_endpoint
    unless @fallback_endpoints
      @fallback_endpoints = Ably::FALLBACK_HOSTS.shuffle.map { |fallback_host| endpoint_for_host(fallback_host) }
    end

    fallback_endpoint_index = connection.manager.retry_count_for_state(:disconnected) + connection.manager.retry_count_for_state(:suspended)

    @fallback_endpoints[fallback_endpoint_index % @fallback_endpoints.count]
  end

  private
  def endpoint_for_host(host)
    URI::Generic.build(
      scheme: use_tls? ? 'wss' : 'ws',
      host:   host
    )
  end
end

#connectionAby::Realtime::Connection (readonly)



141
142
143
# File 'lib/ably/realtime/client.rb', line 141

def connection
  @connection ||= Connection.new(self)
end

#custom_realtime_hostString, Nil (readonly)

The custom realtime websocket host that is being used if it was provided with the option :ws_host when the Ably::Realtime::Client was created



43
44
45
# File 'lib/ably/realtime/client.rb', line 43

def custom_realtime_host
  @custom_realtime_host
end

#echo_messagesBoolean (readonly)

When false the client suppresses messages originating from this connection being echoed back on the same connection. Defaults to true



39
40
41
# File 'lib/ably/realtime/client.rb', line 39

def echo_messages
  @echo_messages
end

#encodersArray<Ably::Models::MessageEncoder::Base> (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The registered encoders that are used to encode and decode message payloads



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/ably/realtime/client.rb', line 20

class Client
  include Ably::Modules::AsyncWrapper
  extend Forwardable

  DOMAIN = 'realtime.ably.io'

  # The collection of {Ably::Realtime::Channel}s that have been created
  # @return [Aby::Realtime::Channels]
  attr_reader :channels

  # (see Ably::Rest::Client#auth)
  attr_reader :auth

  # The {Ably::Rest::Client REST client} instantiated with the same credentials and configuration that is used for all REST operations such as authentication
  # @return [Ably::Rest::Client]
  attr_reader :rest_client

  # When false the client suppresses messages originating from this connection being echoed back on the same connection.  Defaults to true
  # @return [Boolean]
  attr_reader :echo_messages

  # The custom realtime websocket host that is being used if it was provided with the option `:ws_host` when the {Client} was created
  # @return [String,Nil]
  attr_reader :custom_realtime_host

  # When true, as soon as the client library is instantiated it will connect to Ably.  If this attribute is false, a connection must be opened explicitly
  # @return [Boolean]
  attr_reader :auto_connect

  # When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @return [String,Nil]
  attr_reader :recover

  def_delegators :auth, :client_id, :auth_options
  def_delegators :@rest_client, :encoders
  def_delegators :@rest_client, :environment, :use_tls?, :protocol, :protocol_binary?, :custom_host
  def_delegators :@rest_client, :log_level

  # Creates a {Ably::Realtime::Client Realtime Client} and configures the {Ably::Auth} object for the connection.
  #
  # @param (see Ably::Rest::Client#initialize)
  # @option options (see Ably::Rest::Client#initialize)
  # @option options [Boolean] :queue_messages If false, this disables the default behaviour whereby the library queues messages on a connection in the disconnected or connecting states
  # @option options [Boolean] :echo_messages  If false, prevents messages originating from this connection being echoed back on the same connection
  # @option options [String]  :recover        When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @option options [Boolean] :auto_connect   By default as soon as the client library is instantiated it will connect to Ably. You can optionally set this to false and explicitly connect.
  #
  # @return [Ably::Realtime::Client]
  #
  # @example
  #    # create a new client authenticating with basic auth
  #    client = Ably::Realtime::Client.new('key.id:secret')
  #
  #    # create a new client and configure a client ID used for presence
  #    client = Ably::Realtime::Client.new(key: 'key.id:secret', client_id: 'john')
  #
  def initialize(options)
    @rest_client           = Ably::Rest::Client.new(options)
    @auth                  = @rest_client.auth
    @channels              = Ably::Realtime::Channels.new(self)
    @echo_messages         = @rest_client.options.fetch(:echo_messages, true) == false ? false : true
    @custom_realtime_host  = @rest_client.options[:realtime_host] || @rest_client.options[:ws_host]
    @auto_connect          = @rest_client.options.fetch(:auto_connect, true) == false ? false : true
    @recover               = @rest_client.options[:recover]

    raise ArgumentError, "Recovery key is invalid" if @recover && !@recover.match(Connection::RECOVER_REGEX)
  end

  # Return a {Ably::Realtime::Channel Realtime Channel} for the given name
  #
  # @param (see Ably::Realtime::Channels#get)
  # @return (see Ably::Realtime::Channels#get)
  #
  def channel(name, channel_options = {})
    channels.get(name, channel_options)
  end

  # Retrieve the Ably service time
  #
  # @yield [Time] The time as reported by the Ably service
  # @return [Ably::Util::SafeDeferrable]
  #
  def time(&success_callback)
    async_wrap(success_callback) do
      rest_client.time
    end
  end

  # Retrieve the stats for the application
  #
  # @param (see Ably::Rest::Client#stats)
  # @option options (see Ably::Rest::Client#stats)
  #
  # @yield [Ably::Models::PaginatedResult<Ably::Models::Stats>] An Array of Stats
  #
  # @return [Ably::Util::SafeDeferrable]
  #
  def stats(options = {}, &success_callback)
    async_wrap(success_callback) do
      rest_client.stats(options)
    end
  end

  # (see Ably::Realtime::Connection#close)
  def close(&block)
    connection.close(&block)
  end

  # (see Ably::Realtime::Connection#connect)
  def connect(&block)
    connection.connect(&block)
  end

  # @!attribute [r] endpoint
  # @return [URI::Generic] Default Ably Realtime endpoint used for all requests
  def endpoint
    endpoint_for_host(custom_realtime_host || [environment, DOMAIN].compact.join('-'))
  end

  # @!attribute [r] connection
  # @return [Aby::Realtime::Connection] The underlying connection for this client
  def connection
    @connection ||= Connection.new(self)
  end

  # (see Ably::Rest::Client#register_encoder)
  def register_encoder(encoder)
    rest_client.register_encoder encoder
  end

  # (see Ably::Rest::Client#logger)
  def logger
    @logger ||= Ably::Logger.new(self, log_level, rest_client.logger.custom_logger)
  end

  # Disable connection recovery, typically used after a connection has been recovered
  # @return [void]
  # @api private
  def disable_automatic_connection_recovery
    @recover = nil
  end

  # @!attribute [r] fallback_endpoint
  # @return [URI::Generic] Fallback endpoint used to connect to the realtime Ably service. Note, after each connection attempt, a new random {Ably::FALLBACK_HOSTS fallback host} is used
  # @api private
  def fallback_endpoint
    unless @fallback_endpoints
      @fallback_endpoints = Ably::FALLBACK_HOSTS.shuffle.map { |fallback_host| endpoint_for_host(fallback_host) }
    end

    fallback_endpoint_index = connection.manager.retry_count_for_state(:disconnected) + connection.manager.retry_count_for_state(:suspended)

    @fallback_endpoints[fallback_endpoint_index % @fallback_endpoints.count]
  end

  private
  def endpoint_for_host(host)
    URI::Generic.build(
      scheme: use_tls? ? 'wss' : 'ws',
      host:   host
    )
  end
end

#endpointURI::Generic (readonly)



135
136
137
# File 'lib/ably/realtime/client.rb', line 135

def endpoint
  endpoint_for_host(custom_realtime_host || [environment, DOMAIN].compact.join('-'))
end

#environmentString (readonly)

Custom environment to use such as ‘sandbox’ when testing the client library against an alternate Ably environment



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/ably/realtime/client.rb', line 20

class Client
  include Ably::Modules::AsyncWrapper
  extend Forwardable

  DOMAIN = 'realtime.ably.io'

  # The collection of {Ably::Realtime::Channel}s that have been created
  # @return [Aby::Realtime::Channels]
  attr_reader :channels

  # (see Ably::Rest::Client#auth)
  attr_reader :auth

  # The {Ably::Rest::Client REST client} instantiated with the same credentials and configuration that is used for all REST operations such as authentication
  # @return [Ably::Rest::Client]
  attr_reader :rest_client

  # When false the client suppresses messages originating from this connection being echoed back on the same connection.  Defaults to true
  # @return [Boolean]
  attr_reader :echo_messages

  # The custom realtime websocket host that is being used if it was provided with the option `:ws_host` when the {Client} was created
  # @return [String,Nil]
  attr_reader :custom_realtime_host

  # When true, as soon as the client library is instantiated it will connect to Ably.  If this attribute is false, a connection must be opened explicitly
  # @return [Boolean]
  attr_reader :auto_connect

  # When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @return [String,Nil]
  attr_reader :recover

  def_delegators :auth, :client_id, :auth_options
  def_delegators :@rest_client, :encoders
  def_delegators :@rest_client, :environment, :use_tls?, :protocol, :protocol_binary?, :custom_host
  def_delegators :@rest_client, :log_level

  # Creates a {Ably::Realtime::Client Realtime Client} and configures the {Ably::Auth} object for the connection.
  #
  # @param (see Ably::Rest::Client#initialize)
  # @option options (see Ably::Rest::Client#initialize)
  # @option options [Boolean] :queue_messages If false, this disables the default behaviour whereby the library queues messages on a connection in the disconnected or connecting states
  # @option options [Boolean] :echo_messages  If false, prevents messages originating from this connection being echoed back on the same connection
  # @option options [String]  :recover        When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @option options [Boolean] :auto_connect   By default as soon as the client library is instantiated it will connect to Ably. You can optionally set this to false and explicitly connect.
  #
  # @return [Ably::Realtime::Client]
  #
  # @example
  #    # create a new client authenticating with basic auth
  #    client = Ably::Realtime::Client.new('key.id:secret')
  #
  #    # create a new client and configure a client ID used for presence
  #    client = Ably::Realtime::Client.new(key: 'key.id:secret', client_id: 'john')
  #
  def initialize(options)
    @rest_client           = Ably::Rest::Client.new(options)
    @auth                  = @rest_client.auth
    @channels              = Ably::Realtime::Channels.new(self)
    @echo_messages         = @rest_client.options.fetch(:echo_messages, true) == false ? false : true
    @custom_realtime_host  = @rest_client.options[:realtime_host] || @rest_client.options[:ws_host]
    @auto_connect          = @rest_client.options.fetch(:auto_connect, true) == false ? false : true
    @recover               = @rest_client.options[:recover]

    raise ArgumentError, "Recovery key is invalid" if @recover && !@recover.match(Connection::RECOVER_REGEX)
  end

  # Return a {Ably::Realtime::Channel Realtime Channel} for the given name
  #
  # @param (see Ably::Realtime::Channels#get)
  # @return (see Ably::Realtime::Channels#get)
  #
  def channel(name, channel_options = {})
    channels.get(name, channel_options)
  end

  # Retrieve the Ably service time
  #
  # @yield [Time] The time as reported by the Ably service
  # @return [Ably::Util::SafeDeferrable]
  #
  def time(&success_callback)
    async_wrap(success_callback) do
      rest_client.time
    end
  end

  # Retrieve the stats for the application
  #
  # @param (see Ably::Rest::Client#stats)
  # @option options (see Ably::Rest::Client#stats)
  #
  # @yield [Ably::Models::PaginatedResult<Ably::Models::Stats>] An Array of Stats
  #
  # @return [Ably::Util::SafeDeferrable]
  #
  def stats(options = {}, &success_callback)
    async_wrap(success_callback) do
      rest_client.stats(options)
    end
  end

  # (see Ably::Realtime::Connection#close)
  def close(&block)
    connection.close(&block)
  end

  # (see Ably::Realtime::Connection#connect)
  def connect(&block)
    connection.connect(&block)
  end

  # @!attribute [r] endpoint
  # @return [URI::Generic] Default Ably Realtime endpoint used for all requests
  def endpoint
    endpoint_for_host(custom_realtime_host || [environment, DOMAIN].compact.join('-'))
  end

  # @!attribute [r] connection
  # @return [Aby::Realtime::Connection] The underlying connection for this client
  def connection
    @connection ||= Connection.new(self)
  end

  # (see Ably::Rest::Client#register_encoder)
  def register_encoder(encoder)
    rest_client.register_encoder encoder
  end

  # (see Ably::Rest::Client#logger)
  def logger
    @logger ||= Ably::Logger.new(self, log_level, rest_client.logger.custom_logger)
  end

  # Disable connection recovery, typically used after a connection has been recovered
  # @return [void]
  # @api private
  def disable_automatic_connection_recovery
    @recover = nil
  end

  # @!attribute [r] fallback_endpoint
  # @return [URI::Generic] Fallback endpoint used to connect to the realtime Ably service. Note, after each connection attempt, a new random {Ably::FALLBACK_HOSTS fallback host} is used
  # @api private
  def fallback_endpoint
    unless @fallback_endpoints
      @fallback_endpoints = Ably::FALLBACK_HOSTS.shuffle.map { |fallback_host| endpoint_for_host(fallback_host) }
    end

    fallback_endpoint_index = connection.manager.retry_count_for_state(:disconnected) + connection.manager.retry_count_for_state(:suspended)

    @fallback_endpoints[fallback_endpoint_index % @fallback_endpoints.count]
  end

  private
  def endpoint_for_host(host)
    URI::Generic.build(
      scheme: use_tls? ? 'wss' : 'ws',
      host:   host
    )
  end
end

#fallback_endpointURI::Generic (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns Fallback endpoint used to connect to the realtime Ably service. Note, after each connection attempt, a new random fallback host is used.



165
166
167
168
169
170
171
172
173
# File 'lib/ably/realtime/client.rb', line 165

def fallback_endpoint
  unless @fallback_endpoints
    @fallback_endpoints = Ably::FALLBACK_HOSTS.shuffle.map { |fallback_host| endpoint_for_host(fallback_host) }
  end

  fallback_endpoint_index = connection.manager.retry_count_for_state(:disconnected) + connection.manager.retry_count_for_state(:suspended)

  @fallback_endpoints[fallback_endpoint_index % @fallback_endpoints.count]
end

#protocolSymbol (readonly)

The protocol configured for this client, either binary :msgpack or text based :json



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/ably/realtime/client.rb', line 20

class Client
  include Ably::Modules::AsyncWrapper
  extend Forwardable

  DOMAIN = 'realtime.ably.io'

  # The collection of {Ably::Realtime::Channel}s that have been created
  # @return [Aby::Realtime::Channels]
  attr_reader :channels

  # (see Ably::Rest::Client#auth)
  attr_reader :auth

  # The {Ably::Rest::Client REST client} instantiated with the same credentials and configuration that is used for all REST operations such as authentication
  # @return [Ably::Rest::Client]
  attr_reader :rest_client

  # When false the client suppresses messages originating from this connection being echoed back on the same connection.  Defaults to true
  # @return [Boolean]
  attr_reader :echo_messages

  # The custom realtime websocket host that is being used if it was provided with the option `:ws_host` when the {Client} was created
  # @return [String,Nil]
  attr_reader :custom_realtime_host

  # When true, as soon as the client library is instantiated it will connect to Ably.  If this attribute is false, a connection must be opened explicitly
  # @return [Boolean]
  attr_reader :auto_connect

  # When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @return [String,Nil]
  attr_reader :recover

  def_delegators :auth, :client_id, :auth_options
  def_delegators :@rest_client, :encoders
  def_delegators :@rest_client, :environment, :use_tls?, :protocol, :protocol_binary?, :custom_host
  def_delegators :@rest_client, :log_level

  # Creates a {Ably::Realtime::Client Realtime Client} and configures the {Ably::Auth} object for the connection.
  #
  # @param (see Ably::Rest::Client#initialize)
  # @option options (see Ably::Rest::Client#initialize)
  # @option options [Boolean] :queue_messages If false, this disables the default behaviour whereby the library queues messages on a connection in the disconnected or connecting states
  # @option options [Boolean] :echo_messages  If false, prevents messages originating from this connection being echoed back on the same connection
  # @option options [String]  :recover        When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @option options [Boolean] :auto_connect   By default as soon as the client library is instantiated it will connect to Ably. You can optionally set this to false and explicitly connect.
  #
  # @return [Ably::Realtime::Client]
  #
  # @example
  #    # create a new client authenticating with basic auth
  #    client = Ably::Realtime::Client.new('key.id:secret')
  #
  #    # create a new client and configure a client ID used for presence
  #    client = Ably::Realtime::Client.new(key: 'key.id:secret', client_id: 'john')
  #
  def initialize(options)
    @rest_client           = Ably::Rest::Client.new(options)
    @auth                  = @rest_client.auth
    @channels              = Ably::Realtime::Channels.new(self)
    @echo_messages         = @rest_client.options.fetch(:echo_messages, true) == false ? false : true
    @custom_realtime_host  = @rest_client.options[:realtime_host] || @rest_client.options[:ws_host]
    @auto_connect          = @rest_client.options.fetch(:auto_connect, true) == false ? false : true
    @recover               = @rest_client.options[:recover]

    raise ArgumentError, "Recovery key is invalid" if @recover && !@recover.match(Connection::RECOVER_REGEX)
  end

  # Return a {Ably::Realtime::Channel Realtime Channel} for the given name
  #
  # @param (see Ably::Realtime::Channels#get)
  # @return (see Ably::Realtime::Channels#get)
  #
  def channel(name, channel_options = {})
    channels.get(name, channel_options)
  end

  # Retrieve the Ably service time
  #
  # @yield [Time] The time as reported by the Ably service
  # @return [Ably::Util::SafeDeferrable]
  #
  def time(&success_callback)
    async_wrap(success_callback) do
      rest_client.time
    end
  end

  # Retrieve the stats for the application
  #
  # @param (see Ably::Rest::Client#stats)
  # @option options (see Ably::Rest::Client#stats)
  #
  # @yield [Ably::Models::PaginatedResult<Ably::Models::Stats>] An Array of Stats
  #
  # @return [Ably::Util::SafeDeferrable]
  #
  def stats(options = {}, &success_callback)
    async_wrap(success_callback) do
      rest_client.stats(options)
    end
  end

  # (see Ably::Realtime::Connection#close)
  def close(&block)
    connection.close(&block)
  end

  # (see Ably::Realtime::Connection#connect)
  def connect(&block)
    connection.connect(&block)
  end

  # @!attribute [r] endpoint
  # @return [URI::Generic] Default Ably Realtime endpoint used for all requests
  def endpoint
    endpoint_for_host(custom_realtime_host || [environment, DOMAIN].compact.join('-'))
  end

  # @!attribute [r] connection
  # @return [Aby::Realtime::Connection] The underlying connection for this client
  def connection
    @connection ||= Connection.new(self)
  end

  # (see Ably::Rest::Client#register_encoder)
  def register_encoder(encoder)
    rest_client.register_encoder encoder
  end

  # (see Ably::Rest::Client#logger)
  def logger
    @logger ||= Ably::Logger.new(self, log_level, rest_client.logger.custom_logger)
  end

  # Disable connection recovery, typically used after a connection has been recovered
  # @return [void]
  # @api private
  def disable_automatic_connection_recovery
    @recover = nil
  end

  # @!attribute [r] fallback_endpoint
  # @return [URI::Generic] Fallback endpoint used to connect to the realtime Ably service. Note, after each connection attempt, a new random {Ably::FALLBACK_HOSTS fallback host} is used
  # @api private
  def fallback_endpoint
    unless @fallback_endpoints
      @fallback_endpoints = Ably::FALLBACK_HOSTS.shuffle.map { |fallback_host| endpoint_for_host(fallback_host) }
    end

    fallback_endpoint_index = connection.manager.retry_count_for_state(:disconnected) + connection.manager.retry_count_for_state(:suspended)

    @fallback_endpoints[fallback_endpoint_index % @fallback_endpoints.count]
  end

  private
  def endpoint_for_host(host)
    URI::Generic.build(
      scheme: use_tls? ? 'wss' : 'ws',
      host:   host
    )
  end
end

#protocol_binary?Boolean (readonly)



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/ably/realtime/client.rb', line 20

class Client
  include Ably::Modules::AsyncWrapper
  extend Forwardable

  DOMAIN = 'realtime.ably.io'

  # The collection of {Ably::Realtime::Channel}s that have been created
  # @return [Aby::Realtime::Channels]
  attr_reader :channels

  # (see Ably::Rest::Client#auth)
  attr_reader :auth

  # The {Ably::Rest::Client REST client} instantiated with the same credentials and configuration that is used for all REST operations such as authentication
  # @return [Ably::Rest::Client]
  attr_reader :rest_client

  # When false the client suppresses messages originating from this connection being echoed back on the same connection.  Defaults to true
  # @return [Boolean]
  attr_reader :echo_messages

  # The custom realtime websocket host that is being used if it was provided with the option `:ws_host` when the {Client} was created
  # @return [String,Nil]
  attr_reader :custom_realtime_host

  # When true, as soon as the client library is instantiated it will connect to Ably.  If this attribute is false, a connection must be opened explicitly
  # @return [Boolean]
  attr_reader :auto_connect

  # When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @return [String,Nil]
  attr_reader :recover

  def_delegators :auth, :client_id, :auth_options
  def_delegators :@rest_client, :encoders
  def_delegators :@rest_client, :environment, :use_tls?, :protocol, :protocol_binary?, :custom_host
  def_delegators :@rest_client, :log_level

  # Creates a {Ably::Realtime::Client Realtime Client} and configures the {Ably::Auth} object for the connection.
  #
  # @param (see Ably::Rest::Client#initialize)
  # @option options (see Ably::Rest::Client#initialize)
  # @option options [Boolean] :queue_messages If false, this disables the default behaviour whereby the library queues messages on a connection in the disconnected or connecting states
  # @option options [Boolean] :echo_messages  If false, prevents messages originating from this connection being echoed back on the same connection
  # @option options [String]  :recover        When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery
  # @option options [Boolean] :auto_connect   By default as soon as the client library is instantiated it will connect to Ably. You can optionally set this to false and explicitly connect.
  #
  # @return [Ably::Realtime::Client]
  #
  # @example
  #    # create a new client authenticating with basic auth
  #    client = Ably::Realtime::Client.new('key.id:secret')
  #
  #    # create a new client and configure a client ID used for presence
  #    client = Ably::Realtime::Client.new(key: 'key.id:secret', client_id: 'john')
  #
  def initialize(options)
    @rest_client           = Ably::Rest::Client.new(options)
    @auth                  = @rest_client.auth
    @channels              = Ably::Realtime::Channels.new(self)
    @echo_messages         = @rest_client.options.fetch(:echo_messages, true) == false ? false : true
    @custom_realtime_host  = @rest_client.options[:realtime_host] || @rest_client.options[:ws_host]
    @auto_connect          = @rest_client.options.fetch(:auto_connect, true) == false ? false : true
    @recover               = @rest_client.options[:recover]

    raise ArgumentError, "Recovery key is invalid" if @recover && !@recover.match(Connection::RECOVER_REGEX)
  end

  # Return a {Ably::Realtime::Channel Realtime Channel} for the given name
  #
  # @param (see Ably::Realtime::Channels#get)
  # @return (see Ably::Realtime::Channels#get)
  #
  def channel(name, channel_options = {})
    channels.get(name, channel_options)
  end

  # Retrieve the Ably service time
  #
  # @yield [Time] The time as reported by the Ably service
  # @return [Ably::Util::SafeDeferrable]
  #
  def time(&success_callback)
    async_wrap(success_callback) do
      rest_client.time
    end
  end

  # Retrieve the stats for the application
  #
  # @param (see Ably::Rest::Client#stats)
  # @option options (see Ably::Rest::Client#stats)
  #
  # @yield [Ably::Models::PaginatedResult<Ably::Models::Stats>] An Array of Stats
  #
  # @return [Ably::Util::SafeDeferrable]
  #
  def stats(options = {}, &success_callback)
    async_wrap(success_callback) do
      rest_client.stats(options)
    end
  end

  # (see Ably::Realtime::Connection#close)
  def close(&block)
    connection.close(&block)
  end

  # (see Ably::Realtime::Connection#connect)
  def connect(&block)
    connection.connect(&block)
  end

  # @!attribute [r] endpoint
  # @return [URI::Generic] Default Ably Realtime endpoint used for all requests
  def endpoint
    endpoint_for_host(custom_realtime_host || [environment, DOMAIN].compact.join('-'))
  end

  # @!attribute [r] connection
  # @return [Aby::Realtime::Connection] The underlying connection for this client
  def connection
    @connection ||= Connection.new(self)
  end

  # (see Ably::Rest::Client#register_encoder)
  def register_encoder(encoder)
    rest_client.register_encoder encoder
  end

  # (see Ably::Rest::Client#logger)
  def logger
    @logger ||= Ably::Logger.new(self, log_level, rest_client.logger.custom_logger)
  end

  # Disable connection recovery, typically used after a connection has been recovered
  # @return [void]
  # @api private
  def disable_automatic_connection_recovery
    @recover = nil
  end

  # @!attribute [r] fallback_endpoint
  # @return [URI::Generic] Fallback endpoint used to connect to the realtime Ably service. Note, after each connection attempt, a new random {Ably::FALLBACK_HOSTS fallback host} is used
  # @api private
  def fallback_endpoint
    unless @fallback_endpoints
      @fallback_endpoints = Ably::FALLBACK_HOSTS.shuffle.map { |fallback_host| endpoint_for_host(fallback_host) }
    end

    fallback_endpoint_index = connection.manager.retry_count_for_state(:disconnected) + connection.manager.retry_count_for_state(:suspended)

    @fallback_endpoints[fallback_endpoint_index % @fallback_endpoints.count]
  end

  private
  def endpoint_for_host(host)
    URI::Generic.build(
      scheme: use_tls? ? 'wss' : 'ws',
      host:   host
    )
  end
end

#recoverString, Nil (readonly)

When a recover option is specified a connection inherits the state of a previous connection that may have existed under a different instance of the Realtime library, please refer to the API documentation for further information on connection state recovery



51
52
53
# File 'lib/ably/realtime/client.rb', line 51

def recover
  @recover
end

#rest_clientAbly::Rest::Client (readonly)

The REST client instantiated with the same credentials and configuration that is used for all REST operations such as authentication



35
36
37
# File 'lib/ably/realtime/client.rb', line 35

def rest_client
  @rest_client
end

Instance Method Details

#channel(name, channel_options = {}) ⇒ Ably::Realtime::Channel

Return a Realtime Channel for the given name



93
94
95
# File 'lib/ably/realtime/client.rb', line 93

def channel(name, channel_options = {})
  channels.get(name, channel_options)
end

#close {|Ably::Realtime::Connection| ... } ⇒ EventMachine::Deferrable

Causes the connection to close, entering the closed state, from any state except the failed state. Once closed, the library will not attempt to re-establish the connection without a call to Ably::Realtime::Connection#connect.

Yields:



124
125
126
# File 'lib/ably/realtime/client.rb', line 124

def close(&block)
  connection.close(&block)
end

#connect {|Ably::Realtime::Connection| ... } ⇒ EventMachine::Deferrable

Causes the library to attempt connection. If it was previously explicitly closed by the user, or was closed as a result of an unrecoverable error, a new connection will be opened.

Yields:



129
130
131
# File 'lib/ably/realtime/client.rb', line 129

def connect(&block)
  connection.connect(&block)
end

#disable_automatic_connection_recoveryvoid

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Disable connection recovery, typically used after a connection has been recovered



158
159
160
# File 'lib/ably/realtime/client.rb', line 158

def disable_automatic_connection_recovery
  @recover = nil
end

#loggerLogger



151
152
153
# File 'lib/ably/realtime/client.rb', line 151

def logger
  @logger ||= Ably::Logger.new(self, log_level, rest_client.logger.custom_logger)
end

#register_encoder(encoder) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

Encoders and decoders are processed in the order they are added so the first encoder will be given priority when encoding and decoding

This method returns an undefined value.

Register a message encoder and decoder that implements Ably::Models::MessageEncoders::Base interface. Message encoders are used to encode and decode message payloads automatically.



146
147
148
# File 'lib/ably/realtime/client.rb', line 146

def register_encoder(encoder)
  rest_client.register_encoder encoder
end

#stats(options = {}) {|Ably::Models::PaginatedResult<Ably::Models::Stats>| ... } ⇒ Ably::Util::SafeDeferrable

Retrieve the stats for the application

Options Hash (options):

  • :start (Integer, Time)

    Ensure earliest time or millisecond since epoch for any stats retrieved is :start

  • :end (Integer, Time)

    Ensure latest time or millisecond since epoch for any stats retrieved is :end

  • :direction (Symbol)

    :forwards or :backwards, defaults to :backwards

  • :limit (Integer)

    Maximum number of messages to retrieve up to 1,000, defaults to 100

  • :unit (Symbol)

    :minute, :hour, :day or :month. Defaults to :minute

Yields:



117
118
119
120
121
# File 'lib/ably/realtime/client.rb', line 117

def stats(options = {}, &success_callback)
  async_wrap(success_callback) do
    rest_client.stats(options)
  end
end

#time {|Time| ... } ⇒ Ably::Util::SafeDeferrable

Retrieve the Ably service time

Yields:

  • (Time)

    The time as reported by the Ably service



102
103
104
105
106
# File 'lib/ably/realtime/client.rb', line 102

def time(&success_callback)
  async_wrap(success_callback) do
    rest_client.time
  end
end