ably 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -1
  3. data/ably.gemspec +4 -3
  4. data/lib/ably/auth.rb +4 -4
  5. data/lib/ably/logger.rb +1 -1
  6. data/lib/ably/models/idiomatic_ruby_wrapper.rb +8 -8
  7. data/lib/ably/models/message.rb +6 -4
  8. data/lib/ably/models/presence_message.rb +6 -4
  9. data/lib/ably/modules/async_wrapper.rb +2 -2
  10. data/lib/ably/modules/conversions.rb +1 -1
  11. data/lib/ably/modules/encodeable.rb +1 -1
  12. data/lib/ably/modules/event_emitter.rb +2 -2
  13. data/lib/ably/modules/safe_deferrable.rb +1 -1
  14. data/lib/ably/modules/safe_yield.rb +1 -1
  15. data/lib/ably/modules/state_emitter.rb +5 -5
  16. data/lib/ably/realtime/auth.rb +1 -1
  17. data/lib/ably/realtime/channel.rb +3 -3
  18. data/lib/ably/realtime/channel/channel_manager.rb +2 -2
  19. data/lib/ably/realtime/client/incoming_message_dispatcher.rb +3 -2
  20. data/lib/ably/realtime/connection.rb +11 -6
  21. data/lib/ably/realtime/connection/websocket_transport.rb +1 -1
  22. data/lib/ably/realtime/presence.rb +3 -3
  23. data/lib/ably/realtime/presence/members_map.rb +6 -6
  24. data/lib/ably/rest/channel.rb +2 -2
  25. data/lib/ably/rest/client.rb +20 -12
  26. data/lib/ably/version.rb +1 -1
  27. data/spec/acceptance/realtime/auth_spec.rb +13 -37
  28. data/spec/acceptance/realtime/channel_history_spec.rb +7 -1
  29. data/spec/acceptance/realtime/channel_spec.rb +3 -3
  30. data/spec/acceptance/realtime/client_spec.rb +2 -2
  31. data/spec/acceptance/realtime/connection_failures_spec.rb +221 -7
  32. data/spec/acceptance/realtime/connection_spec.rb +13 -21
  33. data/spec/acceptance/realtime/message_spec.rb +2 -2
  34. data/spec/acceptance/realtime/presence_history_spec.rb +12 -3
  35. data/spec/acceptance/realtime/presence_spec.rb +10 -10
  36. data/spec/acceptance/rest/auth_spec.rb +21 -48
  37. data/spec/acceptance/rest/client_spec.rb +193 -68
  38. data/spec/shared/client_initializer_behaviour.rb +1 -9
  39. data/spec/spec_helper.rb +2 -0
  40. data/spec/support/event_emitter_helper.rb +31 -0
  41. data/spec/support/event_machine_helper.rb +1 -1
  42. data/spec/support/test_logger_helper.rb +42 -0
  43. data/spec/unit/logger_spec.rb +1 -9
  44. data/spec/unit/modules/async_wrapper_spec.rb +2 -2
  45. data/spec/unit/modules/event_emitter_spec.rb +3 -3
  46. data/spec/unit/modules/state_emitter_spec.rb +10 -10
  47. data/spec/unit/realtime/channel_spec.rb +1 -1
  48. data/spec/unit/realtime/connection_spec.rb +1 -1
  49. data/spec/unit/realtime/presence_spec.rb +1 -1
  50. data/spec/unit/rest/channel_spec.rb +22 -0
  51. data/spec/unit/util/pub_sub_spec.rb +3 -3
  52. metadata +26 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a05adf2fb91ff543ae2797812dce8bc9c3119cc5ebf9c4a4468a177f07e2587c
4
- data.tar.gz: 97c229e631a871cdba553220677629bff959be160db9a864b8c5b712e26480d1
3
+ metadata.gz: adc7327c5853f3fe2fc8175a94877b4ffcbd22c24ce67cca48dfdce9464d3df1
4
+ data.tar.gz: e1740c98a0a6b24a67c8e3fcb6066a93902f9e12b17562a40c31d83184e86c75
5
5
  SHA512:
6
- metadata.gz: e3a2dc86d92459e6fe03721df934e819e504a39a6be899a42d3ea00b251e8dd8f465552e481451a024903ee199370a932addfdbda1962f441379fc5cb718ea73
7
- data.tar.gz: db1ca5e7ae13cb490f469d72a58ee7ca8f1377a834e200ade85045f0b341f411aaed966a4c7d2d85de9dd7cd55084a8369ff39505e76508ce744549723b305a8
6
+ metadata.gz: 4bee4e577b3c8598219d8143d193b3af8772ff95c25cb55694817ff08792b30ef365921d1cb99964673b58166cd2b08fc7a7931303342874b5412d0c19c46c20
7
+ data.tar.gz: 6aaea4c6281c4bc0d74b3262ed167698145dff798f1dcb735b7684792003117a7431944e4c2512cfcc6306b0fc98aea9f5d26d6132ad755afa1fca0a282a109c
@@ -1,11 +1,36 @@
1
1
  # Change Log
2
2
 
3
- ## [v1.0.5](https://github.com/ably/ably-ruby/tree/v1.0.5)
3
+ ## [v1.0.6](https://github.com/ably/ably-ruby/tree/v1.0.6)
4
4
 
5
+ [Full Changelog](https://github.com/ably/ably-ruby/compare/v1.0.5...v1.0.6)
6
+
7
+ **Fixed bugs:**
8
+
9
+ - WebSocket driver does not emit events for heartbeats [\#116](https://github.com/ably/ably-ruby/issues/116)
10
+
11
+ **Closed issues:**
12
+
13
+ - Passing a frozen channel name or name gives an error on the REST client \[Reopen\] [\#145](https://github.com/ably/ably-ruby/issues/145)
14
+ - Passing a frozen channel name or name gives an error on the REST client [\#132](https://github.com/ably/ably-ruby/issues/132)
15
+
16
+ **Merged pull requests:**
17
+
18
+ - Add request id fix for bulk publishes [\#154](https://github.com/ably/ably-ruby/pull/154) ([mattheworiordan](https://github.com/mattheworiordan))
19
+ - Fix race condition in EventMachine [\#153](https://github.com/ably/ably-ruby/pull/153) ([mattheworiordan](https://github.com/mattheworiordan))
20
+ - Add support for WebSocket native heartbeats [\#151](https://github.com/ably/ably-ruby/pull/151) ([mattheworiordan](https://github.com/mattheworiordan))
21
+ - RSC15d test fixes; add \(failing\) tests for GET as well as POST [\#148](https://github.com/ably/ably-ruby/pull/148) ([SimonWoolf](https://github.com/SimonWoolf))
22
+ - Do not encode strings in-place [\#147](https://github.com/ably/ably-ruby/pull/147) ([mattheworiordan](https://github.com/mattheworiordan))
23
+ - Only resume if connection is fresh \(RTN15g\*\) [\#146](https://github.com/ably/ably-ruby/pull/146) ([mattheworiordan](https://github.com/mattheworiordan))
24
+ - Fix channel history pagination test [\#143](https://github.com/ably/ably-ruby/pull/143) ([funkyboy](https://github.com/funkyboy))
25
+ - Fix presence history test [\#141](https://github.com/ably/ably-ruby/pull/141) ([funkyboy](https://github.com/funkyboy))
26
+ - Do not encode strings in-place [\#140](https://github.com/ably/ably-ruby/pull/140) ([aschuster3](https://github.com/aschuster3))
27
+
28
+ ## [v1.0.5](https://github.com/ably/ably-ruby/tree/v1.0.5) (2018-04-23)
5
29
  [Full Changelog](https://github.com/ably/ably-ruby/compare/v1.0.4...v1.0.5)
6
30
 
7
31
  **Implemented enhancements:**
8
32
 
33
+ - Add Ruby 2.1 and 2.3 to Travis tests [\#129](https://github.com/ably/ably-ruby/issues/129)
9
34
  - Add supported platforms to README file [\#128](https://github.com/ably/ably-ruby/issues/128)
10
35
  - Add Ruby 2.1 and 2.3 to Travis tests [\#130](https://github.com/ably/ably-ruby/pull/130) ([funkyboy](https://github.com/funkyboy))
11
36
 
@@ -18,17 +18,18 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_runtime_dependency 'eventmachine', '~> 1.0'
21
+ spec.add_runtime_dependency 'eventmachine', '~> 1.2.6'
22
22
  spec.add_runtime_dependency 'em-http-request', '~> 1.1'
23
23
  spec.add_runtime_dependency 'statesman', '~> 1.0.0'
24
- spec.add_runtime_dependency 'faraday', '~> 0.9'
24
+ spec.add_runtime_dependency 'faraday', '~> 0.12'
25
+ spec.add_runtime_dependency 'excon', '~> 0.55'
25
26
 
26
27
  if RUBY_VERSION.match(/^1/)
27
28
  spec.add_runtime_dependency 'json', '< 2.0'
28
29
  else
29
30
  spec.add_runtime_dependency 'json'
30
31
  end
31
- spec.add_runtime_dependency 'websocket-driver', '~> 0.6'
32
+ spec.add_runtime_dependency 'websocket-driver', '~> 0.7'
32
33
  spec.add_runtime_dependency 'msgpack', '>= 0.6.2'
33
34
  spec.add_runtime_dependency 'addressable', '>= 2.0.0'
34
35
 
@@ -82,7 +82,7 @@ module Ably
82
82
 
83
83
  if has_client_id? && !token_creatable_externally? && !token_option
84
84
  raise ArgumentError, 'client_id cannot be provided without a complete API key or means to authenticate. An API key is needed to automatically authenticate with Ably and obtain a token' unless api_key_present?
85
- ensure_utf_8 :client_id, client_id
85
+ @client_id = ensure_utf_8(:client_id, client_id) if client_id
86
86
  end
87
87
 
88
88
  # If a token details object or token string is provided in the initializer
@@ -119,7 +119,7 @@ module Ably
119
119
  # token_details = client.auth.authorize
120
120
  #
121
121
  # # will use token request from block to authorize if not already authorized
122
- # token_details = client.auth.authorize {}, auth_callback: Proc.new do
122
+ # token_details = client.auth.authorize {}, auth_callback: lambda do |token_parmas|
123
123
  # # create token_request object
124
124
  # token_request
125
125
  # end
@@ -207,7 +207,7 @@ module Ably
207
207
  # client.auth.request_token ttl: 1.hour
208
208
  #
209
209
  # # token request using auth block
210
- # token_details = client.auth.request_token {}, auth_callback: Proc.new do
210
+ # token_details = client.auth.request_token {}, auth_callback: lambda do |token_params|
211
211
  # # create token_request object
212
212
  # token_request
213
213
  # end
@@ -633,7 +633,7 @@ module Ably
633
633
  method = auth_options[:auth_method] || options[:auth_method] || :get
634
634
  params = (auth_options[:auth_params] || options[:auth_method] || {}).merge(token_params)
635
635
 
636
- response = connection.send(method) do |request|
636
+ response = connection.public_send(method) do |request|
637
637
  request.url uri.path
638
638
  request.headers = auth_options[:auth_headers] || {}
639
639
  if method.to_s.downcase == 'post'
@@ -82,7 +82,7 @@ module Ably
82
82
 
83
83
  def default_logger
84
84
  ::Logger.new(STDOUT).tap do |logger|
85
- logger.formatter = proc do |severity, datetime, progname, msg|
85
+ logger.formatter = lambda do |severity, datetime, progname, msg|
86
86
  severity = ::Logger::SEV_LABEL.index(severity) if severity.kind_of?(String)
87
87
 
88
88
  formatted_date = if severity == ::Logger::DEBUG
@@ -210,14 +210,14 @@ module Ably::Models
210
210
  # key is not found in mixedCase.
211
211
  def source_key_for(symbolized_key)
212
212
  format_preferences = [
213
- proc { |key_sym| convert_to_mixed_case(key_sym) },
214
- proc { |key_sym| key_sym.to_sym },
215
- proc { |key_sym| key_sym.to_s },
216
- proc { |key_sym| convert_to_mixed_case(key_sym).to_sym },
217
- proc { |key_sym| convert_to_lower_case(key_sym) },
218
- proc { |key_sym| convert_to_lower_case(key_sym).to_sym },
219
- proc { |key_sym| convert_to_mixed_case(key_sym, force_camel: true) },
220
- proc { |key_sym| convert_to_mixed_case(key_sym, force_camel: true).to_sym }
213
+ lambda { |key_sym| convert_to_mixed_case(key_sym) },
214
+ lambda { |key_sym| key_sym.to_sym },
215
+ lambda { |key_sym| key_sym.to_s },
216
+ lambda { |key_sym| convert_to_mixed_case(key_sym).to_sym },
217
+ lambda { |key_sym| convert_to_lower_case(key_sym) },
218
+ lambda { |key_sym| convert_to_lower_case(key_sym).to_sym },
219
+ lambda { |key_sym| convert_to_mixed_case(key_sym, force_camel: true) },
220
+ lambda { |key_sym| convert_to_mixed_case(key_sym, force_camel: true).to_sym }
221
221
  ]
222
222
 
223
223
  preferred_format = format_preferences.detect do |format|
@@ -62,9 +62,11 @@ module Ably::Models
62
62
 
63
63
  set_attributes_object attributes
64
64
 
65
- ensure_utf_8 :name, name, allow_nil: true
66
- ensure_utf_8 :client_id, client_id, allow_nil: true
67
- ensure_utf_8 :encoding, encoding, allow_nil: true
65
+ self.attributes[:name] = ensure_utf_8(:name, name, allow_nil: true) if name
66
+ self.attributes[:client_id] = ensure_utf_8(:client_id, client_id, allow_nil: true) if client_id
67
+ self.attributes[:encoding] = ensure_utf_8(:encoding, encoding, allow_nil: true) if encoding
68
+
69
+ self.attributes.freeze
68
70
  end
69
71
 
70
72
  %w( name client_id encoding ).each do |attribute|
@@ -145,7 +147,7 @@ module Ably::Models
145
147
  end
146
148
 
147
149
  def set_attributes_object(new_attributes)
148
- @attributes = IdiomaticRubyWrapper(new_attributes.clone.freeze, stop_at: [:data, :extras])
150
+ @attributes = IdiomaticRubyWrapper(new_attributes.clone, stop_at: [:data, :extras])
149
151
  end
150
152
 
151
153
  def logger
@@ -69,9 +69,11 @@ module Ably::Models
69
69
 
70
70
  set_attributes_object attributes
71
71
 
72
- ensure_utf_8 :client_id, client_id, allow_nil: true
73
- ensure_utf_8 :connection_id, connection_id, allow_nil: true
74
- ensure_utf_8 :encoding, encoding, allow_nil: true
72
+ self.attributes[:client_id] = ensure_utf_8(:client_id, client_id, allow_nil: true) if client_id
73
+ self.attributes[:connection_id] = ensure_utf_8(:connection_id, connection_id, allow_nil: true) if connection_id
74
+ self.attributes[:encoding] = ensure_utf_8(:encoding, encoding, allow_nil: true) if encoding
75
+
76
+ self.attributes.freeze
75
77
  end
76
78
 
77
79
  %w( client_id data encoding ).each do |attribute|
@@ -167,7 +169,7 @@ module Ably::Models
167
169
  end
168
170
 
169
171
  def set_attributes_object(new_attributes)
170
- @attributes = IdiomaticRubyWrapper(new_attributes.clone.freeze, stop_at: [:data])
172
+ @attributes = IdiomaticRubyWrapper(new_attributes.clone, stop_at: [:data])
171
173
  end
172
174
 
173
175
  def logger
@@ -44,7 +44,7 @@ module Ably::Modules
44
44
  Ably::Util::SafeDeferrable.new(logger).tap do |deferrable|
45
45
  deferrable.callback(&success_callback) if success_callback
46
46
 
47
- operation_with_exception_handling = proc do
47
+ operation_with_exception_handling = lambda do
48
48
  begin
49
49
  yield
50
50
  rescue StandardError => err
@@ -57,7 +57,7 @@ module Ably::Modules
57
57
  end
58
58
  end
59
59
 
60
- complete_callback = proc do |result|
60
+ complete_callback = lambda do |result|
61
61
  deferrable.succeed result
62
62
  end
63
63
 
@@ -96,7 +96,7 @@ module Ably::Modules
96
96
  unless options[:allow_nil] && string_value.nil?
97
97
  raise ArgumentError, "#{field_name} must be a String" unless string_value.kind_of?(String)
98
98
  end
99
- string_value.encode!(Encoding::UTF_8) if string_value
99
+ string_value.encode(Encoding::UTF_8) if string_value
100
100
  rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError => e
101
101
  raise ArgumentError, "#{field_name} could not be converted to UTF-8: #{e.message}"
102
102
  end
@@ -95,7 +95,7 @@ module Ably::Modules
95
95
 
96
96
  previous_encoding = message_attributes[:encoding]
97
97
  encoders.each do |encoder|
98
- encoder.send method, message_attributes, channel_options
98
+ encoder.public_send method, message_attributes, channel_options
99
99
  end
100
100
  end until previous_encoding == message_attributes[:encoding]
101
101
 
@@ -31,7 +31,7 @@ module Ably
31
31
  # @option options [Proc] :coerce_into A lambda/Proc that is used to coerce the event names for all events. This is useful to ensure the event names conform to a naming or type convention.
32
32
  #
33
33
  # @example
34
- # configure_event_emitter coerce_into: Proc.new { |event| event.to_sym }
34
+ # configure_event_emitter coerce_into: lambda { |event| event.to_sym }
35
35
  #
36
36
  def configure_event_emitter(options = {})
37
37
  @event_emitter_coerce_proc = options[:coerce_into]
@@ -158,7 +158,7 @@ module Ably
158
158
  # #emit automatically deletes any blocks that return true thus allowing a block to be run once
159
159
  def proc_for_block(block, options = {})
160
160
  {
161
- emit_proc: Proc.new do |*args|
161
+ emit_proc: lambda do |*args|
162
162
  block.call(*args)
163
163
  true if options[:delete_once_run]
164
164
  end,
@@ -71,7 +71,7 @@ module Ably::Modules
71
71
 
72
72
  def fallback_logger
73
73
  @fallback_logger ||= ::Logger.new(STDOUT).tap do |logger|
74
- logger.formatter = proc do |severity, datetime, progname, msg|
74
+ logger.formatter = lambda do |severity, datetime, progname, msg|
75
75
  [
76
76
  "#{datetime.strftime("%Y-%m-%d %H:%M:%S.%L")} #{::Logger::SEV_LABEL[severity]} #{msg}",
77
77
  "Warning: SafeDeferrable expects the method #logger to be defined in the class it is included in, the method was not found in #{self.class}"
@@ -29,7 +29,7 @@ module Ably::Modules
29
29
 
30
30
  def fallback_logger
31
31
  @fallback_logger ||= ::Logger.new(STDOUT).tap do |logger|
32
- logger.formatter = proc do |severity, datetime, progname, msg|
32
+ logger.formatter = lambda do |severity, datetime, progname, msg|
33
33
  [
34
34
  "#{datetime.strftime("%Y-%m-%d %H:%M:%S.%L")} #{::Logger::SEV_LABEL[severity]} #{msg}",
35
35
  "Warning: SafeYield expects the method #logger to be defined in the class it is included in, the method was not found in #{self.class}"
@@ -81,13 +81,13 @@ module Ably::Modules
81
81
  failure_block = options.fetch(:else, nil)
82
82
  failure_wrapper = nil
83
83
 
84
- success_wrapper = Proc.new do
84
+ success_wrapper = lambda do |*args|
85
85
  yield
86
86
  off(&success_wrapper)
87
87
  off(&failure_wrapper) if failure_wrapper
88
88
  end
89
89
 
90
- failure_wrapper = proc do |*args|
90
+ failure_wrapper = lambda do |*args|
91
91
  failure_block.call(*args)
92
92
  off(&success_wrapper)
93
93
  off(&failure_wrapper)
@@ -119,7 +119,7 @@ module Ably::Modules
119
119
  def once_state_changed(options = {}, &block)
120
120
  raise ArgumentError, 'Block required' unless block_given?
121
121
 
122
- once_block = proc do |*args|
122
+ once_block = lambda do |*args|
123
123
  off(*self.class::STATE.map, &once_block)
124
124
  yield(*args)
125
125
  end
@@ -142,7 +142,7 @@ module Ably::Modules
142
142
  #
143
143
  def deferrable_for_state_change_to(target_state)
144
144
  Ably::Util::SafeDeferrable.new(logger).tap do |deferrable|
145
- fail_proc = Proc.new do |state_change|
145
+ fail_proc = lambda do |state_change|
146
146
  deferrable.fail state_change.reason
147
147
  end
148
148
  once_or_if(target_state, else: fail_proc) do
@@ -153,7 +153,7 @@ module Ably::Modules
153
153
  end
154
154
 
155
155
  def self.included(klass)
156
- klass.configure_event_emitter coerce_into: Proc.new { |event|
156
+ klass.configure_event_emitter coerce_into: lambda { |event|
157
157
  # Special case allows EVENT instead of STATE to be emitted
158
158
  # Relies on the assumption that EVENT is a superset of STATE
159
159
  if klass.const_defined?(:EVENT)
@@ -233,7 +233,7 @@ module Ably
233
233
  # @yield [Hash] Auth params for a new Realtime connection
234
234
  #
235
235
  def auth_params(&success_callback)
236
- fail_callback = Proc.new do |error, deferrable|
236
+ fail_callback = lambda do |error, deferrable|
237
237
  logger.error { "Failed to authenticate: #{error}" }
238
238
  if error.kind_of?(Ably::Exceptions::BaseAblyException)
239
239
  # Use base exception if it exists carrying forward the status codes
@@ -93,7 +93,7 @@ module Ably
93
93
  # @option channel_options [Hash,Ably::Models::CipherParams] :cipher A hash of options or a {Ably::Models::CipherParams} to configure the encryption. *:key* is required, all other options are optional. See {Ably::Util::Crypto#initialize} for a list of +:cipher+ options
94
94
  #
95
95
  def initialize(client, name, channel_options = {})
96
- ensure_utf_8 :name, name
96
+ name = ensure_utf_8(:name, name)
97
97
 
98
98
  update_options channel_options
99
99
  @client = client
@@ -159,7 +159,7 @@ module Ably
159
159
  messages = if name.kind_of?(Enumerable)
160
160
  name
161
161
  else
162
- ensure_utf_8 :name, name, allow_nil: true
162
+ name = ensure_utf_8(:name, name, allow_nil: true)
163
163
  ensure_supported_payload data
164
164
  [{ name: name, data: data }.merge(attributes)]
165
165
  end
@@ -291,7 +291,7 @@ module Ably
291
291
  # @api private
292
292
  def __incoming_msgbus__
293
293
  @__incoming_msgbus__ ||= Ably::Util::PubSub.new(
294
- coerce_into: Proc.new { |event| Ably::Models::ProtocolMessage::ACTION(event) }
294
+ coerce_into: lambda { |event| Ably::Models::ProtocolMessage::ACTION(event) }
295
295
  )
296
296
  end
297
297
 
@@ -98,7 +98,7 @@ module Ably::Realtime
98
98
  def fail_messages_awaiting_ack(error, options = {})
99
99
  immediately = options[:immediately] || false
100
100
 
101
- fail_proc = Proc.new do
101
+ fail_proc = lambda do
102
102
  error = Ably::Exceptions::MessageDeliveryFailed.new("Continuity of connection was lost so published messages awaiting ACK have failed") unless error
103
103
  fail_messages_in_queue connection.__pending_message_ack_queue__, error
104
104
  end
@@ -224,7 +224,7 @@ module Ably::Realtime
224
224
  @pending_state_change_timer = nil
225
225
  end
226
226
 
227
- resend_if_disconnected_and_connected = Proc.new do
227
+ resend_if_disconnected_and_connected = lambda do
228
228
  connection.unsafe_once(:disconnected) do
229
229
  next unless pending_state_change_timer
230
230
  connection.unsafe_once(:connected) do
@@ -56,6 +56,7 @@ module Ably::Realtime
56
56
  end
57
57
 
58
58
  update_connection_recovery_info protocol_message
59
+ connection.set_connection_confirmed_alive
59
60
 
60
61
  case protocol_message.action
61
62
  when ACTION.Heartbeat
@@ -75,8 +76,10 @@ module Ably::Realtime
75
76
  elsif connection.connected?
76
77
  logger.debug { "Updated CONNECTED ProtocolMessage received (whilst connected)" }
77
78
  process_connected_update_message protocol_message
79
+ connection.set_connection_confirmed_alive # Connection protocol messages can change liveness settings such as max_idle_interval
78
80
  else
79
81
  process_connected_message protocol_message
82
+ connection.set_connection_confirmed_alive # Connection protocol messages can change liveness settings such as max_idle_interval
80
83
  end
81
84
 
82
85
  when ACTION.Disconnect, ACTION.Disconnected
@@ -132,8 +135,6 @@ module Ably::Realtime
132
135
  error = Ably::Exceptions::ProtocolError.new("Protocol Message Action #{protocol_message.action} is unsupported by this MessageDispatcher", 400, 80013)
133
136
  logger.fatal error.message
134
137
  end
135
-
136
- connection.set_connection_confirmed_alive
137
138
  end
138
139
 
139
140
  def dispatch_channel_error(protocol_message)
@@ -235,7 +235,7 @@ module Ably
235
235
  ping_id = SecureRandom.hex(16)
236
236
  heartbeat_action = Ably::Models::ProtocolMessage::ACTION.Heartbeat
237
237
 
238
- wait_for_ping = Proc.new do |protocol_message|
238
+ wait_for_ping = lambda do |protocol_message|
239
239
  next if finished
240
240
  if protocol_message.action == heartbeat_action && protocol_message.id == ping_id
241
241
  finished = true
@@ -423,9 +423,12 @@ module Ably
423
423
  lib: client.rest_client.lib_version_id,
424
424
  )
425
425
 
426
- # Use native websocket heartbeats if possible
427
- # TODO: Fix once https://github.com/ably/ably-ruby/issues/116 is resolved
428
- url_params['heartbeats'] = 'true' # unless defaults.fetch(:websocket_heartbeats_disabled)
426
+ # Use native websocket heartbeats if possible, but allow Ably protocol heartbeats
427
+ url_params['heartbeats'] = if defaults.fetch(:websocket_heartbeats_disabled)
428
+ 'true'
429
+ else
430
+ 'false'
431
+ end
429
432
 
430
433
  url_params['clientId'] = client.auth.client_id if client.auth.has_client_id?
431
434
 
@@ -579,7 +582,7 @@ module Ably
579
582
 
580
583
  def create_pub_sub_message_bus
581
584
  Ably::Util::PubSub.new(
582
- coerce_into: Proc.new do |event|
585
+ coerce_into: lambda do |event|
583
586
  raise KeyError, "Expected :protocol_message, :#{event} is disallowed" unless event == :protocol_message
584
587
  :protocol_message
585
588
  end
@@ -615,8 +618,10 @@ module Ably
615
618
  def connection_state_available?
616
619
  return true if connected?
617
620
 
621
+ return false if time_since_connection_confirmed_alive? > connection_state_ttl + details.max_idle_interval
622
+
618
623
  connected_last = state_history.reverse.find { |connected| connected.fetch(:state) == :connected }
619
- if connected_last.nil? || (connected_last.fetch(:transitioned_at) < Time.now - connection_state_ttl)
624
+ if connected_last.nil?
620
625
  false
621
626
  else
622
627
  true
@@ -208,7 +208,7 @@ module Ably::Realtime
208
208
 
209
209
  def create_pub_sub_message_bus
210
210
  Ably::Util::PubSub.new(
211
- coerce_into: Proc.new do |event|
211
+ coerce_into: lambda do |event|
212
212
  raise KeyError, "Expected :protocol_message, :#{event} is disallowed" unless event == :protocol_message
213
213
  :protocol_message
214
214
  end