Class: Ably::Realtime::Presence
- Inherits:
-
Object
- Object
- Ably::Realtime::Presence
- Extended by:
- Modules::Enum
- Includes:
- Modules::AsyncWrapper, Modules::Conversions, Modules::EventEmitter, Modules::MessageEmitter, Modules::SafeYield, Modules::StateEmitter, Modules::UsesStateMachine
- Defined in:
- lib/ably/realtime/presence.rb,
lib/ably/realtime/presence/members_map.rb,
lib/ably/realtime/presence/presence_manager.rb,
lib/ably/realtime/presence/presence_state_machine.rb
Overview
Presence provides access to presence operations and state for the associated Channel
Defined Under Namespace
Classes: MembersMap, PresenceManager, PresenceStateMachine
Constant Summary collapse
- STATE =
ruby_enum('STATE', :initialized, :entering, :entered, :leaving, :left, :failed )
Instance Attribute Summary collapse
-
#__incoming_msgbus__ ⇒ Ably::Util::PubSub
readonly
private
Client library internal channel incoming protocol message bus.
-
#channel ⇒ Ably::Realtime::Channel
readonly
Channel this Presence object is associated with.
-
#client_id ⇒ String
readonly
The client_id for the member present on this channel.
-
#connection_id ⇒ String
readonly
A unique identifier for this channel client based on their connection, disambiguating situations where a given client_id is present on multiple connections simultaneously.
-
#data ⇒ String
readonly
The data for the member present on this channel.
-
#manager ⇒ Ably::Realtime::Presence::PresenceManager
readonly
private
The Presence manager responsible for actions relating to state changes such as entering a channel.
-
#members ⇒ MembersMap
readonly
private
MembersMap containing an up to date list of members on this channel.
Attributes included from Modules::UsesStateMachine
#previous_state, #state_history
Instance Method Summary collapse
-
#enter(options = {}) {|Ably::Realtime::Presence| ... } ⇒ Ably::Util::SafeDeferrable
Enter this client into this channel.
-
#enter_client(client_id, options = {}) {|Ably::Realtime::Presence| ... } ⇒ Ably::Util::SafeDeferrable
Enter the specified client_id into this channel.
-
#get(options = {}) {|Array<Ably::Models::PresenceMessage>| ... } ⇒ Ably::Util::SafeDeferrable
Get the presence state for this Channel.
-
#history(options = {}) {|Ably::Models::PaginatedResult<Ably::Models::PresenceMessage>| ... } ⇒ Ably::Util::SafeDeferrable
Return the presence messages history for the channel.
-
#initialize(channel) ⇒ Presence
constructor
A new instance of Presence.
-
#leave(options = {}) {|Ably::Realtime::Presence| ... } ⇒ Ably::Util::SafeDeferrable
Leave this client from this channel.
-
#leave_client(client_id, options = {}) {|Ably::Realtime::Presence| ... } ⇒ Ably::Util::SafeDeferrable
Leave a given client_id from this channel.
-
#logger ⇒ Object
private
Used by Modules::StateEmitter to debug action changes.
-
#set_connection_id(new_connection_id) ⇒ Object
private
Configure the connection ID for this presence channel.
-
#subscribe(*actions) {|Ably::Models::PresenceMessage| ... } ⇒ void
Subscribe to presence events on the associated Channel.
-
#sync_complete? ⇒ Boolean
Returns true when the initial member SYNC following channel attach is completed.
-
#unsubscribe(*actions, &callback) ⇒ void
Unsubscribe the matching block for presence events on the associated Channel.
-
#update(options = {}) {|Ably::Realtime::Presence| ... } ⇒ Ably::Util::SafeDeferrable
Update the presence data for this client.
-
#update_client(client_id, options = {}) {|Ably::Realtime::Presence| ... } ⇒ Ably::Util::SafeDeferrable
Update the presence data for a specified client_id into this channel.
Methods included from Modules::UsesStateMachine
#synchronize_state_with_statemachine, #transition_state_machine, #transition_state_machine!
Methods included from Modules::StateEmitter
#once_or_if, #once_state_changed, #state, #state=, #state?, #unsafe_once_or_if, #unsafe_once_state_changed
Methods included from Modules::MessageEmitter
Methods included from Modules::EventEmitter
#emit, #off, #on, #once, #unsafe_on, #unsafe_once
Constructor Details
#initialize(channel) ⇒ Presence
Returns a new instance of Presence.
49 50 51 52 53 54 55 56 57 |
# File 'lib/ably/realtime/presence.rb', line 49 def initialize(channel) @channel = channel @client_id = client.client_id @state_machine = PresenceStateMachine.new(self) @state = STATE(state_machine.current_state) @members = MembersMap.new(self) @manager = PresenceManager.new(self) end |
Instance Attribute Details
#__incoming_msgbus__ ⇒ Ably::Util::PubSub (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Returns Client library internal channel incoming protocol message bus.
317 318 319 320 321 |
# File 'lib/ably/realtime/presence.rb', line 317 def __incoming_msgbus__ @__incoming_msgbus__ ||= Ably::Util::PubSub.new( coerce_into: Proc.new { |event| Ably::Models::ProtocolMessage::ACTION(event) } ) end |
#channel ⇒ Ably::Realtime::Channel (readonly)
Channel this Presence object is associated with
24 25 26 |
# File 'lib/ably/realtime/presence.rb', line 24 def channel @channel end |
#client_id ⇒ String (readonly)
The client_id for the member present on this channel
33 34 35 |
# File 'lib/ably/realtime/presence.rb', line 33 def client_id @client_id end |
#connection_id ⇒ String (readonly)
A unique identifier for this channel client based on their connection, disambiguating situations where a given client_id is present on multiple connections simultaneously.
29 30 31 |
# File 'lib/ably/realtime/presence.rb', line 29 def connection_id @connection_id end |
#data ⇒ String (readonly)
The data for the member present on this channel
37 38 39 |
# File 'lib/ably/realtime/presence.rb', line 37 def data @data end |
#manager ⇒ Ably::Realtime::Presence::PresenceManager (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The Presence manager responsible for actions relating to state changes such as entering a channel
47 48 49 |
# File 'lib/ably/realtime/presence.rb', line 47 def manager @manager end |
#members ⇒ MembersMap (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
MembersMap containing an up to date list of members on this channel
42 43 44 |
# File 'lib/ably/realtime/presence.rb', line 42 def members @members end |
Instance Method Details
#enter(options = {}) {|Ably::Realtime::Presence| ... } ⇒ Ably::Util::SafeDeferrable
Enter this client into this channel. This client will be added to the presence set and presence subscribers will see an enter message for this client.
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/ably/realtime/presence.rb', line 72 def enter( = {}, &success_block) client_id = .fetch(:client_id, self.client_id) data = .fetch(:data, nil) deferrable = create_deferrable ensure_supported_client_id client_id ensure_supported_payload data unless data.nil? @data = data @client_id = client_id return deferrable_succeed(deferrable, &success_block) if state == STATE.Entered ensure_presence_publishable_on_connection ensure_channel_attached(deferrable) do if entering? once_or_if(STATE.Entered, else: proc { |args| deferrable_fail deferrable, *args }) do deferrable_succeed deferrable, &success_block end else change_state STATE.Entering ( Ably::Models::PresenceMessage::ACTION.Enter, deferrable: deferrable, target_state: STATE.Entered, client_id: client_id, data: data, failed_state: STATE.Failed, &success_block ) end end end |
#enter_client(client_id, options = {}) {|Ably::Realtime::Presence| ... } ⇒ Ably::Util::SafeDeferrable
Enter the specified client_id into this channel. The given client will be added to the presence set and presence subscribers will see a corresponding presence message. This method is provided to support connections (e.g. connections from application server instances) that act on behalf of multiple client_ids. In order to be able to enter the channel with this method, the client library must have been instanced either with a key, or with a token bound to the wildcard client_id
121 122 123 124 125 126 127 |
# File 'lib/ably/realtime/presence.rb', line 121 def enter_client(client_id, = {}, &success_block) raise ArgumentError, 'options must be a Hash' unless .kind_of?(Hash) ensure_supported_client_id client_id ensure_supported_payload [:data] if .has_key?(:data) send_presence_action_for_client(Ably::Models::PresenceMessage::ACTION.Enter, client_id, , &success_block) end |
#get(options = {}) {|Array<Ably::Models::PresenceMessage>| ... } ⇒ Ably::Util::SafeDeferrable
Get the presence state for this Channel.
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 |
# File 'lib/ably/realtime/presence.rb', line 247 def get( = {}, &block) deferrable = create_deferrable ensure_channel_attached(deferrable) do members.get().tap do |members_map_deferrable| members_map_deferrable.callback do |*args| safe_yield(block, *args) if block_given? deferrable.succeed(*args) end members_map_deferrable.errback do |*args| deferrable.fail(*args) end end end end |
#history(options = {}) {|Ably::Models::PaginatedResult<Ably::Models::PresenceMessage>| ... } ⇒ Ably::Util::SafeDeferrable
Return the presence messages history for the channel
Once attached to a channel, you can retrieve presence message history on the channel before the channel was attached with the option until_attach: true
. This is very useful for developers who wish to capture new presence events as well as retrieve historical presence state with the guarantee that no presence history has been missed.
303 304 305 306 307 308 309 310 311 312 |
# File 'lib/ably/realtime/presence.rb', line 303 def history( = {}, &callback) if .delete(:until_attach) raise ArgumentError, 'option :until_attach cannot be specified if the channel is not attached' unless channel.attached? [:from_serial] = channel.attached_serial end async_wrap(callback) do rest_presence.history(.merge(async_blocking_operations: true)) end end |
#leave(options = {}) {|Ably::Realtime::Presence| ... } ⇒ Ably::Util::SafeDeferrable
Leave this client from this channel. This client will be removed from the presence set and presence subscribers will see a leave message for this client.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/ably/realtime/presence.rb', line 138 def leave( = {}, &success_block) data = .fetch(:data, self.data) # nil value defaults leave data to existing value deferrable = create_deferrable ensure_supported_client_id client_id ensure_supported_payload data unless data.nil? raise Ably::Exceptions::Standard.new('Unable to leave presence channel that is not entered', 400, 91002) unless able_to_leave? @data = data return deferrable_succeed(deferrable, &success_block) if state == STATE.Left ensure_presence_publishable_on_connection ensure_channel_attached(deferrable) do if leaving? once_or_if(STATE.Left, else: proc { |error|deferrable_fail deferrable, *args }) do deferrable_succeed deferrable, &success_block end else change_state STATE.Leaving ( Ably::Models::PresenceMessage::ACTION.Leave, deferrable: deferrable, target_state: STATE.Left, client_id: client_id, data: data, failed_state: STATE.Failed, &success_block ) end end end |
#leave_client(client_id, options = {}) {|Ably::Realtime::Presence| ... } ⇒ Ably::Util::SafeDeferrable
Leave a given client_id from this channel. This client will be removed from the presence set and presence subscribers will see a leave message for this client.
180 181 182 183 184 185 186 |
# File 'lib/ably/realtime/presence.rb', line 180 def leave_client(client_id, = {}, &success_block) raise ArgumentError, 'options must be a Hash' unless .kind_of?(Hash) ensure_supported_client_id client_id ensure_supported_payload [:data] if .has_key?(:data) send_presence_action_for_client(Ably::Models::PresenceMessage::ACTION.Leave, client_id, , &success_block) end |
#logger ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Used by Modules::StateEmitter to debug action changes
332 333 334 |
# File 'lib/ably/realtime/presence.rb', line 332 def logger client.logger end |
#set_connection_id(new_connection_id) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Configure the connection ID for this presence channel. Typically configured only once when a user first enters a presence channel.
326 327 328 |
# File 'lib/ably/realtime/presence.rb', line 326 def set_connection_id(new_connection_id) @connection_id = new_connection_id end |
#subscribe(*actions) {|Ably::Models::PresenceMessage| ... } ⇒ void
This method returns an undefined value.
Subscribe to presence events on the associated Channel. This implicitly attaches the Channel if it is not already attached.
271 272 273 274 275 |
# File 'lib/ably/realtime/presence.rb', line 271 def subscribe(*actions, &callback) ensure_channel_attached do super end end |
#sync_complete? ⇒ Boolean
Returns true when the initial member SYNC following channel attach is completed
337 338 339 |
# File 'lib/ably/realtime/presence.rb', line 337 def sync_complete? members.sync_complete? end |
#unsubscribe(*actions, &callback) ⇒ void
This method returns an undefined value.
Unsubscribe the matching block for presence events on the associated Channel. If a block is not provided, all subscriptions will be unsubscribed
284 285 286 |
# File 'lib/ably/realtime/presence.rb', line 284 def unsubscribe(*actions, &callback) super end |
#update(options = {}) {|Ably::Realtime::Presence| ... } ⇒ Ably::Util::SafeDeferrable
Update the presence data for this client. If the client is not already a member of the presence set it will be added, and presence subscribers will see an enter or update message for this client.
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/ably/realtime/presence.rb', line 198 def update( = {}, &success_block) data = .fetch(:data, nil) deferrable = create_deferrable ensure_supported_client_id client_id ensure_supported_payload data unless data.nil? @data = data ensure_presence_publishable_on_connection ensure_channel_attached(deferrable) do ( Ably::Models::PresenceMessage::ACTION.Update, deferrable: deferrable, target_state: STATE.Entered, client_id: client_id, data: data, &success_block ) end end |
#update_client(client_id, options = {}) {|Ably::Realtime::Presence| ... } ⇒ Ably::Util::SafeDeferrable
Update the presence data for a specified client_id into this channel. If the client is not already a member of the presence set it will be added, and presence subscribers will see an enter or update message for this client. As with #enter_client, the connection must be authenticated in a way that enables it to represent an arbitrary clientId.
232 233 234 235 236 237 238 |
# File 'lib/ably/realtime/presence.rb', line 232 def update_client(client_id, = {}, &success_block) raise ArgumentError, 'options must be a Hash' unless .kind_of?(Hash) ensure_supported_client_id client_id ensure_supported_payload [:data] if .has_key?(:data) send_presence_action_for_client(Ably::Models::PresenceMessage::ACTION.Update, client_id, , &success_block) end |