ably 0.1.6 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +9 -0
- data/LICENSE.txt +1 -1
- data/README.md +8 -1
- data/Rakefile +10 -0
- data/ably.gemspec +18 -18
- data/lib/ably.rb +6 -5
- data/lib/ably/auth.rb +11 -14
- data/lib/ably/exceptions.rb +18 -15
- data/lib/ably/logger.rb +102 -0
- data/lib/ably/models/error_info.rb +1 -1
- data/lib/ably/models/message.rb +19 -5
- data/lib/ably/models/message_encoders/base.rb +107 -0
- data/lib/ably/models/message_encoders/base64.rb +39 -0
- data/lib/ably/models/message_encoders/cipher.rb +80 -0
- data/lib/ably/models/message_encoders/json.rb +33 -0
- data/lib/ably/models/message_encoders/utf8.rb +33 -0
- data/lib/ably/models/paginated_resource.rb +23 -6
- data/lib/ably/models/presence_message.rb +19 -7
- data/lib/ably/models/protocol_message.rb +5 -4
- data/lib/ably/models/token.rb +2 -2
- data/lib/ably/modules/channels_collection.rb +0 -3
- data/lib/ably/modules/conversions.rb +3 -3
- data/lib/ably/modules/encodeable.rb +68 -0
- data/lib/ably/modules/event_emitter.rb +10 -4
- data/lib/ably/modules/event_machine_helpers.rb +6 -4
- data/lib/ably/modules/http_helpers.rb +7 -2
- data/lib/ably/modules/model_common.rb +2 -0
- data/lib/ably/modules/state_emitter.rb +10 -1
- data/lib/ably/realtime.rb +19 -12
- data/lib/ably/realtime/channel.rb +26 -13
- data/lib/ably/realtime/client.rb +31 -7
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +14 -3
- data/lib/ably/realtime/client/outgoing_message_dispatcher.rb +13 -4
- data/lib/ably/realtime/connection.rb +152 -46
- data/lib/ably/realtime/connection/connection_manager.rb +168 -0
- data/lib/ably/realtime/connection/connection_state_machine.rb +56 -33
- data/lib/ably/realtime/connection/websocket_transport.rb +56 -29
- data/lib/ably/{models → realtime/models}/nil_channel.rb +1 -1
- data/lib/ably/realtime/presence.rb +38 -13
- data/lib/ably/rest.rb +7 -5
- data/lib/ably/rest/channel.rb +24 -3
- data/lib/ably/rest/client.rb +56 -17
- data/lib/ably/rest/middleware/encoder.rb +49 -0
- data/lib/ably/rest/middleware/exceptions.rb +3 -2
- data/lib/ably/rest/middleware/logger.rb +37 -0
- data/lib/ably/rest/presence.rb +10 -2
- data/lib/ably/util/crypto.rb +57 -29
- data/lib/ably/util/pub_sub.rb +11 -0
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/channel_spec.rb +65 -7
- data/spec/acceptance/realtime/connection_spec.rb +123 -27
- data/spec/acceptance/realtime/message_spec.rb +319 -34
- data/spec/acceptance/realtime/presence_history_spec.rb +58 -0
- data/spec/acceptance/realtime/presence_spec.rb +160 -18
- data/spec/acceptance/rest/auth_spec.rb +93 -49
- data/spec/acceptance/rest/base_spec.rb +10 -10
- data/spec/acceptance/rest/channel_spec.rb +35 -19
- data/spec/acceptance/rest/channels_spec.rb +8 -8
- data/spec/acceptance/rest/message_spec.rb +224 -0
- data/spec/acceptance/rest/presence_spec.rb +159 -23
- data/spec/acceptance/rest/stats_spec.rb +5 -5
- data/spec/acceptance/rest/time_spec.rb +4 -4
- data/spec/integration/rest/auth.rb +1 -1
- data/spec/resources/crypto-data-128.json +56 -0
- data/spec/resources/crypto-data-256.json +56 -0
- data/spec/rspec_config.rb +39 -0
- data/spec/spec_helper.rb +4 -42
- data/spec/support/api_helper.rb +1 -1
- data/spec/support/event_machine_helper.rb +0 -5
- data/spec/support/protocol_msgbus_helper.rb +3 -3
- data/spec/support/test_app.rb +3 -3
- data/spec/unit/logger_spec.rb +135 -0
- data/spec/unit/models/message_encoders/base64_spec.rb +181 -0
- data/spec/unit/models/message_encoders/cipher_spec.rb +260 -0
- data/spec/unit/models/message_encoders/json_spec.rb +135 -0
- data/spec/unit/models/message_encoders/utf8_spec.rb +100 -0
- data/spec/unit/models/message_spec.rb +16 -1
- data/spec/unit/models/paginated_resource_spec.rb +46 -0
- data/spec/unit/models/presence_message_spec.rb +18 -5
- data/spec/unit/models/token_spec.rb +1 -1
- data/spec/unit/modules/event_emitter_spec.rb +24 -10
- data/spec/unit/realtime/channel_spec.rb +3 -3
- data/spec/unit/realtime/channels_spec.rb +1 -1
- data/spec/unit/realtime/client_spec.rb +44 -2
- data/spec/unit/realtime/connection_spec.rb +2 -2
- data/spec/unit/realtime/incoming_message_dispatcher_spec.rb +4 -4
- data/spec/unit/realtime/presence_spec.rb +1 -1
- data/spec/unit/realtime/realtime_spec.rb +3 -3
- data/spec/unit/realtime/websocket_transport_spec.rb +24 -0
- data/spec/unit/rest/channels_spec.rb +1 -1
- data/spec/unit/rest/client_spec.rb +45 -10
- data/spec/unit/util/crypto_spec.rb +82 -0
- data/spec/unit/{modules → util}/pub_sub_spec.rb +13 -1
- metadata +43 -12
- data/spec/acceptance/crypto.rb +0 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d814eac0ae04dc623743bbe5973e80a58662056d
|
4
|
+
data.tar.gz: 95426e76baeaee6fbc297031b83cc128e5bed688
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b660702de87dec06d7f982ea110d59310ba1f9a130be320bd2ec7a40f777b2e5452cfa4f97f6a08a0cf751646326f53196e7cf3a39c023ce55795583309ad4db
|
7
|
+
data.tar.gz: 8088bb09de07b180385a4e817827ef2d867ccb2c6645f55c68888bfaf932df7f2a7c2ec7392b3aa1471a5045beda59d0f93fa5775171ca99b1a1083b3fca2037
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# [Ably](https://ably.io)
|
2
2
|
|
3
|
+
[![Build Status](https://travis-ci.org/ably/ably-ruby.png)](https://travis-ci.org/ably/ably-ruby)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/ably.svg)](http://badge.fury.io/rb/ably)
|
5
|
+
|
3
6
|
A Ruby client library for [ably.io](https://ably.io), the real-time messaging service.
|
4
7
|
|
5
8
|
## Installation
|
@@ -60,7 +63,7 @@ channel.publish("greeting", "Hello World!")
|
|
60
63
|
```ruby
|
61
64
|
client = Ably::Realtime.new(api_key: "xxxxx")
|
62
65
|
channel = client.channel("test")
|
63
|
-
channel.presence.enter(
|
66
|
+
channel.presence.enter(data: 'john.doe') do |presence|
|
64
67
|
presence.get #=> [Array of members present]
|
65
68
|
end
|
66
69
|
```
|
@@ -106,6 +109,10 @@ client = Ably::Rest.new(api_key: "xxxxx")
|
|
106
109
|
client.time #=> 2013-12-12 14:23:34 +0000
|
107
110
|
```
|
108
111
|
|
112
|
+
## Dependencies
|
113
|
+
|
114
|
+
If you only need to use the REST features of this library and do not want EventMachine as a dependency, then you should use the [Ably Ruby REST gem](https://rubygems.org/gems/ably-rest).
|
115
|
+
|
109
116
|
## Contributing
|
110
117
|
|
111
118
|
1. Fork it
|
data/Rakefile
CHANGED
data/ably.gemspec
CHANGED
@@ -4,31 +4,31 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'ably/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'ably'
|
8
8
|
spec.version = Ably::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ['Lewis Marshall', "Matthew O'Riordan"]
|
10
|
+
spec.email = ['lewis@lmars.net', 'matt@ably.io']
|
11
11
|
spec.description = %q{A Ruby client library for ably.io, the real-time messaging service}
|
12
12
|
spec.summary = %q{A Ruby client library for ably.io, the real-time messaging service}
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
13
|
+
spec.homepage = 'http://github.com/ably/ably-ruby'
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_runtime_dependency
|
22
|
-
spec.add_runtime_dependency
|
23
|
-
spec.add_runtime_dependency
|
24
|
-
spec.add_runtime_dependency
|
25
|
-
spec.add_runtime_dependency
|
26
|
-
spec.add_runtime_dependency
|
21
|
+
spec.add_runtime_dependency 'eventmachine', '~> 1.0'
|
22
|
+
spec.add_runtime_dependency 'statesman', '~> 1.0.0'
|
23
|
+
spec.add_runtime_dependency 'faraday', '~> 0.9'
|
24
|
+
spec.add_runtime_dependency 'json'
|
25
|
+
spec.add_runtime_dependency 'websocket-driver', '~> 0.3'
|
26
|
+
spec.add_runtime_dependency 'msgpack-ably', '~> 0.5.10'
|
27
27
|
|
28
|
-
spec.add_development_dependency
|
29
|
-
spec.add_development_dependency
|
30
|
-
spec.add_development_dependency
|
31
|
-
spec.add_development_dependency
|
32
|
-
spec.add_development_dependency
|
33
|
-
spec.add_development_dependency
|
28
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
29
|
+
spec.add_development_dependency 'rake'
|
30
|
+
spec.add_development_dependency 'redcarpet'
|
31
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
32
|
+
spec.add_development_dependency 'yard'
|
33
|
+
spec.add_development_dependency 'webmock'
|
34
34
|
end
|
data/lib/ably.rb
CHANGED
@@ -4,11 +4,12 @@
|
|
4
4
|
end
|
5
5
|
end
|
6
6
|
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
7
|
+
require 'ably/auth'
|
8
|
+
require 'ably/exceptions'
|
9
|
+
require 'ably/logger'
|
10
|
+
require 'ably/realtime'
|
11
|
+
require 'ably/rest'
|
12
|
+
require 'ably/version'
|
12
13
|
|
13
14
|
# Ably is the base namespace for the Ably {Ably::Realtime Realtime} & {Ably::Rest Rest} client libraries.
|
14
15
|
#
|
data/lib/ably/auth.rb
CHANGED
@@ -2,7 +2,7 @@ require 'json'
|
|
2
2
|
require 'faraday'
|
3
3
|
require 'securerandom'
|
4
4
|
|
5
|
-
require
|
5
|
+
require 'ably/rest/middleware/external_exceptions'
|
6
6
|
|
7
7
|
module Ably
|
8
8
|
# Auth is responsible for authentication with {https://ably.io Ably} using basic or token authentication
|
@@ -44,26 +44,26 @@ module Ably
|
|
44
44
|
@auth_callback = auth_block if block_given?
|
45
45
|
|
46
46
|
unless auth_options.kind_of?(Hash)
|
47
|
-
raise ArgumentError,
|
47
|
+
raise ArgumentError, 'Expected auth_options to be a Hash'
|
48
48
|
end
|
49
49
|
|
50
50
|
if auth_options[:api_key] && (auth_options[:key_secret] || auth_options[:key_id])
|
51
|
-
raise ArgumentError,
|
51
|
+
raise ArgumentError, 'api_key and key_id or key_secret are mutually exclusive. Provider either an api_key or key_id & key_secret'
|
52
52
|
end
|
53
53
|
|
54
54
|
if auth_options[:api_key]
|
55
55
|
api_key_parts = auth_options[:api_key].to_s.match(/(?<id>[\w_-]+\.[\w_-]+):(?<secret>[\w_-]+)/)
|
56
|
-
raise ArgumentError,
|
56
|
+
raise ArgumentError, 'api_key is invalid' unless api_key_parts
|
57
57
|
auth_options[:key_id] = api_key_parts[:id]
|
58
58
|
auth_options[:key_secret] = api_key_parts[:secret]
|
59
59
|
end
|
60
60
|
|
61
61
|
if using_basic_auth? && !api_key_present?
|
62
|
-
raise ArgumentError,
|
62
|
+
raise ArgumentError, 'api_key is missing. Either an API key, token, or token auth method must be provided'
|
63
63
|
end
|
64
64
|
|
65
65
|
if has_client_id? && !api_key_present?
|
66
|
-
raise ArgumentError,
|
66
|
+
raise ArgumentError, 'client_id cannot be provided without a complete API key. Key ID & Secret is needed to authenticate with Ably and obtain a token'
|
67
67
|
end
|
68
68
|
|
69
69
|
@options.freeze
|
@@ -162,7 +162,7 @@ module Ably
|
|
162
162
|
|
163
163
|
token_request = IdiomaticRubyWrapper(token_request)
|
164
164
|
|
165
|
-
response = client.post("/keys/#{token_request.fetch(:id)}/requestToken", token_request, send_auth_header: false)
|
165
|
+
response = client.post("/keys/#{token_request.fetch(:id)}/requestToken", token_request.hash, send_auth_header: false)
|
166
166
|
body = IdiomaticRubyWrapper(response.body)
|
167
167
|
|
168
168
|
Ably::Models::Token.new(body.fetch(:access_token))
|
@@ -199,7 +199,7 @@ module Ably
|
|
199
199
|
request_key_id = token_options.delete(:key_id) || key_id
|
200
200
|
request_key_secret = token_options.delete(:key_secret) || key_secret
|
201
201
|
|
202
|
-
raise Ably::Exceptions::TokenRequestError,
|
202
|
+
raise Ably::Exceptions::TokenRequestError, 'Key ID and Key Secret are required to generate a new token request' unless request_key_id && request_key_secret
|
203
203
|
|
204
204
|
timestamp = if token_options[:query_time]
|
205
205
|
client.time
|
@@ -294,7 +294,7 @@ module Ably
|
|
294
294
|
|
295
295
|
# Basic Auth HTTP Authorization header value
|
296
296
|
def basic_auth_header
|
297
|
-
raise Ably::Exceptions::InsecureRequestError,
|
297
|
+
raise Ably::Exceptions::InsecureRequestError, 'Cannot use Basic Auth over non-TLS connections' unless client.use_tls?
|
298
298
|
"Basic #{encode64("#{api_key}")}"
|
299
299
|
end
|
300
300
|
|
@@ -313,7 +313,7 @@ module Ably
|
|
313
313
|
|
314
314
|
# Basic Auth params to authenticate the Realtime connection
|
315
315
|
def basic_auth_params
|
316
|
-
raise Ably::Exceptions::InsecureRequestError,
|
316
|
+
raise Ably::Exceptions::InsecureRequestError, 'Cannot use Basic Auth over non-TLS connections' unless client.use_tls?
|
317
317
|
# TODO: Change to key_secret when API is updated
|
318
318
|
{
|
319
319
|
key_id: key_id,
|
@@ -395,10 +395,7 @@ module Ably
|
|
395
395
|
# Raise exceptions if response code is invalid
|
396
396
|
builder.use Ably::Rest::Middleware::ExternalExceptions
|
397
397
|
|
398
|
-
setup_incoming_middleware builder
|
399
|
-
|
400
|
-
# Log HTTP requests if log level is DEBUG option set
|
401
|
-
builder.response :logger if client.log_level == Logger::DEBUG
|
398
|
+
setup_incoming_middleware builder, client.logger
|
402
399
|
|
403
400
|
# Set Faraday's HTTP adapter
|
404
401
|
builder.adapter Faraday.default_adapter
|
data/lib/ably/exceptions.rb
CHANGED
@@ -9,7 +9,7 @@ module Ably
|
|
9
9
|
# @return [String] HTTP status code of error
|
10
10
|
# @!attribute [r] code
|
11
11
|
# @return [String] Ably specific error code
|
12
|
-
class
|
12
|
+
class BaseAblyException < StandardError
|
13
13
|
attr_reader :status, :code
|
14
14
|
def initialize(message, status = nil, code = nil)
|
15
15
|
super message
|
@@ -19,7 +19,23 @@ module Ably
|
|
19
19
|
end
|
20
20
|
|
21
21
|
# An invalid request was received by Ably
|
22
|
-
class InvalidRequest <
|
22
|
+
class InvalidRequest < BaseAblyException; end
|
23
|
+
|
24
|
+
# The token is invalid
|
25
|
+
class InvalidToken < BaseAblyException; end
|
26
|
+
|
27
|
+
# Ably Protocol message received that is invalid
|
28
|
+
class ProtocolError < BaseAblyException; end
|
29
|
+
|
30
|
+
# Encryption or Decryption failure
|
31
|
+
class CipherError < BaseAblyException; end
|
32
|
+
|
33
|
+
# Encoding or decoding failure
|
34
|
+
class EncoderError < BaseAblyException; end
|
35
|
+
|
36
|
+
# A generic Ably exception taht supports a status & code.
|
37
|
+
# See https://github.com/ably/ably-common/blob/master/protocol/errors.json for a list of Ably errors
|
38
|
+
class Standard < BaseAblyException; end
|
23
39
|
|
24
40
|
# The HTTP request has returned a 500 error
|
25
41
|
class ServerError < StandardError; end
|
@@ -35,18 +51,5 @@ module Ably
|
|
35
51
|
|
36
52
|
# The token request could not be created
|
37
53
|
class TokenRequestError < StandardError; end
|
38
|
-
|
39
|
-
# The token is invalid
|
40
|
-
class InvalidToken < Base; end
|
41
|
-
|
42
|
-
# Encryption or decryption related failures
|
43
|
-
class EncryptionError < StandardError; end
|
44
|
-
|
45
|
-
# Ably Protocol message received that is invalid
|
46
|
-
class ProtocolError < Base; end
|
47
|
-
|
48
|
-
# A generic Ably exception taht supports a status & code.
|
49
|
-
# See https://github.com/ably/ably-common/blob/master/protocol/errors.json for a list of Ably errors
|
50
|
-
class Standard < Base; end
|
51
54
|
end
|
52
55
|
end
|
data/lib/ably/logger.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
module Ably
|
2
|
+
# Logger unifies logging for #debug, #info, #warn, #error, and #fatal messages.
|
3
|
+
# A new Ably client uses this Logger and sets the appropriate log level.
|
4
|
+
# A custom Logger can be configured when instantiating the client, refer to the {Ably::Rest::Client} and {Ably::Realtime::Client} documentation
|
5
|
+
#
|
6
|
+
class Logger
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
# @param client [Ably::Rest::Client,Ably::Realtime::Client] Rest or Realtime Ably client
|
10
|
+
# @param log_level [Integer] {http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html Ruby Logger} log level
|
11
|
+
# @param custom_logger [nil,Object] A custom logger can optionally be used instead of the,
|
12
|
+
# however it must provide a {http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html Ruby Logger} compatible interface.
|
13
|
+
#
|
14
|
+
def initialize(client, log_level, custom_logger = nil)
|
15
|
+
@client = client
|
16
|
+
@custom_logger = custom_logger
|
17
|
+
@logger = custom_logger || default_logger
|
18
|
+
@log_level = log_level
|
19
|
+
|
20
|
+
ensure_logger_interface_is_valid
|
21
|
+
|
22
|
+
@logger.level = log_level
|
23
|
+
end
|
24
|
+
|
25
|
+
# The logger used by this class, defaults to {http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html Ruby Logger}
|
26
|
+
# @return {Object,Logger}
|
27
|
+
attr_reader :logger
|
28
|
+
|
29
|
+
# If a custom logger is being used with this Logger, this property is not nil
|
30
|
+
# @return {nil,Object}
|
31
|
+
attr_reader :custom_logger
|
32
|
+
|
33
|
+
# The log level ranging from DEBUG to FATAL, refer to http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html
|
34
|
+
# @return {Integer}
|
35
|
+
attr_reader :log_level
|
36
|
+
|
37
|
+
def_delegators :logger, :fatal, :error, :warn, :info, :debug
|
38
|
+
|
39
|
+
private
|
40
|
+
attr_reader :client
|
41
|
+
|
42
|
+
def color(color_value, string)
|
43
|
+
"\033[#{color_value}m#{string}\033[0m"
|
44
|
+
end
|
45
|
+
|
46
|
+
def red(string)
|
47
|
+
color(31, string)
|
48
|
+
end
|
49
|
+
|
50
|
+
def magenta(string)
|
51
|
+
color(35, string)
|
52
|
+
end
|
53
|
+
|
54
|
+
def cyan(string)
|
55
|
+
color(36, string)
|
56
|
+
end
|
57
|
+
|
58
|
+
def connection_id
|
59
|
+
if realtime?
|
60
|
+
if client.connection.id
|
61
|
+
"[#{cyan(client.connection.id)}] "
|
62
|
+
else
|
63
|
+
"[ #{cyan('--')} ] "
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def realtime?
|
69
|
+
client.respond_to?(:connection)
|
70
|
+
end
|
71
|
+
|
72
|
+
def default_logger
|
73
|
+
::Logger.new(STDOUT).tap do |logger|
|
74
|
+
logger.formatter = proc do |severity, datetime, progname, msg|
|
75
|
+
severity = ::Logger::SEV_LABEL.index(severity) if severity.kind_of?(String)
|
76
|
+
|
77
|
+
formatted_date = if severity == ::Logger::DEBUG
|
78
|
+
datetime.strftime("%H:%M:%S.%L")
|
79
|
+
else
|
80
|
+
datetime.strftime("%Y-%m-%d %H:%M:%S.%L")
|
81
|
+
end
|
82
|
+
|
83
|
+
severity_label = if severity <= ::Logger::INFO
|
84
|
+
magenta(::Logger::SEV_LABEL[severity])
|
85
|
+
else
|
86
|
+
red(::Logger::SEV_LABEL[severity])
|
87
|
+
end
|
88
|
+
|
89
|
+
"#{formatted_date} #{severity_label} #{connection_id}#{msg}\n"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def ensure_logger_interface_is_valid
|
95
|
+
%w(fatal error warn info debug level level=).each do |method|
|
96
|
+
unless logger.respond_to?(method)
|
97
|
+
raise ArgumentError, "The custom Logger's interface does not provide the method '#{method}'"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/ably/models/message.rb
CHANGED
@@ -25,6 +25,9 @@ module Ably::Models
|
|
25
25
|
# @return [String] The id of the publisher of this message
|
26
26
|
# @!attribute [r] data
|
27
27
|
# @return [Object] The message payload. See the documentation for supported datatypes.
|
28
|
+
# @!attribute [r] encoding
|
29
|
+
# @return [Object] The encoding for the message data. Encoding and decoding of messages is handled automatically by the client library.
|
30
|
+
# Therefore, the `encoding` attribute should always be nil unless an Ably library decoding error has occurred.
|
28
31
|
# @!attribute [r] timestamp
|
29
32
|
# @return [Time] Timestamp when the message was received by the Ably the real-time service
|
30
33
|
# @!attribute [r] id
|
@@ -34,6 +37,7 @@ module Ably::Models
|
|
34
37
|
#
|
35
38
|
class Message
|
36
39
|
include Ably::Modules::ModelCommon
|
40
|
+
include Ably::Modules::Encodeable
|
37
41
|
include EventMachine::Deferrable
|
38
42
|
|
39
43
|
# {Message} initializer
|
@@ -44,10 +48,11 @@ module Ably::Models
|
|
44
48
|
def initialize(hash_object, protocol_message = nil)
|
45
49
|
@protocol_message = protocol_message
|
46
50
|
@raw_hash_object = hash_object
|
47
|
-
|
51
|
+
|
52
|
+
set_hash_object hash_object
|
48
53
|
end
|
49
54
|
|
50
|
-
%w( name client_id ).each do |attribute|
|
55
|
+
%w( name client_id encoding ).each do |attribute|
|
51
56
|
define_method attribute do
|
52
57
|
hash[attribute.to_sym]
|
53
58
|
end
|
@@ -74,8 +79,11 @@ module Ably::Models
|
|
74
79
|
end
|
75
80
|
|
76
81
|
def as_json(*args)
|
77
|
-
raise RuntimeError,
|
78
|
-
|
82
|
+
raise RuntimeError, ':name is missing, cannot generate a valid Hash for Message' unless name
|
83
|
+
|
84
|
+
hash.dup.tap do |message|
|
85
|
+
decode_binary_data_before_to_json message
|
86
|
+
end.as_json
|
79
87
|
end
|
80
88
|
|
81
89
|
# Assign this message to a ProtocolMessage before delivery to the Ably system
|
@@ -95,11 +103,13 @@ module Ably::Models
|
|
95
103
|
# @return [Ably::Models::ProtocolMessage]
|
96
104
|
# @api private
|
97
105
|
def protocol_message
|
98
|
-
raise RuntimeError,
|
106
|
+
raise RuntimeError, 'Message is not yet published with a ProtocolMessage. ProtocolMessage is nil' if @protocol_message.nil?
|
99
107
|
@protocol_message
|
100
108
|
end
|
101
109
|
|
102
110
|
private
|
111
|
+
attr_reader :raw_hash_object
|
112
|
+
|
103
113
|
def protocol_message_index
|
104
114
|
protocol_message.messages.index(self)
|
105
115
|
end
|
@@ -111,5 +121,9 @@ module Ably::Models
|
|
111
121
|
def message_serial
|
112
122
|
protocol_message.message_serial
|
113
123
|
end
|
124
|
+
|
125
|
+
def set_hash_object(hash)
|
126
|
+
@hash_object = IdiomaticRubyWrapper(hash.clone.freeze, stop_at: [:data])
|
127
|
+
end
|
114
128
|
end
|
115
129
|
end
|