ably 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -1
- data/ably.gemspec +4 -3
- data/lib/ably.rb +6 -2
- data/lib/ably/auth.rb +24 -16
- data/lib/ably/exceptions.rb +16 -5
- data/lib/ably/{realtime/models → models}/error_info.rb +9 -11
- data/lib/ably/models/idiomatic_ruby_wrapper.rb +57 -26
- data/lib/ably/{realtime/models → models}/message.rb +45 -38
- data/lib/ably/{realtime/models → models}/nil_channel.rb +4 -4
- data/lib/ably/{rest/models/paged_resource.rb → models/paginated_resource.rb} +21 -10
- data/lib/ably/models/presence_message.rb +126 -0
- data/lib/ably/{realtime/models → models}/protocol_message.rb +76 -38
- data/lib/ably/models/token.rb +74 -0
- data/lib/ably/modules/channels_collection.rb +49 -0
- data/lib/ably/modules/conversions.rb +2 -0
- data/lib/ably/modules/event_emitter.rb +43 -8
- data/lib/ably/modules/event_machine_helpers.rb +1 -0
- data/lib/ably/modules/http_helpers.rb +9 -2
- data/lib/ably/modules/message_pack.rb +14 -0
- data/lib/ably/modules/model_common.rb +29 -0
- data/lib/ably/modules/{state.rb → state_emitter.rb} +8 -7
- data/lib/ably/realtime.rb +37 -7
- data/lib/ably/realtime/channel.rb +154 -31
- data/lib/ably/realtime/channels.rb +47 -0
- data/lib/ably/realtime/client.rb +39 -33
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +50 -21
- data/lib/ably/realtime/client/outgoing_message_dispatcher.rb +9 -11
- data/lib/ably/realtime/connection.rb +148 -79
- data/lib/ably/realtime/connection/connection_state_machine.rb +111 -0
- data/lib/ably/realtime/connection/websocket_transport.rb +161 -0
- data/lib/ably/realtime/presence.rb +270 -0
- data/lib/ably/rest.rb +14 -3
- data/lib/ably/rest/channel.rb +3 -3
- data/lib/ably/rest/channels.rb +26 -12
- data/lib/ably/rest/client.rb +42 -25
- data/lib/ably/rest/middleware/exceptions.rb +21 -23
- data/lib/ably/rest/middleware/external_exceptions.rb +8 -10
- data/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +17 -0
- data/lib/ably/rest/middleware/parse_json.rb +9 -2
- data/lib/ably/rest/middleware/parse_message_pack.rb +6 -2
- data/lib/ably/rest/presence.rb +4 -4
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/channel_history_spec.rb +125 -0
- data/spec/acceptance/realtime/channel_spec.rb +135 -63
- data/spec/acceptance/realtime/connection_spec.rb +86 -0
- data/spec/acceptance/realtime/message_spec.rb +116 -94
- data/spec/acceptance/realtime/presence_history_spec.rb +0 -0
- data/spec/acceptance/realtime/presence_spec.rb +277 -0
- data/spec/acceptance/rest/auth_spec.rb +351 -347
- data/spec/acceptance/rest/base_spec.rb +43 -26
- data/spec/acceptance/rest/channel_spec.rb +88 -83
- data/spec/acceptance/rest/channels_spec.rb +32 -28
- data/spec/acceptance/rest/presence_spec.rb +83 -63
- data/spec/acceptance/rest/stats_spec.rb +38 -37
- data/spec/acceptance/rest/time_spec.rb +10 -6
- data/spec/integration/modules/{state_spec.rb → state_emitter_spec.rb} +16 -2
- data/spec/spec_helper.rb +14 -0
- data/spec/support/api_helper.rb +4 -0
- data/spec/support/model_helper.rb +28 -9
- data/spec/support/protocol_msgbus_helper.rb +8 -1
- data/spec/support/test_app.rb +24 -14
- data/spec/unit/{realtime → models}/error_info_spec.rb +4 -4
- data/spec/unit/models/idiomatic_ruby_wrapper_spec.rb +46 -9
- data/spec/unit/models/message_spec.rb +229 -0
- data/spec/unit/{rest/paged_resource_spec.rb → models/paginated_resource_spec.rb} +19 -11
- data/spec/unit/models/presence_message_spec.rb +230 -0
- data/spec/unit/models/protocol_message_spec.rb +280 -0
- data/spec/unit/{token_spec.rb → models/token_spec.rb} +18 -22
- data/spec/unit/modules/conversions_spec.rb +1 -1
- data/spec/unit/modules/event_emitter_spec.rb +36 -4
- data/spec/unit/realtime/channel_spec.rb +76 -2
- data/spec/unit/realtime/channels_spec.rb +50 -0
- data/spec/unit/realtime/client_spec.rb +31 -1
- data/spec/unit/realtime/connection_spec.rb +8 -15
- data/spec/unit/realtime/incoming_message_dispatcher_spec.rb +6 -6
- data/spec/unit/realtime/presence_spec.rb +100 -0
- data/spec/unit/rest/channels_spec.rb +48 -0
- metadata +72 -38
- data/lib/ably/realtime/models/shared.rb +0 -17
- data/lib/ably/rest/models/message.rb +0 -64
- data/lib/ably/rest/models/presence_message.rb +0 -21
- data/lib/ably/token.rb +0 -80
- data/spec/unit/realtime/message_spec.rb +0 -117
- data/spec/unit/realtime/protocol_message_spec.rb +0 -172
- data/spec/unit/rest/message_spec.rb +0 -75
data/lib/ably/rest.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
1
|
require "ably/rest/channel"
|
2
2
|
require "ably/rest/channels"
|
3
3
|
require "ably/rest/client"
|
4
|
-
require "ably/rest/models/message"
|
5
|
-
require "ably/rest/models/paged_resource"
|
6
|
-
require "ably/rest/models/presence_message"
|
7
4
|
require "ably/rest/presence"
|
8
5
|
|
6
|
+
Dir.glob(File.expand_path("ably/models/*.rb", File.dirname(__FILE__))).each do |file|
|
7
|
+
require file
|
8
|
+
end
|
9
|
+
|
9
10
|
module Ably
|
11
|
+
# Rest provides the top-level class to be instanced for the Ably Rest library
|
12
|
+
#
|
13
|
+
# @example
|
14
|
+
# client = Ably::Rest.new("xxxxx")
|
15
|
+
# channel = client.channel("test")
|
16
|
+
# channel.publish "greeting", "data"
|
17
|
+
#
|
10
18
|
module Rest
|
11
19
|
# Convenience method providing an alias to {Ably::Rest::Client} constructor.
|
12
20
|
#
|
@@ -23,6 +31,9 @@ module Ably
|
|
23
31
|
# # create a new client authenticating with basic auth
|
24
32
|
# client = Ably::Rest.new('key.id:secret')
|
25
33
|
#
|
34
|
+
# # create a new client authenticating with basic auth and a client_id
|
35
|
+
# client = Ably::Rest.new(api_key: 'key.id:secret', client_id: 'john')
|
36
|
+
#
|
26
37
|
def self.new(options, &auth_block)
|
27
38
|
Ably::Rest::Client.new(options, &auth_block)
|
28
39
|
end
|
data/lib/ably/rest/channel.rb
CHANGED
@@ -31,7 +31,7 @@ module Ably
|
|
31
31
|
|
32
32
|
response = client.post("#{base_path}/publish", payload)
|
33
33
|
|
34
|
-
response.status
|
34
|
+
[201, 204].include?(response.status)
|
35
35
|
end
|
36
36
|
|
37
37
|
# Return the message history of the channel
|
@@ -43,7 +43,7 @@ module Ably
|
|
43
43
|
# @option options [Integer] :limit Maximum number of messages to retrieve up to 10,000
|
44
44
|
# @option options [Symbol] :by `:message`, `:bundle` or `:hour`. Defaults to `:message`
|
45
45
|
#
|
46
|
-
# @return [Models::
|
46
|
+
# @return [Ably::Models::PaginatedResource<Ably::Models::Message>] An Array of hashes representing the message history that supports paging (next, first)
|
47
47
|
def history(options = {})
|
48
48
|
url = "#{base_path}/messages"
|
49
49
|
|
@@ -52,7 +52,7 @@ module Ably
|
|
52
52
|
|
53
53
|
response = client.get(url, options.merge(merge_options))
|
54
54
|
|
55
|
-
Models::
|
55
|
+
Ably::Models::PaginatedResource.new(response, url, client, coerce_into: 'Ably::Models::Message')
|
56
56
|
end
|
57
57
|
|
58
58
|
def presence
|
data/lib/ably/rest/channels.rb
CHANGED
@@ -1,29 +1,43 @@
|
|
1
1
|
module Ably
|
2
2
|
module Rest
|
3
3
|
class Channels
|
4
|
-
|
4
|
+
include Ably::Modules::ChannelsCollection
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# {Ably::Rest::Channels} provides simple accessor methods to access a {Ably::Rest::Channel} object
|
6
|
+
# @return [Ably::Rest::Channels]
|
9
7
|
def initialize(client)
|
10
|
-
|
11
|
-
@channels = {}
|
8
|
+
super client, Ably::Rest::Channel
|
12
9
|
end
|
13
10
|
|
14
|
-
#
|
11
|
+
# @!method get(name, channel_options = {})
|
12
|
+
# Return a {Ably::Rest::Channel} for the given name
|
15
13
|
#
|
16
14
|
# @param name [String] The name of the channel
|
17
15
|
# @param channel_options [Hash] Channel options, currently reserved for Encryption options
|
16
|
+
# @return [Ably::Rest::Channel}
|
17
|
+
def get(*args)
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
# @!method fetch(name, &missing_block)
|
22
|
+
# Return a {Ably::Rest::Channel} for the given name if it exists, else the block will be called.
|
23
|
+
# This method is intentionally similar to {http://ruby-doc.org/core-2.1.3/Hash.html#method-i-fetch Hash#fetch} providing a simple way to check if a channel exists or not without creating one
|
18
24
|
#
|
25
|
+
# @param name [String] The name of the channel
|
26
|
+
# @yield [options] (optional) if a missing_block is passed to this method and no channel exists matching the name, this block is called
|
27
|
+
# @yieldparam [String] name of the missing channel
|
19
28
|
# @return [Ably::Rest::Channel]
|
20
|
-
def
|
21
|
-
|
29
|
+
def fetch(*args)
|
30
|
+
super
|
22
31
|
end
|
23
|
-
alias_method :[], :get
|
24
32
|
|
25
|
-
|
26
|
-
|
33
|
+
# Destroy the {Ably::Rest::Channel} and releases the associated resources.
|
34
|
+
#
|
35
|
+
# Releasing a {Ably::Rest::Channel} is not typically necessary as a channel consumes no resources other than the memory footprint of the
|
36
|
+
# {Ably::Rest::Channel} object. Explicitly release channels to free up resources if required
|
37
|
+
#
|
38
|
+
# @return [void]
|
39
|
+
def release(*args)
|
40
|
+
super
|
27
41
|
end
|
28
42
|
end
|
29
43
|
end
|
data/lib/ably/rest/client.rb
CHANGED
@@ -14,10 +14,12 @@ module Ably
|
|
14
14
|
# @return [String] A client ID, used for identifying this client for presence purposes
|
15
15
|
# @!attribute [r] auth_options
|
16
16
|
# @return [Hash] {Ably::Auth} options configured for this client
|
17
|
-
# @!attribute [r] tls
|
18
|
-
# @return [Boolean] True if client is configured to use TLS for all Ably communication
|
19
17
|
# @!attribute [r] environment
|
20
18
|
# @return [String] May contain 'sandbox' when testing the client library against an alternate Ably environment
|
19
|
+
# @!attribute [r] log_level
|
20
|
+
# @return [Logger::Severity] Log level configured for this {Client}
|
21
|
+
# @!attribute [r] channels
|
22
|
+
# @return [Aby::Rest::Channels] The collection of {Ably::Rest::Channel}s that have been created
|
21
23
|
class Client
|
22
24
|
include Ably::Modules::Conversions
|
23
25
|
include Ably::Modules::HttpHelpers
|
@@ -25,18 +27,24 @@ module Ably
|
|
25
27
|
|
26
28
|
DOMAIN = "rest.ably.io"
|
27
29
|
|
28
|
-
attr_reader :
|
30
|
+
attr_reader :environment, :protocol, :auth, :channels, :log_level
|
29
31
|
def_delegators :auth, :client_id, :auth_options
|
30
32
|
|
33
|
+
# The additional options passed to this Client's #initialize method not available as attributes of this class
|
34
|
+
# @return [Hash]
|
35
|
+
# @api private
|
36
|
+
attr_reader :options
|
37
|
+
|
31
38
|
# Creates a {Ably::Rest::Client Rest Client} and configures the {Ably::Auth} object for the connection.
|
32
39
|
#
|
33
40
|
# @param [Hash,String] options an options Hash used to configure the client and the authentication, or String with an API key
|
34
41
|
# @option options (see Ably::Auth#authorise)
|
35
|
-
# @option options [Boolean]
|
36
|
-
# @option options [String]
|
37
|
-
# @option options [String]
|
38
|
-
# @option options [Symbol]
|
39
|
-
# @option options [
|
42
|
+
# @option options [Boolean] :tls TLS is used by default, providing a value of false disbles TLS. Please note Basic Auth is disallowed without TLS as secrets cannot be transmitted over unsecured connections.
|
43
|
+
# @option options [String] :api_key API key comprising the key ID and key secret in a single string
|
44
|
+
# @option options [String] :environment Specify 'sandbox' when testing the client library against an alternate Ably environment
|
45
|
+
# @option options [Symbol] :protocol Protocol used to communicate with Ably, :json and :msgpack currently supported. Defaults to :msgpack
|
46
|
+
# @option options [Boolean] :use_binary_protocol Protocol used to communicate with Ably, defaults to true and uses MessagePack protocol. This option will overide :protocol option
|
47
|
+
# @option options [Logger::Severity,Symbol] :log_level 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)
|
40
48
|
#
|
41
49
|
# @yield (see Ably::Auth#authorise)
|
42
50
|
# @yieldparam (see Ably::Auth#authorise)
|
@@ -53,19 +61,28 @@ module Ably
|
|
53
61
|
#
|
54
62
|
def initialize(options, &auth_block)
|
55
63
|
options = options.clone
|
56
|
-
|
57
64
|
if options.kind_of?(String)
|
58
65
|
options = { api_key: options }
|
59
66
|
end
|
60
67
|
|
61
68
|
@tls = options.delete(:tls) == false ? false : true
|
62
69
|
@environment = options.delete(:environment) # nil is production
|
63
|
-
@protocol = options.delete(:protocol) || :
|
70
|
+
@protocol = options.delete(:protocol) || :msgpack
|
64
71
|
@debug_http = options.delete(:debug_http)
|
65
|
-
@log_level = options.delete(:log_level) || Logger::
|
72
|
+
@log_level = options.delete(:log_level) || Logger::ERROR
|
66
73
|
|
74
|
+
@log_level = Logger.const_get(log_level.to_s.upcase) if log_level.kind_of?(Symbol) || log_level.kind_of?(String)
|
75
|
+
|
76
|
+
options.delete(:use_binary_protocol).tap do |use_binary_protocol|
|
77
|
+
if use_binary_protocol == true
|
78
|
+
@protocol = :msgpack
|
79
|
+
elsif use_binary_protocol == false
|
80
|
+
@protocol = :json
|
81
|
+
end
|
82
|
+
end
|
67
83
|
raise ArgumentError, 'Protocol is invalid. Must be either :msgpack or :json' unless [:msgpack, :json].include?(@protocol)
|
68
84
|
|
85
|
+
@options = options.freeze
|
69
86
|
@auth = Auth.new(self, options, &auth_block)
|
70
87
|
@channels = Ably::Rest::Channels.new(self)
|
71
88
|
end
|
@@ -79,7 +96,7 @@ module Ably
|
|
79
96
|
channels.get(name, channel_options)
|
80
97
|
end
|
81
98
|
|
82
|
-
#
|
99
|
+
# Retrieve the stats for the application
|
83
100
|
#
|
84
101
|
# @return [Array] An Array of hashes representing the stats
|
85
102
|
def stats(params = {})
|
@@ -95,7 +112,7 @@ module Ably
|
|
95
112
|
end
|
96
113
|
end
|
97
114
|
|
98
|
-
#
|
115
|
+
# Retrieve the Ably service time
|
99
116
|
#
|
100
117
|
# @return [Time] The time as reported by the Ably service
|
101
118
|
def time
|
@@ -104,9 +121,8 @@ module Ably
|
|
104
121
|
as_time_from_epoch(response.body.first)
|
105
122
|
end
|
106
123
|
|
107
|
-
#
|
108
|
-
#
|
109
|
-
# @return [Boolean]
|
124
|
+
# @!attribute [r] use_tls?
|
125
|
+
# @return [Boolean] True if client is configured to use TLS for all Ably communication
|
110
126
|
def use_tls?
|
111
127
|
@tls == true
|
112
128
|
end
|
@@ -125,9 +141,8 @@ module Ably
|
|
125
141
|
request(:post, path, params, options)
|
126
142
|
end
|
127
143
|
|
128
|
-
#
|
129
|
-
#
|
130
|
-
# @return [URI::Generic]
|
144
|
+
# @!attribute [r] endpoint
|
145
|
+
# @return [URI::Generic] Default Ably REST endpoint used for all requests
|
131
146
|
def endpoint
|
132
147
|
URI::Generic.build(
|
133
148
|
scheme: use_tls? ? "https" : "http",
|
@@ -135,15 +150,17 @@ module Ably
|
|
135
150
|
)
|
136
151
|
end
|
137
152
|
|
153
|
+
# @!attribute [r] logger
|
154
|
+
# @return [Logger] The Logger configured for this client when the client was instantiated.
|
155
|
+
# Configure the log_level with the `:log_level` option, refer to {Client#initialize}
|
138
156
|
def logger
|
139
157
|
@logger ||= Logger.new(STDOUT).tap do |logger|
|
140
158
|
logger.level = log_level
|
141
159
|
end
|
142
160
|
end
|
143
161
|
|
144
|
-
#
|
145
|
-
#
|
146
|
-
# @return [String]
|
162
|
+
# @!attribute [r] mime_type
|
163
|
+
# @return [String] Mime type used for HTTP requests
|
147
164
|
def mime_type
|
148
165
|
case protocol
|
149
166
|
when :json
|
@@ -174,7 +191,7 @@ module Ably
|
|
174
191
|
auth.authorise force: true
|
175
192
|
retry
|
176
193
|
else
|
177
|
-
raise Ably::Exceptions::InvalidToken.new(e.message,
|
194
|
+
raise Ably::Exceptions::InvalidToken.new(e.message, e.status, e.code)
|
178
195
|
end
|
179
196
|
end
|
180
197
|
end
|
@@ -208,16 +225,16 @@ module Ably
|
|
208
225
|
# @see http://mislav.uniqpath.com/2011/07/faraday-advanced-http/
|
209
226
|
def middleware
|
210
227
|
@middleware ||= Faraday::RackBuilder.new do |builder|
|
211
|
-
|
228
|
+
setup_outgoing_middleware builder
|
212
229
|
|
213
230
|
# Raise exceptions if response code is invalid
|
214
231
|
builder.use Ably::Rest::Middleware::Exceptions
|
215
232
|
|
233
|
+
setup_incoming_middleware builder, fail_if_unsupported_mime_type: true
|
216
234
|
|
217
235
|
# Log HTTP requests if log level is DEBUG option set
|
218
236
|
builder.response :logger if log_level == Logger::DEBUG
|
219
237
|
|
220
|
-
|
221
238
|
# Set Faraday's HTTP adapter
|
222
239
|
builder.adapter Faraday.default_adapter
|
223
240
|
end
|
@@ -4,35 +4,33 @@ module Ably
|
|
4
4
|
module Rest
|
5
5
|
module Middleware
|
6
6
|
# HTTP exceptions raised by Ably due to an error status code
|
7
|
-
# Ably returns JSON error codes and messages so include this if possible in the exception messages
|
7
|
+
# Ably returns JSON/Msgpack error codes and messages so include this if possible in the exception messages
|
8
8
|
class Exceptions < Faraday::Response::Middleware
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
error_code = nil
|
9
|
+
def on_complete(env)
|
10
|
+
if env.status >= 400
|
11
|
+
error_status_code = env.status
|
12
|
+
error_code = nil
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
if env.body.kind_of?(Hash)
|
15
|
+
error = env.body.fetch('error', {})
|
16
|
+
error_status_code = error['statusCode'].to_i if error['statusCode']
|
17
|
+
error_code = error['code'].to_i if error['code']
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
rescue JSON::ParserError
|
26
|
-
message = env[:body]
|
19
|
+
if error
|
20
|
+
message = "#{error['message']} (status: #{error_status_code}, code: #{error_code})"
|
21
|
+
else
|
22
|
+
message = env.body
|
27
23
|
end
|
24
|
+
else
|
25
|
+
message = env.body
|
26
|
+
end
|
28
27
|
|
29
|
-
|
28
|
+
message = "Unknown server error" if message.to_s.strip == ''
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
30
|
+
if env.status >= 500
|
31
|
+
raise Ably::Exceptions::ServerError, message
|
32
|
+
else
|
33
|
+
raise Ably::Exceptions::InvalidRequest.new(message, error_status_code, error_code)
|
36
34
|
end
|
37
35
|
end
|
38
36
|
end
|
@@ -6,17 +6,15 @@ module Ably
|
|
6
6
|
# HTTP exceptions raised due to a status code error on a 3rd party site
|
7
7
|
# Used by auth calls
|
8
8
|
class ExternalExceptions < Faraday::Response::Middleware
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
message = "Error #{error_status_code}: #{(env[:body] || '')[0...200]}"
|
9
|
+
def on_complete(env)
|
10
|
+
if env.status >= 400
|
11
|
+
error_status_code = env.status
|
12
|
+
message = "Error #{error_status_code}: #{(env.body || '')[0...200]}"
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
14
|
+
if error_status_code >= 500
|
15
|
+
raise Ably::Exceptions::ServerError, message
|
16
|
+
else
|
17
|
+
raise Ably::Exceptions::InvalidRequest, message
|
20
18
|
end
|
21
19
|
end
|
22
20
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Ably
|
5
|
+
module Rest
|
6
|
+
module Middleware
|
7
|
+
class FailIfUnsupportedMimeType < Faraday::Response::Middleware
|
8
|
+
def on_complete(env)
|
9
|
+
unless env.response_headers['Ably-Middleware-Parsed'] == true
|
10
|
+
raise Ably::Exceptions::InvalidResponseBody,
|
11
|
+
"Content Type #{env.response_headers['Content-Type']} is not supported by this client library"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -6,11 +6,18 @@ module Ably
|
|
6
6
|
module Middleware
|
7
7
|
class ParseJson < Faraday::Response::Middleware
|
8
8
|
def on_complete(env)
|
9
|
-
|
9
|
+
if env.response_headers['Content-Type'] == 'application/json'
|
10
|
+
env.body = parse(env.body) unless env.response_headers['Ably-Middleware-Parsed'] == true
|
11
|
+
env.response_headers['Ably-Middleware-Parsed'] = true
|
12
|
+
end
|
10
13
|
end
|
11
14
|
|
12
15
|
def parse(body)
|
13
|
-
|
16
|
+
if body.length > 0
|
17
|
+
JSON.parse(body)
|
18
|
+
else
|
19
|
+
body
|
20
|
+
end
|
14
21
|
rescue JSON::ParserError => e
|
15
22
|
raise Ably::Exceptions::InvalidResponseBody, "Expected JSON response: #{e.message}"
|
16
23
|
end
|
@@ -7,13 +7,17 @@ module Ably
|
|
7
7
|
class ParseMessagePack < Faraday::Response::Middleware
|
8
8
|
def on_complete(env)
|
9
9
|
if env.response_headers['Content-Type'] == 'application/x-msgpack'
|
10
|
-
env.body = parse(env.body)
|
10
|
+
env.body = parse(env.body) unless env.response_headers['Ably-Middleware-Parsed'] == true
|
11
11
|
env.response_headers['Ably-Middleware-Parsed'] = true
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
15
|
def parse(body)
|
16
|
-
|
16
|
+
if body.length > 0
|
17
|
+
MessagePack.unpack(body)
|
18
|
+
else
|
19
|
+
body
|
20
|
+
end
|
17
21
|
rescue MessagePack::MalformedFormatError => e
|
18
22
|
raise Ably::Exceptions::InvalidResponseBody, "Expected MessagePack response: #{e.message}"
|
19
23
|
end
|
data/lib/ably/rest/presence.rb
CHANGED
@@ -16,11 +16,11 @@ module Ably
|
|
16
16
|
|
17
17
|
# Obtain the set of members currently present for a channel
|
18
18
|
#
|
19
|
-
# @return [Models::
|
19
|
+
# @return [Ably::Models::PaginatedResource<Ably::Models::PresenceMessage>] An Array of presence-message Hash objects that supports paging (next, first)
|
20
20
|
#
|
21
21
|
def get(options = {})
|
22
22
|
response = client.get(base_path, options)
|
23
|
-
Models::
|
23
|
+
Ably::Models::PaginatedResource.new(response, base_path, client, coerce_into: 'Ably::Models::PresenceMessage')
|
24
24
|
end
|
25
25
|
|
26
26
|
# Return the presence messages history for the channel
|
@@ -31,7 +31,7 @@ module Ably
|
|
31
31
|
# @option options [Symbol] :direction `:forwards` or `:backwards`
|
32
32
|
# @option options [Integer] :limit Maximum number of presence messages to retrieve up to 10,000
|
33
33
|
#
|
34
|
-
# @return [Models::
|
34
|
+
# @return [Ably::Models::PaginatedResource<Ably::Models::PresenceMessage>] An Array of presence-message Hash objects that supports paging (next, first)
|
35
35
|
#
|
36
36
|
def history(options = {})
|
37
37
|
url = "#{base_path}/history"
|
@@ -41,7 +41,7 @@ module Ably
|
|
41
41
|
|
42
42
|
response = client.get(url, options.merge(merge_options))
|
43
43
|
|
44
|
-
Models::
|
44
|
+
Ably::Models::PaginatedResource.new(response, url, client, coerce_into: 'Ably::Models::PresenceMessage')
|
45
45
|
end
|
46
46
|
|
47
47
|
private
|