ably-rest 0.7.5 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.travis.yml +2 -0
- data/README.md +41 -15
- data/SPEC.md +654 -518
- data/lib/submodules/ably-ruby/.gitignore +1 -0
- data/lib/submodules/ably-ruby/.gitmodules +3 -0
- data/lib/submodules/ably-ruby/README.md +54 -26
- data/lib/submodules/ably-ruby/SPEC.md +468 -322
- data/lib/submodules/ably-ruby/ably.gemspec +4 -2
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +185 -131
- data/lib/submodules/ably-ruby/lib/ably/models/message.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/models/paginated_resource.rb +31 -44
- data/lib/submodules/ably-ruby/lib/ably/models/presence_message.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +1 -2
- data/lib/submodules/ably-ruby/lib/ably/models/stat.rb +67 -24
- data/lib/submodules/ably-ruby/lib/ably/models/stats_types.rb +131 -0
- data/lib/submodules/ably-ruby/lib/ably/models/token_details.rb +101 -0
- data/lib/submodules/ably-ruby/lib/ably/models/token_request.rb +108 -0
- data/lib/submodules/ably-ruby/lib/ably/modules/async_wrapper.rb +3 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/http_helpers.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/message_emitter.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime.rb +3 -7
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +32 -5
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +1 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +4 -8
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +5 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +12 -1
- data/lib/submodules/ably-ruby/lib/ably/rest.rb +3 -7
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +13 -10
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +19 -20
- data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +14 -12
- data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +74 -23
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +3 -3
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +18 -18
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +5 -5
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +12 -12
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +5 -5
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +56 -13
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +8 -8
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/stats_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/time_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +262 -158
- data/lib/submodules/ably-ruby/spec/acceptance/rest/base_spec.rb +11 -9
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +28 -21
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channels_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +30 -27
- data/lib/submodules/ably-ruby/spec/acceptance/rest/encoders_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +10 -10
- data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +93 -56
- data/lib/submodules/ably-ruby/spec/acceptance/rest/stats_spec.rb +50 -45
- data/lib/submodules/ably-ruby/spec/acceptance/rest/time_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/rspec_config.rb +3 -2
- data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +36 -28
- data/lib/submodules/ably-ruby/spec/spec_helper.rb +3 -0
- data/lib/submodules/ably-ruby/spec/support/api_helper.rb +3 -3
- data/lib/submodules/ably-ruby/spec/support/markdown_spec_formatter.rb +1 -1
- data/lib/submodules/ably-ruby/spec/support/test_app.rb +20 -33
- data/lib/submodules/ably-ruby/spec/unit/auth_spec.rb +18 -1
- data/lib/submodules/ably-ruby/spec/unit/models/paginated_resource_spec.rb +81 -72
- data/lib/submodules/ably-ruby/spec/unit/models/stats_spec.rb +289 -0
- data/lib/submodules/ably-ruby/spec/unit/models/token_details_spec.rb +111 -0
- data/lib/submodules/ably-ruby/spec/unit/models/token_request_spec.rb +110 -0
- data/lib/submodules/ably-ruby/spec/unit/modules/async_wrapper_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/realtime_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/rest/channel_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/rest/client_spec.rb +8 -8
- data/lib/submodules/ably-ruby/spec/unit/rest/rest_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/util/crypto_spec.rb +1 -1
- metadata +9 -7
- data/lib/submodules/ably-ruby/lib/ably/models/token.rb +0 -74
- data/lib/submodules/ably-ruby/spec/resources/crypto-data-128.json +0 -56
- data/lib/submodules/ably-ruby/spec/resources/crypto-data-256.json +0 -56
- data/lib/submodules/ably-ruby/spec/unit/models/stat_spec.rb +0 -113
- data/lib/submodules/ably-ruby/spec/unit/models/token_spec.rb +0 -86
@@ -0,0 +1,101 @@
|
|
1
|
+
module Ably::Models
|
2
|
+
# Convert token details argument to a {TokenDetails} object
|
3
|
+
#
|
4
|
+
# @param attributes [TokenDetails,Hash] A {TokenDetails} object or Hash of token and meta data attributes
|
5
|
+
# @option attributes (see TokenDetails#initialize)
|
6
|
+
#
|
7
|
+
# @return [TokenDetails]
|
8
|
+
def self.TokenDetails(attributes)
|
9
|
+
case attributes
|
10
|
+
when TokenDetails
|
11
|
+
return attributes
|
12
|
+
else
|
13
|
+
TokenDetails.new(attributes)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# TokenDetails is a class providing details of the token string and the token's associated metadata,
|
18
|
+
# constructed from the response from Ably when request in a token via the REST API.
|
19
|
+
#
|
20
|
+
# Ruby {Time} objects are supported in place of Ably ms since epoch time fields. However, if a numeric is provided
|
21
|
+
# it must always be expressed in milliseconds as the Ably API always uses milliseconds for time fields.
|
22
|
+
#
|
23
|
+
class TokenDetails
|
24
|
+
include Ably::Modules::ModelCommon
|
25
|
+
|
26
|
+
# Buffer in seconds before a token is considered unusable
|
27
|
+
# For example, if buffer is 10s, the token can no longer be used for new requests 9s before it expires
|
28
|
+
TOKEN_EXPIRY_BUFFER = 5
|
29
|
+
|
30
|
+
def initialize(attributes)
|
31
|
+
@hash_object = IdiomaticRubyWrapper(attributes.clone.freeze)
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param attributes
|
35
|
+
# @option attributes [String] :token token used to authenticate requests
|
36
|
+
# @option attributes [String] :key_name API key name used to create this token
|
37
|
+
# @option attributes [Time,Integer] :issued Time the token was issued as Time or Integer in milliseconds
|
38
|
+
# @option attributes [Time,Integer] :expires Time the token expires as Time or Integer in milliseconds
|
39
|
+
# @option attributes [String] :capability JSON stringified capabilities assigned to this token
|
40
|
+
# @option attributes [String] :client_id client ID assigned to this token
|
41
|
+
#
|
42
|
+
def initialize(attributes = {})
|
43
|
+
@hash_object = IdiomaticRubyWrapper(attributes.clone)
|
44
|
+
|
45
|
+
%w(issued expires).map(&:to_sym).each do |time_attribute|
|
46
|
+
hash[time_attribute] = (hash[time_attribute].to_f * 1000).round if hash[time_attribute].kind_of?(Time)
|
47
|
+
end
|
48
|
+
|
49
|
+
hash.freeze
|
50
|
+
end
|
51
|
+
|
52
|
+
# @!attribute [r] token
|
53
|
+
# @return [String] Token used to authenticate requests
|
54
|
+
def token
|
55
|
+
hash.fetch(:token)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @!attribute [r] key_name
|
59
|
+
# @return [String] API key name used to create this token. An API key is made up of an API key name and secret delimited by a +:+
|
60
|
+
def key_name
|
61
|
+
hash.fetch(:key_name)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @!attribute [r] issued
|
65
|
+
# @return [Time] Time the token was issued
|
66
|
+
def issued
|
67
|
+
as_time_from_epoch(hash.fetch(:issued), granularity: :ms)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @!attribute [r] expires
|
71
|
+
# @return [Time] Time the token expires
|
72
|
+
def expires
|
73
|
+
as_time_from_epoch(hash.fetch(:expires), granularity: :ms)
|
74
|
+
end
|
75
|
+
|
76
|
+
# @!attribute [r] capability
|
77
|
+
# @return [Hash] Capabilities assigned to this token
|
78
|
+
def capability
|
79
|
+
JSON.parse(hash.fetch(:capability))
|
80
|
+
end
|
81
|
+
|
82
|
+
# @!attribute [r] client_id
|
83
|
+
# @return [String] Optional client ID assigned to this token
|
84
|
+
def client_id
|
85
|
+
hash[:client_id]
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns true if token is expired or about to expire
|
89
|
+
#
|
90
|
+
# @return [Boolean]
|
91
|
+
def expired?
|
92
|
+
expires < Time.now + TOKEN_EXPIRY_BUFFER
|
93
|
+
end
|
94
|
+
|
95
|
+
# @!attribute [r] hash
|
96
|
+
# @return [Hash] Access the token details Hash object ruby'fied to use symbolized keys
|
97
|
+
def hash
|
98
|
+
@hash_object
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Ably::Models
|
2
|
+
# Convert token request argument to a {TokenRequest} object
|
3
|
+
#
|
4
|
+
# @param attributes [TokenRequest,Hash] A {TokenRequest} object or Hash of attributes to create a new token request
|
5
|
+
# @option attributes (see TokenRequest#initialize)
|
6
|
+
#
|
7
|
+
# @return [TokenRequest]
|
8
|
+
def self.TokenRequest(attributes)
|
9
|
+
case attributes
|
10
|
+
when TokenRequest
|
11
|
+
return attributes
|
12
|
+
else
|
13
|
+
TokenRequest.new(attributes)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
# TokenRequest is a class that stores the attributes of a token request
|
19
|
+
#
|
20
|
+
# Ruby {Time} objects are supported in place of Ably ms since epoch time fields. However, if a numeric is provided
|
21
|
+
# it must always be expressed in milliseconds as the Ably API always uses milliseconds for time fields.
|
22
|
+
#
|
23
|
+
class TokenRequest
|
24
|
+
include Ably::Modules::ModelCommon
|
25
|
+
|
26
|
+
# @param attributes
|
27
|
+
# @option attributes [Integer] :ttl requested time to live for the token in milliseconds
|
28
|
+
# @option attributes [Time,Integer] :timestamp the timestamp of this request in milliseconds or as a {Time}
|
29
|
+
# @option attributes [String] :key_name API key name of the key against which this request is made
|
30
|
+
# @option attributes [String] :capability JSON stringified capability of the token
|
31
|
+
# @option attributes [String] :client_id client ID to associate with this token
|
32
|
+
# @option attributes [String] :nonce an opaque nonce string of at least 16 characters
|
33
|
+
# @option attributes [String] :mac the Message Authentication Code for this request
|
34
|
+
#
|
35
|
+
def initialize(attributes = {})
|
36
|
+
@hash_object = IdiomaticRubyWrapper(attributes.clone)
|
37
|
+
hash[:timestamp] = (hash[:timestamp].to_f * 1000).round if hash[:timestamp].kind_of?(Time)
|
38
|
+
hash.freeze
|
39
|
+
end
|
40
|
+
|
41
|
+
# @!attribute [r] key_name
|
42
|
+
# @return [String] API key name of the key against which this request is made. An API key is made up of an API key name and secret delimited by a +:+
|
43
|
+
def key_name
|
44
|
+
hash.fetch(:key_name)
|
45
|
+
end
|
46
|
+
|
47
|
+
# @!attribute [r] ttl
|
48
|
+
# @return [Integer] requested time to live for the token in seconds. If the token request is successful,
|
49
|
+
# the TTL of the returned token will be less than or equal to this value depending on application
|
50
|
+
# settings and the attributes of the issuing key.
|
51
|
+
# TTL when sent to Ably is in milliseconds.
|
52
|
+
def ttl
|
53
|
+
hash.fetch(:ttl) / 1000
|
54
|
+
end
|
55
|
+
|
56
|
+
# @!attribute [r] capability
|
57
|
+
# @return [Hash] capability of the token. If the token request is successful,
|
58
|
+
# the capability of the returned token will be the intersection of
|
59
|
+
# this capability with the capability of the issuing key.
|
60
|
+
def capability
|
61
|
+
JSON.parse(hash.fetch(:capability))
|
62
|
+
end
|
63
|
+
|
64
|
+
# @!attribute [r] client_id
|
65
|
+
# @return [String] the client ID to associate with this token. The generated token
|
66
|
+
# may be used to authenticate as this clientId.
|
67
|
+
def client_id
|
68
|
+
hash[:client_id]
|
69
|
+
end
|
70
|
+
|
71
|
+
# @!attribute [r] timestamp
|
72
|
+
# @return [Time] the timestamp of this request.
|
73
|
+
# Timestamps, in conjunction with the nonce, are used to prevent
|
74
|
+
# token requests from being replayed.
|
75
|
+
# Timestamp when sent to Ably is in milliseconds.
|
76
|
+
def timestamp
|
77
|
+
as_time_from_epoch(hash.fetch(:timestamp), granularity: :ms)
|
78
|
+
end
|
79
|
+
|
80
|
+
# @!attribute [r] nonce
|
81
|
+
# @return [String] an opaque nonce string of at least 16 characters to ensure
|
82
|
+
# uniqueness of this request. Any subsequent request using the
|
83
|
+
# same nonce will be rejected.
|
84
|
+
def nonce
|
85
|
+
hash.fetch(:nonce)
|
86
|
+
end
|
87
|
+
|
88
|
+
# @!attribute [r] mac
|
89
|
+
# @return [String] the Message Authentication Code for this request. See the
|
90
|
+
# {https://www.ably.io/documentation Ably Authentication documentation} for more details.
|
91
|
+
def mac
|
92
|
+
hash.fetch(:mac)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Requests that the token is always persisted
|
96
|
+
# @api private
|
97
|
+
#
|
98
|
+
def persisted
|
99
|
+
hash.fetch(:persisted)
|
100
|
+
end
|
101
|
+
|
102
|
+
# @!attribute [r] hash
|
103
|
+
# @return [Hash] the token request Hash object ruby'fied to use symbolized keys
|
104
|
+
def hash
|
105
|
+
@hash_object
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -47,8 +47,9 @@ module Ably::Modules
|
|
47
47
|
operation_with_exception_handling = proc do
|
48
48
|
begin
|
49
49
|
yield
|
50
|
-
rescue StandardError =>
|
51
|
-
|
50
|
+
rescue StandardError => err
|
51
|
+
logger.error "An exception in an AsyncWrapper block was caught. #{err.class}: #{err.message}\n#{err.backtrace.join("\n")}"
|
52
|
+
deferrable.fail err
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
@@ -6,7 +6,7 @@ module Ably::Modules
|
|
6
6
|
module MessageEmitter
|
7
7
|
# Subscribe to events on this object
|
8
8
|
#
|
9
|
-
# @param
|
9
|
+
# @param names [String,Symbol] Optional, the event name(s) to subscribe to. Defaults to `:all` events
|
10
10
|
# @yield [Object] For each event, the provided block is called with the event payload object
|
11
11
|
#
|
12
12
|
# @return [void]
|
@@ -22,7 +22,7 @@ module Ably::Modules
|
|
22
22
|
# Unsubscribe the matching block for events on the this object.
|
23
23
|
# If a block is not provided, all subscriptions will be unsubscribed
|
24
24
|
#
|
25
|
-
# @param
|
25
|
+
# @param names [String,Symbol] Optional, the event name(s) to unsubscribe from. Defaults to `:all` events
|
26
26
|
#
|
27
27
|
# @return [void]
|
28
28
|
#
|
@@ -39,10 +39,6 @@ module Ably
|
|
39
39
|
# @param (see Ably::Realtime::Client#initialize)
|
40
40
|
# @option options (see Ably::Realtime::Client#initialize)
|
41
41
|
#
|
42
|
-
# @yield (see Ably::Realtime::Client#initialize)
|
43
|
-
# @yieldparam (see Ably::Realtime::Client#initialize)
|
44
|
-
# @yieldreturn (see Ably::Realtime::Client#initialize)
|
45
|
-
#
|
46
42
|
# @return [Ably::Realtime::Client]
|
47
43
|
#
|
48
44
|
# @example
|
@@ -50,10 +46,10 @@ module Ably
|
|
50
46
|
# client = Ably::Realtime.new('key.id:secret')
|
51
47
|
#
|
52
48
|
# # create a new client authenticating with basic auth and a client_id
|
53
|
-
# client = Ably::Realtime.new(
|
49
|
+
# client = Ably::Realtime.new(key: 'key.id:secret', client_id: 'john')
|
54
50
|
#
|
55
|
-
def self.new(options
|
56
|
-
Ably::Realtime::Client.new(options
|
51
|
+
def self.new(options)
|
52
|
+
Ably::Realtime::Client.new(options)
|
57
53
|
end
|
58
54
|
end
|
59
55
|
end
|
@@ -23,7 +23,7 @@ module Ably
|
|
23
23
|
# Channel::STATE.Detached
|
24
24
|
# Channel::STATE.Failed
|
25
25
|
#
|
26
|
-
# Channels emit errors - use
|
26
|
+
# Channels emit errors - use +on(:error)+ to subscribe to errors
|
27
27
|
#
|
28
28
|
# @!attribute [r] state
|
29
29
|
# @return {Ably::Realtime::Connection::STATE} channel state
|
@@ -71,13 +71,18 @@ module Ably
|
|
71
71
|
# @api private
|
72
72
|
attr_reader :manager
|
73
73
|
|
74
|
+
# Serial number assigned to this channel when it was attached
|
75
|
+
# @return [Integer]
|
76
|
+
# @api private
|
77
|
+
attr_reader :attached_serial
|
78
|
+
|
74
79
|
# Initialize a new Channel object
|
75
80
|
#
|
76
81
|
# @param client [Ably::Rest::Client]
|
77
82
|
# @param name [String] The name of the channel
|
78
83
|
# @param channel_options [Hash] Channel options, currently reserved for Encryption options
|
79
84
|
# @option channel_options [Boolean] :encrypted setting this to true for this channel will encrypt & decrypt all messages automatically
|
80
|
-
# @option channel_options [Hash] :cipher_params A hash of options to configure the encryption. *:key* is required, all other options are optional. See {Ably::Util::Crypto#initialize} for a list of
|
85
|
+
# @option channel_options [Hash] :cipher_params A hash of options to configure the encryption. *:key* is required, all other options are optional. See {Ably::Util::Crypto#initialize} for a list of +cipher_params+ options
|
81
86
|
#
|
82
87
|
def initialize(client, name, channel_options = {})
|
83
88
|
ensure_utf_8 :name, name
|
@@ -95,7 +100,9 @@ module Ably
|
|
95
100
|
setup_presence
|
96
101
|
end
|
97
102
|
|
98
|
-
# Publish a message on the channel
|
103
|
+
# Publish a message on the channel.
|
104
|
+
#
|
105
|
+
# When publishing a message, if the channel is not attached, the channel is implicitly attached
|
99
106
|
#
|
100
107
|
# @param name [String] The event name of the message
|
101
108
|
# @param data [String,ByteArray] payload for the message
|
@@ -122,7 +129,9 @@ module Ably
|
|
122
129
|
end
|
123
130
|
end
|
124
131
|
|
125
|
-
# Subscribe to messages matching providing event name, or all messages if event name not provided
|
132
|
+
# Subscribe to messages matching providing event name, or all messages if event name not provided.
|
133
|
+
#
|
134
|
+
# When subscribing to messages, if the channel is not attached, the channel is implicitly attached
|
126
135
|
#
|
127
136
|
# @param names [String] The event name of the message to subscribe to if provided. Defaults to all events.
|
128
137
|
# @yield [Ably::Models::Message] For each message received, the block is called
|
@@ -172,6 +181,8 @@ module Ably
|
|
172
181
|
# presence on the channel and may also be used to obtain presence information
|
173
182
|
# and change events for other members of the channel.
|
174
183
|
#
|
184
|
+
# When accessing presence, if the channel is not attached, the channel is implicitly attached
|
185
|
+
#
|
175
186
|
# @return {Ably::Realtime::Presence}
|
176
187
|
#
|
177
188
|
def presence
|
@@ -181,13 +192,24 @@ module Ably
|
|
181
192
|
|
182
193
|
# Return the message history of the channel
|
183
194
|
#
|
195
|
+
# If the channel is attached, you can retrieve messages published on the channel before the
|
196
|
+
# channel was attached with the option <tt>until_attach: true</tt>. This is useful when a developer
|
197
|
+
# wishes to display historical messages with the guarantee that no messages have been missed since attach.
|
198
|
+
#
|
184
199
|
# @param (see Ably::Rest::Channel#history)
|
185
200
|
# @option options (see Ably::Rest::Channel#history)
|
201
|
+
# @option options [Boolean] :until_attach When true, the history request will be limited only to messages published before this channel was attached. Channel must be attached
|
186
202
|
#
|
187
|
-
# @yield [Ably::Models::PaginatedResource<Ably::Models::Message>]
|
203
|
+
# @yield [Ably::Models::PaginatedResource<Ably::Models::Message>] First {Ably::Models::PaginatedResource page} of {Ably::Models::Message} objects accessible with {Ably::Models::PaginatedResource#items #items}.
|
188
204
|
#
|
189
205
|
# @return [Ably::Util::SafeDeferrable]
|
206
|
+
#
|
190
207
|
def history(options = {}, &callback)
|
208
|
+
if options.delete(:until_attach)
|
209
|
+
raise ArgumentError, 'option :until_attach is invalid as the channel is not attached' unless attached?
|
210
|
+
options[:from_serial] = attached_serial
|
211
|
+
end
|
212
|
+
|
191
213
|
async_wrap(callback) do
|
192
214
|
rest_channel.history(options.merge(async_blocking_operations: true))
|
193
215
|
end
|
@@ -212,6 +234,11 @@ module Ably
|
|
212
234
|
@error_reason = nil
|
213
235
|
end
|
214
236
|
|
237
|
+
# @api private
|
238
|
+
def set_attached_serial(serial)
|
239
|
+
@attached_serial = serial
|
240
|
+
end
|
241
|
+
|
215
242
|
# Used by {Ably::Modules::StateEmitter} to debug state changes
|
216
243
|
# @api private
|
217
244
|
def logger
|
@@ -64,10 +64,6 @@ module Ably
|
|
64
64
|
# @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
|
65
65
|
# @option options [Boolean] :connect_automatically 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.
|
66
66
|
#
|
67
|
-
# @yield (see Ably::Rest::Client#initialize)
|
68
|
-
# @yieldparam (see Ably::Rest::Client#initialize)
|
69
|
-
# @yieldreturn (see Ably::Rest::Client#initialize)
|
70
|
-
#
|
71
67
|
# @return [Ably::Realtime::Client]
|
72
68
|
#
|
73
69
|
# @example
|
@@ -75,10 +71,10 @@ module Ably
|
|
75
71
|
# client = Ably::Realtime::Client.new('key.id:secret')
|
76
72
|
#
|
77
73
|
# # create a new client and configure a client ID used for presence
|
78
|
-
# client = Ably::Realtime::Client.new(
|
74
|
+
# client = Ably::Realtime::Client.new(key: 'key.id:secret', client_id: 'john')
|
79
75
|
#
|
80
|
-
def initialize(options
|
81
|
-
@rest_client = Ably::Rest::Client.new(options
|
76
|
+
def initialize(options)
|
77
|
+
@rest_client = Ably::Rest::Client.new(options)
|
82
78
|
@auth = @rest_client.auth
|
83
79
|
@channels = Ably::Realtime::Channels.new(self)
|
84
80
|
@echo_messages = @rest_client.options.fetch(:echo_messages, true) == false ? false : true
|
@@ -114,7 +110,7 @@ module Ably
|
|
114
110
|
# @param (see Ably::Rest::Client#stats)
|
115
111
|
# @option options (see Ably::Rest::Client#stats)
|
116
112
|
#
|
117
|
-
# @yield [Ably::Models::PaginatedResource<Ably::Models::
|
113
|
+
# @yield [Ably::Models::PaginatedResource<Ably::Models::Stats>] An Array of Stats
|
118
114
|
#
|
119
115
|
# @return [Ably::Util::SafeDeferrable]
|
120
116
|
#
|
@@ -10,8 +10,9 @@ module Ably
|
|
10
10
|
# connected: 2
|
11
11
|
# disconnected: 3
|
12
12
|
# suspended: 4
|
13
|
-
#
|
14
|
-
#
|
13
|
+
# closing: 5
|
14
|
+
# closed: 6
|
15
|
+
# failed: 7
|
15
16
|
#
|
16
17
|
# Note that the states are available as Enum-like constants:
|
17
18
|
#
|
@@ -20,6 +21,7 @@ module Ably
|
|
20
21
|
# Connection::STATE.Connected
|
21
22
|
# Connection::STATE.Disconnected
|
22
23
|
# Connection::STATE.Suspended
|
24
|
+
# Connection::STATE.Closing
|
23
25
|
# Connection::STATE.Closed
|
24
26
|
# Connection::STATE.Failed
|
25
27
|
#
|
@@ -150,7 +152,7 @@ module Ably
|
|
150
152
|
# @yield [Integer] if a block is passed to this method, then this block will be called once the ping heartbeat is received with the time elapsed in milliseconds
|
151
153
|
#
|
152
154
|
# @example
|
153
|
-
# client = Ably::Rest::Client.new(
|
155
|
+
# client = Ably::Rest::Client.new(key: 'key.id:secret')
|
154
156
|
# client.connection.ping do |ms_elapsed|
|
155
157
|
# puts "Ping took #{ms_elapsed}ms"
|
156
158
|
# end
|
@@ -265,14 +265,25 @@ module Ably::Realtime
|
|
265
265
|
|
266
266
|
# Return the presence messages history for the channel
|
267
267
|
#
|
268
|
+
# Once attached to a channel, you can retrieve presence message history on the channel before the
|
269
|
+
# channel was attached with the option <tt>until_attach: true</tt>. This is very useful for
|
270
|
+
# developers who wish to capture new presence events as well as retrieve historical presence state with
|
271
|
+
# the guarantee that no presence history has been missed.
|
272
|
+
#
|
268
273
|
# @param (see Ably::Rest::Presence#history)
|
269
274
|
# @option options (see Ably::Rest::Presence#history)
|
275
|
+
# @option options [Boolean] :until_attach When true, request for history will be limited only to messages published before the associated channel was attached. The associated channel must be attached.
|
270
276
|
#
|
271
|
-
# @yield [Ably::Models::PaginatedResource<Ably::Models::PresenceMessage>]
|
277
|
+
# @yield [Ably::Models::PaginatedResource<Ably::Models::PresenceMessage>] First {Ably::Models::PaginatedResource page} of {Ably::Models::PresenceMessage} objects accessible with {Ably::Models::PaginatedResource#items #items}.
|
272
278
|
#
|
273
279
|
# @return [Ably::Util::SafeDeferrable]
|
274
280
|
#
|
275
281
|
def history(options = {}, &callback)
|
282
|
+
if options.delete(:until_attach)
|
283
|
+
raise ArgumentError, 'option :until_attach cannot be specified if the channel is not attached' unless channel.attached?
|
284
|
+
options[:from_serial] = channel.attached_serial
|
285
|
+
end
|
286
|
+
|
276
287
|
async_wrap(callback) do
|
277
288
|
rest_presence.history(options.merge(async_blocking_operations: true))
|
278
289
|
end
|