ably-pubsub-core 0.0.1.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/ably/agent.rb +8 -0
- data/lib/ably/auth.rb +791 -0
- data/lib/ably/exceptions.rb +169 -0
- data/lib/ably/logger.rb +119 -0
- data/lib/ably/models/auth_details.rb +45 -0
- data/lib/ably/models/channel_details.rb +69 -0
- data/lib/ably/models/channel_metrics.rb +107 -0
- data/lib/ably/models/channel_occupancy.rb +50 -0
- data/lib/ably/models/channel_options.rb +120 -0
- data/lib/ably/models/channel_state_change.rb +84 -0
- data/lib/ably/models/channel_status.rb +63 -0
- data/lib/ably/models/cipher_params.rb +137 -0
- data/lib/ably/models/connection_details.rb +149 -0
- data/lib/ably/models/connection_state_change.rb +83 -0
- data/lib/ably/models/delta_extras.rb +28 -0
- data/lib/ably/models/device_details.rb +126 -0
- data/lib/ably/models/device_push_details.rb +94 -0
- data/lib/ably/models/error_info.rb +104 -0
- data/lib/ably/models/http_paginated_response.rb +112 -0
- data/lib/ably/models/idiomatic_ruby_wrapper.rb +235 -0
- data/lib/ably/models/message.rb +223 -0
- data/lib/ably/models/message_encoders/base.rb +135 -0
- data/lib/ably/models/message_encoders/base64.rb +40 -0
- data/lib/ably/models/message_encoders/cipher.rb +84 -0
- data/lib/ably/models/message_encoders/json.rb +34 -0
- data/lib/ably/models/message_encoders/utf8.rb +26 -0
- data/lib/ably/models/nil_logger.rb +20 -0
- data/lib/ably/models/paginated_result.rb +201 -0
- data/lib/ably/models/presence_message.rb +244 -0
- data/lib/ably/models/protocol_message.rb +288 -0
- data/lib/ably/models/push_channel_subscription.rb +114 -0
- data/lib/ably/models/stats.rb +242 -0
- data/lib/ably/models/stats_types.rb +107 -0
- data/lib/ably/models/token_details.rb +148 -0
- data/lib/ably/models/token_request.rb +180 -0
- data/lib/ably/modules/ably.rb +26 -0
- data/lib/ably/modules/async_wrapper.rb +69 -0
- data/lib/ably/modules/channels_collection.rb +105 -0
- data/lib/ably/modules/conversions.rb +153 -0
- data/lib/ably/modules/encodeable.rb +111 -0
- data/lib/ably/modules/enum.rb +230 -0
- data/lib/ably/modules/event_emitter.rb +200 -0
- data/lib/ably/modules/event_machine_helpers.rb +26 -0
- data/lib/ably/modules/exception_codes.rb +128 -0
- data/lib/ably/modules/http_helpers.rb +41 -0
- data/lib/ably/modules/message_emitter.rb +78 -0
- data/lib/ably/modules/message_pack.rb +14 -0
- data/lib/ably/modules/model_common.rb +84 -0
- data/lib/ably/modules/safe_deferrable.rb +83 -0
- data/lib/ably/modules/safe_yield.rb +41 -0
- data/lib/ably/modules/state_emitter.rb +181 -0
- data/lib/ably/modules/state_machine.rb +59 -0
- data/lib/ably/modules/statesman_monkey_patch.rb +33 -0
- data/lib/ably/modules/uses_state_machine.rb +111 -0
- data/lib/ably/realtime/auth.rb +283 -0
- data/lib/ably/realtime/channel/channel_manager.rb +272 -0
- data/lib/ably/realtime/channel/channel_properties.rb +40 -0
- data/lib/ably/realtime/channel/channel_state_machine.rb +104 -0
- data/lib/ably/realtime/channel/publisher.rb +82 -0
- data/lib/ably/realtime/channel/push_channel.rb +69 -0
- data/lib/ably/realtime/channel.rb +440 -0
- data/lib/ably/realtime/channels.rb +71 -0
- data/lib/ably/realtime/client/incoming_message_dispatcher.rb +225 -0
- data/lib/ably/realtime/client/outgoing_message_dispatcher.rb +87 -0
- data/lib/ably/realtime/client.rb +363 -0
- data/lib/ably/realtime/connection/connection_manager.rb +594 -0
- data/lib/ably/realtime/connection/connection_state_machine.rb +144 -0
- data/lib/ably/realtime/connection/websocket_transport.rb +287 -0
- data/lib/ably/realtime/connection.rb +738 -0
- data/lib/ably/realtime/models/nil_channel.rb +30 -0
- data/lib/ably/realtime/presence/members_map.rb +395 -0
- data/lib/ably/realtime/presence/presence_manager.rb +78 -0
- data/lib/ably/realtime/presence/presence_state_machine.rb +57 -0
- data/lib/ably/realtime/presence.rb +502 -0
- data/lib/ably/realtime/push/admin.rb +75 -0
- data/lib/ably/realtime/push/channel_subscriptions.rb +108 -0
- data/lib/ably/realtime/push/device_registrations.rb +105 -0
- data/lib/ably/realtime/push.rb +25 -0
- data/lib/ably/realtime/recovery_key_context.rb +36 -0
- data/lib/ably/realtime.rb +60 -0
- data/lib/ably/rest/channel/push_channel.rb +59 -0
- data/lib/ably/rest/channel.rb +194 -0
- data/lib/ably/rest/channels.rb +47 -0
- data/lib/ably/rest/client.rb +727 -0
- data/lib/ably/rest/middleware/encoder.rb +49 -0
- data/lib/ably/rest/middleware/exceptions.rb +53 -0
- data/lib/ably/rest/middleware/external_exceptions.rb +24 -0
- data/lib/ably/rest/middleware/fail_if_unsupported_mime_type.rb +22 -0
- data/lib/ably/rest/middleware/logger.rb +58 -0
- data/lib/ably/rest/middleware/parse_json.rb +27 -0
- data/lib/ably/rest/middleware/parse_message_pack.rb +43 -0
- data/lib/ably/rest/presence.rb +113 -0
- data/lib/ably/rest/push/admin.rb +58 -0
- data/lib/ably/rest/push/channel_subscriptions.rb +121 -0
- data/lib/ably/rest/push/device_registrations.rb +114 -0
- data/lib/ably/rest/push.rb +25 -0
- data/lib/ably/rest.rb +40 -0
- data/lib/ably/util/ably_extensions.rb +29 -0
- data/lib/ably/util/crypto.rb +134 -0
- data/lib/ably/util/pub_sub.rb +45 -0
- data/lib/ably/util/safe_deferrable.rb +44 -0
- data/lib/ably/version.rb +7 -0
- data/lib/ably.rb +16 -0
- metadata +497 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
require 'ably/modules/exception_codes'
|
|
2
|
+
|
|
3
|
+
module Ably
|
|
4
|
+
module Exceptions
|
|
5
|
+
TOKEN_EXPIRED_CODE = 40140..40149
|
|
6
|
+
|
|
7
|
+
# Base Ably exception class that contains status and code values used by Ably
|
|
8
|
+
# Refer to https://github.com/ably/ably-common/blob/main/protocol/errors.json
|
|
9
|
+
#
|
|
10
|
+
# @!attribute [r] message
|
|
11
|
+
# @return [String] Error message from Ably
|
|
12
|
+
# @!attribute [r] status
|
|
13
|
+
# @return [String] HTTP status code of error
|
|
14
|
+
# @!attribute [r] code
|
|
15
|
+
# @return [String] Ably specific error code
|
|
16
|
+
class BaseAblyException < StandardError
|
|
17
|
+
attr_reader :status, :code, :request_id
|
|
18
|
+
|
|
19
|
+
def initialize(message, status = nil, code = nil, base_exception = nil, options = {})
|
|
20
|
+
super message
|
|
21
|
+
|
|
22
|
+
@base_exception = base_exception
|
|
23
|
+
@status = status
|
|
24
|
+
@status ||= base_exception.status if base_exception && base_exception.respond_to?(:status)
|
|
25
|
+
@status ||= options[:fallback_status]
|
|
26
|
+
@code = code
|
|
27
|
+
@code ||= base_exception.code if base_exception && base_exception.respond_to?(:code)
|
|
28
|
+
@code ||= options[:fallback_code]
|
|
29
|
+
@request_id ||= options[:request_id]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def to_s
|
|
33
|
+
message = [super]
|
|
34
|
+
if status || code
|
|
35
|
+
additional_info = []
|
|
36
|
+
additional_info << "code: #{code}" if code
|
|
37
|
+
additional_info << "http status: #{status}" if status
|
|
38
|
+
additional_info << "base exception: #{@base_exception.class}" if @base_exception
|
|
39
|
+
additional_info << "request_id: #{request_id}" if request_id
|
|
40
|
+
message << "(#{additional_info.join(', ')})"
|
|
41
|
+
message << "-> see https://help.ably.io/error/#{code} for help" if code
|
|
42
|
+
end
|
|
43
|
+
message.join(' ')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def as_json(*args)
|
|
47
|
+
{
|
|
48
|
+
message: "#{self.class}: #{message}",
|
|
49
|
+
status: @status,
|
|
50
|
+
code: @code
|
|
51
|
+
}.delete_if { |key, val| val.nil? }
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Maximum frame size exceeded TO3l9
|
|
56
|
+
class MaxFrameSizeExceeded < BaseAblyException; end
|
|
57
|
+
|
|
58
|
+
# Maximum message size exceeded TO3l8
|
|
59
|
+
class MaxMessageSizeExceeded < BaseAblyException; end
|
|
60
|
+
|
|
61
|
+
# An invalid request was received by Ably
|
|
62
|
+
class InvalidRequest < BaseAblyException; end
|
|
63
|
+
|
|
64
|
+
class InvalidCredentials < BaseAblyException; end
|
|
65
|
+
|
|
66
|
+
# Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided
|
|
67
|
+
class UnauthorizedRequest < BaseAblyException; end
|
|
68
|
+
|
|
69
|
+
# The request was a valid request, but Ably is refusing to respond to it
|
|
70
|
+
class ForbiddenRequest < BaseAblyException; end
|
|
71
|
+
|
|
72
|
+
# The requested resource could not be found but may be available again in the future
|
|
73
|
+
class ResourceMissing < BaseAblyException; end
|
|
74
|
+
|
|
75
|
+
# Ably Protocol message received that is invalid
|
|
76
|
+
class ProtocolError < BaseAblyException; end
|
|
77
|
+
|
|
78
|
+
# Encryption or Decryption failure
|
|
79
|
+
class CipherError < BaseAblyException; end
|
|
80
|
+
|
|
81
|
+
# Encoding or decoding failure
|
|
82
|
+
class EncoderError < BaseAblyException; end
|
|
83
|
+
|
|
84
|
+
# Connection error from Realtime or REST service
|
|
85
|
+
class ConnectionError < BaseAblyException
|
|
86
|
+
def initialize(message, status = nil, code = nil, base_exception = nil, options = {})
|
|
87
|
+
super message, status, code, base_exception, options
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def to_s
|
|
91
|
+
message = [super]
|
|
92
|
+
if @base_exception
|
|
93
|
+
message << "#{@base_exception}"
|
|
94
|
+
if @base_exception.respond_to?(:message) && @base_exception.message.match(/certificate verify failed/i)
|
|
95
|
+
message << "See https://goo.gl/eKvfcR to resolve this issue."
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
message.join(' < ')
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Connection Timeout accessing Realtime or REST service
|
|
103
|
+
class ConnectionTimeout < ConnectionError; end
|
|
104
|
+
|
|
105
|
+
# Transport closed unexpectedly
|
|
106
|
+
class TransportClosed < ConnectionError; end
|
|
107
|
+
|
|
108
|
+
# Connection closed unexpectedly
|
|
109
|
+
class ConnectionClosed < ConnectionError; end
|
|
110
|
+
|
|
111
|
+
# Connection suspended
|
|
112
|
+
class ConnectionSuspended < ConnectionError; end
|
|
113
|
+
|
|
114
|
+
# Connection failed
|
|
115
|
+
class ConnectionFailed < ConnectionError; end
|
|
116
|
+
|
|
117
|
+
class AuthenticationFailed < ConnectionError; end
|
|
118
|
+
|
|
119
|
+
# Invalid State Change error on a {https://github.com/gocardless/statesman Statesman State Machine}
|
|
120
|
+
class InvalidStateChange < BaseAblyException; end
|
|
121
|
+
|
|
122
|
+
class InvalidState < BaseAblyException; end
|
|
123
|
+
|
|
124
|
+
# A generic Ably exception taht supports a status & code.
|
|
125
|
+
# See https://github.com/ably/ably-common/blob/main/protocol/errors.json for a list of Ably errors
|
|
126
|
+
class Standard < BaseAblyException; end
|
|
127
|
+
|
|
128
|
+
# The HTTP request has returned a 500 error
|
|
129
|
+
class ServerError < BaseAblyException; end
|
|
130
|
+
|
|
131
|
+
# PaginatedResult cannot retrieve the page
|
|
132
|
+
class PageMissing < BaseAblyException; end
|
|
133
|
+
|
|
134
|
+
# The expected response from the server was invalid
|
|
135
|
+
class InvalidResponseBody < BaseAblyException; end
|
|
136
|
+
|
|
137
|
+
# The request cannot be performed because it is insecure
|
|
138
|
+
class InsecureRequest < BaseAblyException; end
|
|
139
|
+
|
|
140
|
+
# The token request could not be created
|
|
141
|
+
class TokenRequestFailed < BaseAblyException; end
|
|
142
|
+
|
|
143
|
+
# The token has expired, 40140..40149
|
|
144
|
+
class TokenExpired < BaseAblyException; end
|
|
145
|
+
|
|
146
|
+
# The message could not be delivered to the server
|
|
147
|
+
class MessageDeliveryFailed < BaseAblyException; end
|
|
148
|
+
|
|
149
|
+
# The client has been configured to not queue messages i.e. only publish down an active connection
|
|
150
|
+
class MessageQueueingDisabled < BaseAblyException; end
|
|
151
|
+
|
|
152
|
+
# The data payload type is not supported
|
|
153
|
+
class UnsupportedDataType < BaseAblyException; end
|
|
154
|
+
|
|
155
|
+
# When a channel is detached / failed, certain operations are not permitted such as publishing messages
|
|
156
|
+
class ChannelInactive < BaseAblyException; end
|
|
157
|
+
|
|
158
|
+
class IncompatibleClientId < BaseAblyException
|
|
159
|
+
def initialize(messages, status = 400, code = Ably::Exceptions::Codes::INVALID_CLIENT_ID, *args)
|
|
160
|
+
super(message, status, code, *args)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Token request has missing or invalid attributes
|
|
165
|
+
class InvalidTokenRequest < BaseAblyException; end
|
|
166
|
+
|
|
167
|
+
class PushNotificationsNotSupported < BaseAblyException; end
|
|
168
|
+
end
|
|
169
|
+
end
|
data/lib/ably/logger.rb
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
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-3.1.1/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-3.1.1/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
|
+
|
|
24
|
+
@log_mutex = Mutex.new
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# The logger used by this class, defaults to {http://www.ruby-doc.org/stdlib-3.1.1/libdoc/logger/rdoc/Logger.html Ruby Logger}
|
|
28
|
+
# @return {Object,Logger}
|
|
29
|
+
attr_reader :logger
|
|
30
|
+
|
|
31
|
+
# If a custom logger is being used with this Logger, this property is not nil
|
|
32
|
+
# @return {nil,Object}
|
|
33
|
+
attr_reader :custom_logger
|
|
34
|
+
|
|
35
|
+
# The log level ranging from DEBUG to FATAL, refer to http://www.ruby-doc.org/stdlib-3.1.1/libdoc/logger/rdoc/Logger.html
|
|
36
|
+
# @return {Integer}
|
|
37
|
+
attr_reader :log_level
|
|
38
|
+
|
|
39
|
+
# Catch exceptiosn in blocks passed to the logger, log the error and continue
|
|
40
|
+
%w(fatal error warn info debug).each do |method_name|
|
|
41
|
+
define_method(method_name) do |*args, &block|
|
|
42
|
+
begin
|
|
43
|
+
log_mutex.synchronize do
|
|
44
|
+
logger.public_send(method_name, *args, &block)
|
|
45
|
+
end
|
|
46
|
+
rescue StandardError => e
|
|
47
|
+
logger.error "Logger: Failed to log #{method_name} block - #{e.class}: #{e.message}\n#{e.backtrace.join("\n")}"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
attr_reader :log_mutex
|
|
54
|
+
|
|
55
|
+
def client
|
|
56
|
+
@client
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def color(color_value, string)
|
|
60
|
+
"\033[#{color_value}m#{string}\033[0m"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def red(string)
|
|
64
|
+
color(31, string)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def magenta(string)
|
|
68
|
+
color(35, string)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def cyan(string)
|
|
72
|
+
color(36, string)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def connection_id
|
|
76
|
+
if realtime?
|
|
77
|
+
if client.connection.id
|
|
78
|
+
"[#{cyan(client.connection.id)}] "
|
|
79
|
+
else
|
|
80
|
+
"[ #{cyan('--')} ] "
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def realtime?
|
|
86
|
+
defined?(Ably::Realtime::Client) && client.kind_of?(Ably::Realtime::Client)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def default_logger
|
|
90
|
+
::Logger.new(STDOUT).tap do |logger|
|
|
91
|
+
logger.formatter = lambda do |severity, datetime, progname, msg|
|
|
92
|
+
severity = ::Logger::SEV_LABEL.index(severity) if severity.kind_of?(String)
|
|
93
|
+
|
|
94
|
+
formatted_date = if severity == ::Logger::DEBUG
|
|
95
|
+
datetime.strftime("%H:%M:%S.%L")
|
|
96
|
+
else
|
|
97
|
+
datetime.strftime("%Y-%m-%d %H:%M:%S.%L")
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
severity_label = if severity <= ::Logger::INFO
|
|
101
|
+
magenta(::Logger::SEV_LABEL[severity])
|
|
102
|
+
else
|
|
103
|
+
red(::Logger::SEV_LABEL[severity])
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
"#{formatted_date} #{severity_label} #{connection_id}#{msg}\n"
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def ensure_logger_interface_is_valid
|
|
112
|
+
%w(fatal error warn info debug level level=).each do |method|
|
|
113
|
+
unless logger.respond_to?(method)
|
|
114
|
+
raise ArgumentError, "The custom Logger's interface does not provide the method '#{method}'"
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Ably::Models
|
|
2
|
+
# Convert auth details attributes to a {AuthDetails} object
|
|
3
|
+
#
|
|
4
|
+
# @param attributes (see #initialize)
|
|
5
|
+
#
|
|
6
|
+
# @return [AuthDetails]
|
|
7
|
+
#
|
|
8
|
+
def self.AuthDetails(attributes)
|
|
9
|
+
case attributes
|
|
10
|
+
when AuthDetails
|
|
11
|
+
return attributes
|
|
12
|
+
else
|
|
13
|
+
AuthDetails.new(attributes || {})
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# AuthDetails are included in an +AUTH+ {Ably::Models::ProtocolMessage#auth} attribute
|
|
18
|
+
# to provide the realtime service with new token authentication details following a re-auth workflow
|
|
19
|
+
#
|
|
20
|
+
class AuthDetails
|
|
21
|
+
include Ably::Modules::ModelCommon
|
|
22
|
+
|
|
23
|
+
# @param attributes [Hash]
|
|
24
|
+
# @option attributes [String] :access_token token string
|
|
25
|
+
#
|
|
26
|
+
def initialize(attributes = {})
|
|
27
|
+
@hash_object = IdiomaticRubyWrapper(attributes.clone)
|
|
28
|
+
self.attributes.freeze
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# The authentication token string.
|
|
32
|
+
#
|
|
33
|
+
# @spec AD2
|
|
34
|
+
#
|
|
35
|
+
# @return [String]
|
|
36
|
+
#
|
|
37
|
+
def access_token
|
|
38
|
+
attributes[:access_token]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def attributes
|
|
42
|
+
@hash_object
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module Ably::Models
|
|
2
|
+
# Convert token details argument to a {ChannelDetails} object
|
|
3
|
+
#
|
|
4
|
+
# @param attributes (see #initialize)
|
|
5
|
+
#
|
|
6
|
+
# @return [ChannelDetails]
|
|
7
|
+
#
|
|
8
|
+
def self.ChannelDetails(attributes)
|
|
9
|
+
case attributes
|
|
10
|
+
when ChannelDetails
|
|
11
|
+
return attributes
|
|
12
|
+
else
|
|
13
|
+
ChannelDetails.new(attributes)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Contains the details of a {Ably::Models::Rest::Channel} or {Ably::Models::Realtime::Channel} object
|
|
18
|
+
# such as its ID and {Ably::Models::ChannelStatus}.
|
|
19
|
+
#
|
|
20
|
+
class ChannelDetails
|
|
21
|
+
extend Ably::Modules::Enum
|
|
22
|
+
extend Forwardable
|
|
23
|
+
include Ably::Modules::ModelCommon
|
|
24
|
+
|
|
25
|
+
# The attributes of ChannelDetails
|
|
26
|
+
#
|
|
27
|
+
# @spec CHD2
|
|
28
|
+
#
|
|
29
|
+
attr_reader :attributes
|
|
30
|
+
|
|
31
|
+
alias_method :to_h, :attributes
|
|
32
|
+
|
|
33
|
+
# Initialize a new ChannelDetails
|
|
34
|
+
#
|
|
35
|
+
def initialize(attrs)
|
|
36
|
+
@attributes = IdiomaticRubyWrapper(attrs.clone)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# The identifier of the channel
|
|
40
|
+
#
|
|
41
|
+
# @spec CHD2a
|
|
42
|
+
#
|
|
43
|
+
# @return [String]
|
|
44
|
+
#
|
|
45
|
+
def channel_id
|
|
46
|
+
attributes[:channel_id]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# The identifier of the channel
|
|
50
|
+
#
|
|
51
|
+
# @spec CHD2a
|
|
52
|
+
#
|
|
53
|
+
# @return [String]
|
|
54
|
+
#
|
|
55
|
+
def name
|
|
56
|
+
attributes[:name]
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# A {Ably::Models::ChannelStatus} object.
|
|
60
|
+
#
|
|
61
|
+
# @spec CHD2b
|
|
62
|
+
#
|
|
63
|
+
# @return [Ably::Models::ChannelStatus, nil]
|
|
64
|
+
#
|
|
65
|
+
def status
|
|
66
|
+
Ably::Models::ChannelStatus(attributes[:status])
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
module Ably::Models
|
|
2
|
+
# Convert token details argument to a {ChannelMetrics} object
|
|
3
|
+
#
|
|
4
|
+
# @param attributes (see #initialize)
|
|
5
|
+
#
|
|
6
|
+
# @return [ChannelMetrics]
|
|
7
|
+
#
|
|
8
|
+
def self.ChannelMetrics(attributes)
|
|
9
|
+
case attributes
|
|
10
|
+
when ChannelMetrics
|
|
11
|
+
return attributes
|
|
12
|
+
else
|
|
13
|
+
ChannelMetrics.new(attributes)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Contains the metrics associated with a {Ably::Models::Rest::Channel} or {Ably::Models::Realtime::Channel},
|
|
18
|
+
# such as the number of publishers, subscribers and connections it has.
|
|
19
|
+
#
|
|
20
|
+
# @spec CHM1
|
|
21
|
+
#
|
|
22
|
+
class ChannelMetrics
|
|
23
|
+
extend Ably::Modules::Enum
|
|
24
|
+
extend Forwardable
|
|
25
|
+
include Ably::Modules::ModelCommon
|
|
26
|
+
|
|
27
|
+
# The attributes of ChannelMetrics (CHM2)
|
|
28
|
+
#
|
|
29
|
+
attr_reader :attributes
|
|
30
|
+
|
|
31
|
+
alias_method :to_h, :attributes
|
|
32
|
+
|
|
33
|
+
# Initialize a new ChannelMetrics
|
|
34
|
+
#
|
|
35
|
+
def initialize(attrs)
|
|
36
|
+
@attributes = IdiomaticRubyWrapper(attrs.clone)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# The number of realtime connections attached to the channel.
|
|
40
|
+
#
|
|
41
|
+
# @spec CHM2a
|
|
42
|
+
#
|
|
43
|
+
# @return [Integer]
|
|
44
|
+
#
|
|
45
|
+
def connections
|
|
46
|
+
attributes[:connections]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# The number of realtime connections attached to the channel with permission to enter the presence set, regardless
|
|
50
|
+
# of whether or not they have entered it. This requires the presence capability and for a client to not have specified
|
|
51
|
+
# a {Ably::Models::ChannelOptions::MODES} flag that excludes {Ably::Models::ChannelOptions::MODES}#PRESENCE.
|
|
52
|
+
#
|
|
53
|
+
# @spec CHM2b
|
|
54
|
+
#
|
|
55
|
+
# @return [Integer]
|
|
56
|
+
#
|
|
57
|
+
def presence_connections
|
|
58
|
+
attributes[:presence_connections]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# The number of members in the presence set of the channel.
|
|
62
|
+
#
|
|
63
|
+
# @spec CHM2c
|
|
64
|
+
#
|
|
65
|
+
# @return [Integer]
|
|
66
|
+
#
|
|
67
|
+
def presence_members
|
|
68
|
+
attributes[:presence_members]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# The number of realtime attachments receiving presence messages on the channel. This requires the subscribe capability
|
|
72
|
+
# and for a client to not have specified a {Ably::Models::ChannelOptions::MODES} flag that excludes
|
|
73
|
+
# {Ably::Models::ChannelOptions::MODES}#PRESENCE_SUBSCRIBE.
|
|
74
|
+
#
|
|
75
|
+
# @spec CHM2d
|
|
76
|
+
#
|
|
77
|
+
# @return [Integer]
|
|
78
|
+
#
|
|
79
|
+
def presence_subscribers
|
|
80
|
+
attributes[:presence_subscribers]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# The number of realtime attachments permitted to publish messages to the channel. This requires the publish
|
|
84
|
+
# capability and for a client to not have specified a {Ably::Models::ChannelOptions::MODES} flag that excludes
|
|
85
|
+
# {Ably::Models::ChannelOptions::MODES}#PUBLISH.
|
|
86
|
+
#
|
|
87
|
+
# @spec CHM2e
|
|
88
|
+
#
|
|
89
|
+
# @return [Integer]
|
|
90
|
+
#
|
|
91
|
+
def publishers
|
|
92
|
+
attributes[:publishers]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# The number of realtime attachments receiving messages on the channel. This requires the subscribe capability and
|
|
96
|
+
# for a client to not have specified a {Ably::Models::ChannelOptions::MODES} flag that excludes
|
|
97
|
+
# {Ably::Models::ChannelOptions::MODES}#SUBSCRIBE.
|
|
98
|
+
#
|
|
99
|
+
# @spec CHM2f
|
|
100
|
+
#
|
|
101
|
+
# @return [Integer]
|
|
102
|
+
#
|
|
103
|
+
def subscribers
|
|
104
|
+
attributes[:subscribers]
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Ably::Models
|
|
2
|
+
# Convert token details argument to a {ChannelOccupancy} object
|
|
3
|
+
#
|
|
4
|
+
# @param attributes (see #initialize)
|
|
5
|
+
#
|
|
6
|
+
# @return [ChannelOccupancy]
|
|
7
|
+
#
|
|
8
|
+
def self.ChannelOccupancy(attributes)
|
|
9
|
+
case attributes
|
|
10
|
+
when ChannelOccupancy
|
|
11
|
+
return attributes
|
|
12
|
+
else
|
|
13
|
+
ChannelOccupancy.new(attributes)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Contains the metrics of a {Ably::Models::Rest::Channel} or {Ably::Models::Realtime::Channel} object.
|
|
18
|
+
#
|
|
19
|
+
# @spec CHO1
|
|
20
|
+
#
|
|
21
|
+
class ChannelOccupancy
|
|
22
|
+
extend Ably::Modules::Enum
|
|
23
|
+
extend Forwardable
|
|
24
|
+
include Ably::Modules::ModelCommon
|
|
25
|
+
|
|
26
|
+
# The attributes of ChannelOccupancy.
|
|
27
|
+
#
|
|
28
|
+
# @spec CH02
|
|
29
|
+
#
|
|
30
|
+
attr_reader :attributes
|
|
31
|
+
|
|
32
|
+
alias_method :to_h, :attributes
|
|
33
|
+
|
|
34
|
+
# Initialize a new ChannelOccupancy
|
|
35
|
+
#
|
|
36
|
+
def initialize(attrs)
|
|
37
|
+
@attributes = IdiomaticRubyWrapper(attrs.clone)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# A {Ably::Models::ChannelMetrics} object.
|
|
41
|
+
#
|
|
42
|
+
# @spec CHO2a
|
|
43
|
+
#
|
|
44
|
+
# @return [Ably::Models::ChannelMetrics, nil]
|
|
45
|
+
#
|
|
46
|
+
def metrics
|
|
47
|
+
Ably::Models::ChannelMetrics(attributes[:metrics])
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
module Ably::Models
|
|
2
|
+
# Convert token details argument to a {ChannelOptions} object
|
|
3
|
+
#
|
|
4
|
+
# @param attributes (see #initialize)
|
|
5
|
+
#
|
|
6
|
+
# @return [ChannelOptions]
|
|
7
|
+
#
|
|
8
|
+
def self.ChannelOptions(attributes)
|
|
9
|
+
case attributes
|
|
10
|
+
when ChannelOptions
|
|
11
|
+
return attributes
|
|
12
|
+
else
|
|
13
|
+
ChannelOptions.new(attributes)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Represents options of a channel
|
|
18
|
+
class ChannelOptions
|
|
19
|
+
extend Ably::Modules::Enum
|
|
20
|
+
extend Forwardable
|
|
21
|
+
include Ably::Modules::ModelCommon
|
|
22
|
+
|
|
23
|
+
# Describes the possible flags used to configure client capabilities, using {Ably::Models::ChannelOptions::MODES}.
|
|
24
|
+
#
|
|
25
|
+
# PRESENCE The client can enter the presence set.
|
|
26
|
+
# PUBLISH The client can publish messages.
|
|
27
|
+
# SUBSCRIBE The client can subscribe to messages.
|
|
28
|
+
# PRESENCE_SUBSCRIBE The client can receive presence messages.
|
|
29
|
+
#
|
|
30
|
+
# @spec TB2d
|
|
31
|
+
#
|
|
32
|
+
MODES = ruby_enum('MODES',
|
|
33
|
+
presence: 0,
|
|
34
|
+
publish: 1,
|
|
35
|
+
subscribe: 2,
|
|
36
|
+
presence_subscribe: 3
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
attr_reader :attributes
|
|
40
|
+
|
|
41
|
+
alias_method :to_h, :attributes
|
|
42
|
+
|
|
43
|
+
def_delegators :attributes, :fetch, :size, :empty?
|
|
44
|
+
# Initialize a new ChannelOptions
|
|
45
|
+
#
|
|
46
|
+
# @spec TB3
|
|
47
|
+
#
|
|
48
|
+
# @option params [Hash] (TB2c) params (for realtime client libraries only) a of key/value pairs
|
|
49
|
+
# @option modes [Hash] modes (for realtime client libraries only) an array of ChannelMode
|
|
50
|
+
# @option cipher [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.
|
|
51
|
+
#
|
|
52
|
+
def initialize(attrs)
|
|
53
|
+
@attributes = IdiomaticRubyWrapper(attrs.clone)
|
|
54
|
+
|
|
55
|
+
attributes[:modes] = modes.to_a.map { |mode| Ably::Models::ChannelOptions::MODES[mode] } if modes
|
|
56
|
+
attributes[:cipher] = Ably::Models::CipherParams(cipher) if cipher
|
|
57
|
+
attributes.clone
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Requests encryption for this channel when not null, and specifies encryption-related parameters (such as algorithm,
|
|
61
|
+
# chaining mode, key length and key). See an example.
|
|
62
|
+
#
|
|
63
|
+
# @spec RSL5a, TB2b
|
|
64
|
+
#
|
|
65
|
+
# @return [CipherParams]
|
|
66
|
+
#
|
|
67
|
+
def cipher
|
|
68
|
+
attributes[:cipher]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Channel Parameters that configure the behavior of the channel.
|
|
72
|
+
#
|
|
73
|
+
# @spec TB2c
|
|
74
|
+
#
|
|
75
|
+
# @return [Hash]
|
|
76
|
+
#
|
|
77
|
+
def params
|
|
78
|
+
attributes[:params].to_h
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# An array of {Ably:Models:ChannelOptions::MODES} objects.
|
|
82
|
+
#
|
|
83
|
+
# @spec TB2d
|
|
84
|
+
#
|
|
85
|
+
# @return [Array<ChannelOptions::MODES>]
|
|
86
|
+
#
|
|
87
|
+
def modes
|
|
88
|
+
attributes[:modes]
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Converts modes to a bitfield that coresponds to ProtocolMessage#flags
|
|
92
|
+
#
|
|
93
|
+
# @return [Integer]
|
|
94
|
+
#
|
|
95
|
+
def modes_to_flags
|
|
96
|
+
modes.map { |mode| Ably::Models::ProtocolMessage::ATTACH_FLAGS_MAPPING[mode.to_sym] }.reduce(:|)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# @return [Hash]
|
|
100
|
+
# @api private
|
|
101
|
+
def set_params(hash)
|
|
102
|
+
attributes[:params] = hash
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Sets modes from ProtocolMessage#flags
|
|
106
|
+
#
|
|
107
|
+
# @return [Array<ChannelOptions::MODES>]
|
|
108
|
+
# @api private
|
|
109
|
+
def set_modes_from_flags(flags)
|
|
110
|
+
return unless flags
|
|
111
|
+
|
|
112
|
+
message_modes = MODES.select do |mode|
|
|
113
|
+
flag = Ably::Models::ProtocolMessage::ATTACH_FLAGS_MAPPING[mode.to_sym]
|
|
114
|
+
flags & flag == flag
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
attributes[:modes] = message_modes.map { |mode| Ably::Models::ChannelOptions::MODES[mode] }
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|