Class: Slanger::PresenceChannel

Inherits:
Channel
  • Object
show all
Defined in:
lib/slanger/presence_channel.rb

Constant Summary

Constants inherited from Channel

Channel::CHANNEL_SUBSCRIBER_COUNT_KEY, Channel::CHANNEL_VACATED_DICT

Instance Attribute Summary

Attributes inherited from Channel

#channel_id

Instance Method Summary collapse

Methods inherited from Channel

all, #authenticated?, #channel, create, from, lookup, send_client_message, #send_client_message, unsubscribe

Constructor Details

#initialize(attrs) ⇒ PresenceChannel

Returns a new instance of PresenceChannel.



28
29
30
31
32
# File 'lib/slanger/presence_channel.rb', line 28

def initialize(attrs)
  super
  # Also subscribe the slanger daemon to a Redis channel used for events concerning subscriptions.
  Slanger::Redis.subscribe "slanger:connection_notification"
end

Instance Method Details

#dispatch(message, channel) ⇒ Object

Send an event received from Redis to the EventMachine channel



18
19
20
21
22
23
24
25
26
# File 'lib/slanger/presence_channel.rb', line 18

def dispatch(message, channel)
  if channel =~ /\Aslanger:/
    # Messages received from the Redis channel slanger:*  carry info on
    # subscriptions. Update our subscribers accordingly.
    update_subscribers message
  else
    push Oj.dump(message, mode: :compat)
  end
end

#idsObject



59
60
61
# File 'lib/slanger/presence_channel.rb', line 59

def ids
  subscriptions.map { |_, v| v["user_id"] }
end

#subscribe(msg, callback, &blk) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/slanger/presence_channel.rb', line 34

def subscribe(msg, callback, &blk)
  channel_data = Oj.strict_load msg["data"]["channel_data"]
  public_subscription_id = SecureRandom.uuid

  # Send event about the new subscription to the Redis slanger:connection_notification Channel.
  publisher = publish_connection_notification subscription_id: public_subscription_id, online: true,
                                              channel_data: channel_data, channel: channel_id

  # Associate the subscription data to the public id in Redis.
  roster_add public_subscription_id, channel_data

  # fuuuuuuuuuccccccck!
  publisher.callback do
    EM.next_tick do
      # The Subscription event has been sent to Redis successfully.
      # Call the provided callback.
      callback.call
      # Add the subscription to our table.
      internal_subscription_table[public_subscription_id] = channel.subscribe &blk
    end
  end

  public_subscription_id
end

#subscribersObject



63
64
65
# File 'lib/slanger/presence_channel.rb', line 63

def subscribers
  Hash[subscriptions.map { |_, v| [v["user_id"], v["user_info"]] }]
end

#unsubscribe(public_subscription_id) ⇒ Object



67
68
69
70
71
72
73
74
# File 'lib/slanger/presence_channel.rb', line 67

def unsubscribe(public_subscription_id)
  # Unsubscribe from EM::Channel
  channel.unsubscribe(internal_subscription_table.delete(public_subscription_id)) # if internal_subscription_table[public_subscription_id]
  # Remove subscription data from Redis
  roster_remove public_subscription_id
  # Notify all instances
  publish_connection_notification subscription_id: public_subscription_id, online: false, channel: channel_id
end