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,114 @@
|
|
|
1
|
+
module Ably::Rest
|
|
2
|
+
class Push
|
|
3
|
+
# Manage device registrations for push notifications
|
|
4
|
+
class DeviceRegistrations
|
|
5
|
+
include Ably::Modules::Conversions
|
|
6
|
+
|
|
7
|
+
# @api private
|
|
8
|
+
attr_reader :client
|
|
9
|
+
|
|
10
|
+
# @api private
|
|
11
|
+
attr_reader :admin
|
|
12
|
+
|
|
13
|
+
def initialize(admin)
|
|
14
|
+
@admin = admin
|
|
15
|
+
@client = admin.client
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Get registered device by device ID
|
|
19
|
+
#
|
|
20
|
+
# @spec RSH1b1
|
|
21
|
+
#
|
|
22
|
+
# @param [String, Ably::Models::DeviceDetails] device_id the device to retrieve
|
|
23
|
+
#
|
|
24
|
+
# @return [Ably::Models::DeviceDetails] Returns {Ably::Models::DeviceDetails} if a match is found else a {Ably::Exceptions::ResourceMissing} is raised
|
|
25
|
+
#
|
|
26
|
+
def get(device_id)
|
|
27
|
+
device_id = device_id.id if device_id.kind_of?(Ably::Models::DeviceDetails)
|
|
28
|
+
raise ArgumentError, "device_id must be a string or DeviceDetails object" unless device_id.kind_of?(String)
|
|
29
|
+
|
|
30
|
+
DeviceDetails(client.get("/push/deviceRegistrations/#{device_id}").body)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# List registered devices filtered by optional params
|
|
34
|
+
#
|
|
35
|
+
# @spec RSH1b2
|
|
36
|
+
#
|
|
37
|
+
# @param [Hash] params the filter options for the list registered device request
|
|
38
|
+
# @option params [String] :client_id filter by devices registered to a client identifier. Cannot be used with +device_id+ param
|
|
39
|
+
# @option params [String] :device_id filter by unique device ID. Cannot be used with +client_id+ param
|
|
40
|
+
# @option params [Integer] :limit maximum number of devices to retrieve up to 1,000, defaults to 100
|
|
41
|
+
#
|
|
42
|
+
# @return [Ably::Models::PaginatedResult<Ably::Models::DeviceDetails>] Paginated list of matching {Ably::Models::DeviceDetails}
|
|
43
|
+
#
|
|
44
|
+
def list(params = {})
|
|
45
|
+
params = {} if params.nil?
|
|
46
|
+
raise ArgumentError, "params must be a Hash" unless params.kind_of?(Hash)
|
|
47
|
+
raise ArgumentError, "device_id filter cannot be specified alongside a client_id filter. Use one or the other" if params[:client_id] && params[:device_id]
|
|
48
|
+
|
|
49
|
+
params = params.clone
|
|
50
|
+
|
|
51
|
+
paginated_options = {
|
|
52
|
+
coerce_into: 'Ably::Models::DeviceDetails',
|
|
53
|
+
async_blocking_operations: params.delete(:async_blocking_operations),
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
response = client.get('/push/deviceRegistrations', IdiomaticRubyWrapper(params).as_json)
|
|
57
|
+
|
|
58
|
+
Ably::Models::PaginatedResult.new(response, '', client, paginated_options)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Registers or updates a {Ably::Models::DeviceDetails} object with Ably.
|
|
62
|
+
# Returns the new, or updated {Ably::Models::DeviceDetails} object.
|
|
63
|
+
#
|
|
64
|
+
# @spec RSH1b3
|
|
65
|
+
#
|
|
66
|
+
# @param [Ably::Models::DeviceDetails, Hash] device the device details to save
|
|
67
|
+
#
|
|
68
|
+
# @return [void]
|
|
69
|
+
#
|
|
70
|
+
def save(device)
|
|
71
|
+
device_details = DeviceDetails(device)
|
|
72
|
+
raise ArgumentError, "Device ID is required yet is empty" if device_details.id.nil? || device_details == ''
|
|
73
|
+
|
|
74
|
+
client.put("/push/deviceRegistrations/#{device_details.id}", device_details.as_json)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Remove device
|
|
78
|
+
#
|
|
79
|
+
# @spec RSH1b4
|
|
80
|
+
#
|
|
81
|
+
# @param [String, Ably::Models::DeviceDetails] device_id the device to remove
|
|
82
|
+
#
|
|
83
|
+
# @return [void]
|
|
84
|
+
#
|
|
85
|
+
def remove(device_id)
|
|
86
|
+
device_id = device_id.id if device_id.kind_of?(Ably::Models::DeviceDetails)
|
|
87
|
+
raise ArgumentError, "device_id must be a string or DeviceDetails object" unless device_id.kind_of?(String)
|
|
88
|
+
|
|
89
|
+
client.delete("/push/deviceRegistrations/#{device_id}", {})
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Removes all devices registered to receive push notifications from Ably matching the filter params provided.
|
|
93
|
+
#
|
|
94
|
+
# @spec RSH1b5
|
|
95
|
+
#
|
|
96
|
+
# @param [Hash] params the filter params for the remove request
|
|
97
|
+
# @option params [String] :client_id remove devices registered to a client identifier. Cannot be used with +device_id+ param
|
|
98
|
+
# @option params [String] :device_id remove device with this unique device ID. Cannot be used with +client_id+ param
|
|
99
|
+
#
|
|
100
|
+
# @return [void]
|
|
101
|
+
#
|
|
102
|
+
def remove_where(params = {})
|
|
103
|
+
filter = if params.kind_of?(Ably::Models::DeviceDetails)
|
|
104
|
+
{ 'deviceId' => params.id }
|
|
105
|
+
else
|
|
106
|
+
raise ArgumentError, "params must be a Hash" unless params.kind_of?(Hash)
|
|
107
|
+
raise ArgumentError, "device_id filter cannot be specified alongside a client_id filter. Use one or the other" if params[:client_id] && params[:device_id]
|
|
108
|
+
IdiomaticRubyWrapper(params).as_json
|
|
109
|
+
end
|
|
110
|
+
client.delete("/push/deviceRegistrations", filter)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'ably/rest/push/admin'
|
|
2
|
+
|
|
3
|
+
module Ably
|
|
4
|
+
module Rest
|
|
5
|
+
# Class providing push notification functionality
|
|
6
|
+
class Push
|
|
7
|
+
include Ably::Modules::Conversions
|
|
8
|
+
|
|
9
|
+
# @private
|
|
10
|
+
attr_reader :client
|
|
11
|
+
|
|
12
|
+
def initialize(client)
|
|
13
|
+
@client = client
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Admin features for push notifications like managing devices and channel subscriptions
|
|
17
|
+
#
|
|
18
|
+
# @return [Ably::Rest::Push::Admin]
|
|
19
|
+
#
|
|
20
|
+
def admin
|
|
21
|
+
@admin ||= Admin.new(self)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/ably/rest.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'ably/rest/channel'
|
|
2
|
+
require 'ably/rest/channels'
|
|
3
|
+
require 'ably/rest/client'
|
|
4
|
+
require 'ably/rest/push'
|
|
5
|
+
require 'ably/rest/presence'
|
|
6
|
+
|
|
7
|
+
require 'ably/models/message_encoders/base'
|
|
8
|
+
|
|
9
|
+
Dir.glob(File.expand_path("models/*.rb", File.dirname(__FILE__))).each do |file|
|
|
10
|
+
require file
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
module Ably
|
|
14
|
+
# Rest provides the top-level class to be instanced for the Ably Rest library
|
|
15
|
+
#
|
|
16
|
+
# @example
|
|
17
|
+
# client = Ably::Rest.new("xxxxx")
|
|
18
|
+
# channel = client.channel("test")
|
|
19
|
+
# channel.publish "greeting", "data"
|
|
20
|
+
#
|
|
21
|
+
module Rest
|
|
22
|
+
# Convenience method providing an alias to {Ably::Rest::Client} constructor.
|
|
23
|
+
#
|
|
24
|
+
# @param (see Ably::Rest::Client#initialize)
|
|
25
|
+
# @option options (see Ably::Rest::Client#initialize)
|
|
26
|
+
#
|
|
27
|
+
# @return [Ably::Rest::Client]
|
|
28
|
+
#
|
|
29
|
+
# @example
|
|
30
|
+
# # create a new client authenticating with basic auth
|
|
31
|
+
# client = Ably::Rest.new('key.id:secret')
|
|
32
|
+
#
|
|
33
|
+
# # create a new client authenticating with basic auth and a client_id
|
|
34
|
+
# client = Ably::Rest.new(key: 'key.id:secret', client_id: 'john')
|
|
35
|
+
#
|
|
36
|
+
def self.new(options)
|
|
37
|
+
Ably::Rest::Client.new(options)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ably::Util
|
|
4
|
+
module AblyExtensions
|
|
5
|
+
refine Object do
|
|
6
|
+
def nil_or_empty?
|
|
7
|
+
self.nil? || self.empty?
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
refine Hash do
|
|
12
|
+
def fetch_with_default(key, default)
|
|
13
|
+
value = self.fetch(key, default)
|
|
14
|
+
if value.nil?
|
|
15
|
+
return default
|
|
16
|
+
end
|
|
17
|
+
return value
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def delete_with_default(key, default)
|
|
21
|
+
value = self.delete(key)
|
|
22
|
+
if value.nil?
|
|
23
|
+
return default
|
|
24
|
+
end
|
|
25
|
+
return value
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require 'msgpack'
|
|
2
|
+
require 'openssl'
|
|
3
|
+
|
|
4
|
+
module Ably::Util
|
|
5
|
+
# Contains the properties required to configure the encryption of {Ably::Models::Message} payloads.
|
|
6
|
+
#
|
|
7
|
+
class Crypto
|
|
8
|
+
DEFAULTS = {
|
|
9
|
+
algorithm: 'aes',
|
|
10
|
+
mode: 'cbc',
|
|
11
|
+
key_length: 256,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
BLOCK_LENGTH = 16
|
|
15
|
+
|
|
16
|
+
# Configured {Ably::Models::CipherParams} for this Crypto object, see {#initialize} for a list of configureable options
|
|
17
|
+
#
|
|
18
|
+
# @return [Ably::Models::CipherParams]
|
|
19
|
+
#
|
|
20
|
+
attr_reader :cipher_params
|
|
21
|
+
|
|
22
|
+
# Creates a {Ably::Util::Crypto} object
|
|
23
|
+
#
|
|
24
|
+
# @param [Hash] params a Hash used to configure the Crypto library's {Ably::Models::CipherParams}
|
|
25
|
+
# @option params (see Ably::Models::CipherParams#initialize)
|
|
26
|
+
#
|
|
27
|
+
# @return [Ably::Util::Crypto]
|
|
28
|
+
#
|
|
29
|
+
# @example
|
|
30
|
+
# key = Ably::Util::Crypto.generate_random_key
|
|
31
|
+
# crypto = Ably::Util::Crypto.new(key: key)
|
|
32
|
+
# encrypted = crypto.encrypt('secret text')
|
|
33
|
+
# crypto.decrypt(decrypted) # => 'secret text'
|
|
34
|
+
#
|
|
35
|
+
def initialize(params)
|
|
36
|
+
@fixed_iv = params[:fixed_iv]
|
|
37
|
+
@cipher_params = Ably::Models::CipherParams(params)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns a {Ably::Models::CipherParams} object, using the default values for any fields not supplied by the `Hash` object.
|
|
41
|
+
#
|
|
42
|
+
# @spec RSE1, RSE1b, RSE1b
|
|
43
|
+
#
|
|
44
|
+
# @param [Hash] params a Hash used to configure the Crypto library's {Ably::Models::CipherParams}
|
|
45
|
+
# @option params (see {Ably::Models::CipherParams#initialize})
|
|
46
|
+
#
|
|
47
|
+
# @return [Ably::Models::CipherParams] Configured cipher params with :key, :algorithm, :mode, :key_length attributes
|
|
48
|
+
#
|
|
49
|
+
def self.get_default_params(params = {})
|
|
50
|
+
Ably::Models::CipherParams(params)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Generates a random key to be used in the encryption of the channel. If the language cryptographic randomness
|
|
54
|
+
# primitives are blocking or async, a callback is used. The callback returns a generated binary key.
|
|
55
|
+
#
|
|
56
|
+
# @spec RSE2, RSE2a, RSE2b
|
|
57
|
+
#
|
|
58
|
+
# @param [Integer] key_length The length of the key, in bits, to be generated. If not specified, this is equal to the default keyLength of the default algorithm: for AES this is 256 bits.
|
|
59
|
+
# @return Binary The key as a binary, for example, a byte array.
|
|
60
|
+
#
|
|
61
|
+
def self.generate_random_key(key_length = DEFAULTS.fetch(:key_length))
|
|
62
|
+
params = DEFAULTS.merge(key_length: key_length)
|
|
63
|
+
OpenSSL::Cipher.new(cipher_type(params)).random_key
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# The Cipher algorithm string such as AES-128-CBC
|
|
67
|
+
# @api private
|
|
68
|
+
def self.cipher_type(options)
|
|
69
|
+
Ably::Models::CipherParams.cipher_type(options)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Encrypt payload using configured Cipher
|
|
73
|
+
#
|
|
74
|
+
# @param [String] payload the payload to be encrypted
|
|
75
|
+
# @param [Hash] encrypt_options an options Hash to configure the encrypt action
|
|
76
|
+
# @option encrypt_options [String] :iv optionally use the provided Initialization Vector instead of a randomly generated IV
|
|
77
|
+
#
|
|
78
|
+
# @return [String] binary string with +Encoding::ASCII_8BIT+ encoding
|
|
79
|
+
#
|
|
80
|
+
def encrypt(payload, encrypt_options = {})
|
|
81
|
+
cipher = openssl_cipher
|
|
82
|
+
cipher.encrypt
|
|
83
|
+
cipher.key = key
|
|
84
|
+
iv = encrypt_options[:iv] || fixed_iv || cipher.random_iv
|
|
85
|
+
cipher.iv = iv
|
|
86
|
+
iv << cipher.update(payload) unless payload.empty?
|
|
87
|
+
iv << cipher.final
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Decrypt payload using configured Cipher
|
|
91
|
+
#
|
|
92
|
+
# @param [String] encrypted_payload_with_iv the encrypted payload to be decrypted
|
|
93
|
+
#
|
|
94
|
+
# @return [String]
|
|
95
|
+
#
|
|
96
|
+
def decrypt(encrypted_payload_with_iv)
|
|
97
|
+
raise Ably::Exceptions::CipherError, 'iv is missing or not long enough' unless encrypted_payload_with_iv.length >= BLOCK_LENGTH*2
|
|
98
|
+
|
|
99
|
+
iv = encrypted_payload_with_iv.slice(0...BLOCK_LENGTH)
|
|
100
|
+
encrypted_payload = encrypted_payload_with_iv.slice(BLOCK_LENGTH..-1)
|
|
101
|
+
|
|
102
|
+
decipher = openssl_cipher
|
|
103
|
+
decipher.decrypt
|
|
104
|
+
decipher.key = key
|
|
105
|
+
decipher.iv = iv
|
|
106
|
+
|
|
107
|
+
decipher.update(encrypted_payload) << decipher.final
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Generate a random IV
|
|
111
|
+
# @return [String]
|
|
112
|
+
def random_iv
|
|
113
|
+
openssl_cipher.random_iv
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
private
|
|
117
|
+
# Used solely for tests to fix the IV instead of randomly generate one
|
|
118
|
+
attr_reader :fixed_iv
|
|
119
|
+
|
|
120
|
+
# Generate a random key
|
|
121
|
+
# @return [String]
|
|
122
|
+
def random_key
|
|
123
|
+
openssl_cipher.random_key
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def key
|
|
127
|
+
cipher_params.key
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def openssl_cipher
|
|
131
|
+
@openssl_cipher ||= OpenSSL::Cipher.new(cipher_params.cipher_type)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'ably/modules/event_emitter.rb'
|
|
2
|
+
|
|
3
|
+
module Ably::Util
|
|
4
|
+
# PubSub class provides methods to publish & subscribe to events, with methods and naming
|
|
5
|
+
# intentionally different to EventEmitter as it is intended for private message handling
|
|
6
|
+
# within the client library.
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# class Channel
|
|
10
|
+
# def messages
|
|
11
|
+
# @messages ||= PubSub.new
|
|
12
|
+
# end
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# channel = Channel.new
|
|
16
|
+
# channel.messages.subscribe(:event) { |name| puts "Event message #{name} received" }
|
|
17
|
+
# channel.messages.publish :event, "Test"
|
|
18
|
+
# #=> "Event message Test received"
|
|
19
|
+
# channel.messages.remove :event
|
|
20
|
+
#
|
|
21
|
+
class PubSub
|
|
22
|
+
include Ably::Modules::EventEmitter
|
|
23
|
+
|
|
24
|
+
# Ensure new PubSub object does not share class instance variables
|
|
25
|
+
def self.new(options = {})
|
|
26
|
+
Class.new(PubSub).allocate.tap do |pub_sub_object|
|
|
27
|
+
pub_sub_object.send(:initialize, options)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def inspect
|
|
32
|
+
"<#PubSub: @event_emitter_coerce_proc: #{self.class.event_emitter_coerce_proc.inspect}\n @callbacks: #{callbacks}>"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def initialize(options = {})
|
|
36
|
+
self.class.instance_eval do
|
|
37
|
+
configure_event_emitter options
|
|
38
|
+
|
|
39
|
+
alias_method :subscribe, :unsafe_on
|
|
40
|
+
alias_method :publish, :emit
|
|
41
|
+
alias_method :unsubscribe, :unsafe_off
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Ably::Util
|
|
2
|
+
# SafeDeferrable class provides a Deferrable that is safe to use for for public interfaces
|
|
3
|
+
# of this client library. Any exceptions raised in the success or failure callbacks are
|
|
4
|
+
# caught and logged to the provided logger.
|
|
5
|
+
#
|
|
6
|
+
# An exception in a callback provided by a developer should not break this client library
|
|
7
|
+
# and stop further execution of code.
|
|
8
|
+
#
|
|
9
|
+
class SafeDeferrable
|
|
10
|
+
include Ably::Modules::SafeDeferrable
|
|
11
|
+
|
|
12
|
+
attr_reader :logger
|
|
13
|
+
|
|
14
|
+
def initialize(logger)
|
|
15
|
+
@logger = logger
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Create a new {SafeDeferrable} and fail immediately with the provided error in the next eventloop cycle
|
|
19
|
+
#
|
|
20
|
+
# @param error [Ably::Exceptions::BaseAblyException, Ably::Models::ErrorInfo] The error used to fail the newly created {SafeDeferrable}
|
|
21
|
+
#
|
|
22
|
+
# @return [SafeDeferrable]
|
|
23
|
+
#
|
|
24
|
+
def self.new_and_fail_immediately(logger, error)
|
|
25
|
+
new(logger).tap do |deferrable|
|
|
26
|
+
EventMachine.next_tick do
|
|
27
|
+
deferrable.fail error
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Create a new {SafeDeferrable} and succeed immediately with the provided arguments in the next eventloop cycle
|
|
33
|
+
#
|
|
34
|
+
# @return [SafeDeferrable]
|
|
35
|
+
#
|
|
36
|
+
def self.new_and_succeed_immediately(logger, *args)
|
|
37
|
+
new(logger).tap do |deferrable|
|
|
38
|
+
EventMachine.next_tick do
|
|
39
|
+
deferrable.succeed *args
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
data/lib/ably/version.rb
ADDED
data/lib/ably.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'addressable/uri'
|
|
2
|
+
|
|
3
|
+
require 'ably/version'
|
|
4
|
+
require 'ably/agent'
|
|
5
|
+
|
|
6
|
+
%w(modules util).each do |namespace|
|
|
7
|
+
Dir.glob(File.expand_path("ably/#{namespace}/*.rb", File.dirname(__FILE__))).sort.each do |file|
|
|
8
|
+
require file
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
require 'ably/auth'
|
|
13
|
+
require 'ably/exceptions'
|
|
14
|
+
require 'ably/logger'
|
|
15
|
+
require 'ably/realtime'
|
|
16
|
+
require 'ably/rest'
|