Class: Juggernaut::Client

Inherits:
Object
  • Object
show all
Includes:
Miscel
Defined in:
lib/juggernaut/client.rb

Defined Under Namespace

Classes: UnverifiedClient

Constant Summary collapse

@@clients =
[]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Miscel

#config_path, #log_path, #logger, #options, #options=, #pid_path

Constructor Details

#initialize(subscriber, request) ⇒ Client

Returns a new instance of Client.



86
87
88
89
90
91
# File 'lib/juggernaut/client.rb', line 86

def initialize(subscriber, request)
  @connections = []
  @id         = request[:client_id]
  self.authenticate(request)
  add_new_connection(subscriber)
end

Instance Attribute Details

#connectionsObject (readonly)

Returns the value of attribute connections.



16
17
18
# File 'lib/juggernaut/client.rb', line 16

def connections
  @connections
end

#idObject (readonly)

Returns the value of attribute id.



15
16
17
# File 'lib/juggernaut/client.rb', line 15

def id
  @id
end

Class Method Details

.add_client(client) ⇒ Object



32
33
34
# File 'lib/juggernaut/client.rb', line 32

def add_client(client)
  @@clients << client unless @@clients.include?(client)
end

.find(&block) ⇒ Object



42
43
44
# File 'lib/juggernaut/client.rb', line 42

def find(&block)
  @@clients.select(&block).uniq
end

.find_allObject

Client find methods



38
39
40
# File 'lib/juggernaut/client.rb', line 38

def find_all
  @@clients
end

.find_by_channels(channels) ⇒ Object



57
58
59
60
61
# File 'lib/juggernaut/client.rb', line 57

def find_by_channels(channels)
  find {|client| 
    client.has_channels?(channels)
  }
end

.find_by_id(id) ⇒ Object



46
47
48
# File 'lib/juggernaut/client.rb', line 46

def find_by_id(id)
  find {|client| client.id == id }.first
end

.find_by_id_and_channels(id, channels) ⇒ Object



63
64
65
66
67
# File 'lib/juggernaut/client.rb', line 63

def find_by_id_and_channels(id, channels)
  find {|client| 
    client.has_channels?(channels) && client.id == id
  }.first
end

.find_by_signature(signature) ⇒ Object



50
51
52
53
54
55
# File 'lib/juggernaut/client.rb', line 50

def find_by_signature(signature)
  # signature should be unique
  find {|client| 
    client.connections.select {|connection| connection.signature == signature }.any?
  }.first
end

.find_or_create(subscriber, request) ⇒ Object

Actually does a find_or_create_by_id



21
22
23
24
25
26
27
28
29
# File 'lib/juggernaut/client.rb', line 21

def find_or_create(subscriber, request)
  if client = find_by_id(request[:client_id])
    client.add_new_connection(subscriber)
    client.authenticate(request)
    client
  else
    self.new(subscriber, request)
  end
end

.send_logouts_after_timeoutObject



69
70
71
72
73
74
75
76
# File 'lib/juggernaut/client.rb', line 69

def send_logouts_after_timeout
  @@clients.each do |client|
    if !client.alive? and client.give_up?
      client.logout_request
      @@clients.delete(client)
    end
  end
end

.send_logouts_to_all_clientsObject

Called when the server is shutting down



79
80
81
82
83
# File 'lib/juggernaut/client.rb', line 79

def send_logouts_to_all_clients
  @@clients.each do |client|
    client.logout_request
  end
end

Instance Method Details

#add_new_connection(subscriber) ⇒ Object



107
108
109
# File 'lib/juggernaut/client.rb', line 107

def add_new_connection(subscriber)
  @connections << subscriber
end

#alive?Boolean

Returns:

  • (Boolean)


145
146
147
# File 'lib/juggernaut/client.rb', line 145

def alive?
  @connections.select{|em| em.alive? }.any?
end

#authenticate(request) ⇒ Object

Raises:



93
94
95
96
97
98
99
# File 'lib/juggernaut/client.rb', line 93

def authenticate(request)
  time = request[:time]
  nonce = request[:nonce]
  hmac = Base64.decode64(CGI.unescape(request[:hash]))
  calculated_hmac = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, @id, "#{options[:client_secret_key]}:#{time}:#{nonce}:#{@id}")
  raise UnverifiedClient unless hmac == calculated_hmac
end

#give_up?Boolean

Returns:

  • (Boolean)


149
150
151
152
153
# File 'lib/juggernaut/client.rb', line 149

def give_up?
  @connections.select {|em| 
    em.logout_timeout and Time.now > em.logout_timeout 
  }.any?
end

#has_channels?(channels) ⇒ Boolean

Returns:

  • (Boolean)


132
133
134
135
136
137
# File 'lib/juggernaut/client.rb', line 132

def has_channels?(channels)
  @connections.each do |em|
    return true if em.has_channels?(channels)
  end
  false
end

#logout_connection_request(channels) ⇒ Object



116
117
118
119
# File 'lib/juggernaut/client.rb', line 116

def logout_connection_request(channels)
  return true unless options[:logout_connection_url]
  post_request(options[:logout_connection_url], channels)
end

#logout_requestObject



121
122
123
124
# File 'lib/juggernaut/client.rb', line 121

def logout_request
  return true unless options[:logout_url]
  post_request(options[:logout_url])
end

#remove_channels!(channels) ⇒ Object



139
140
141
142
143
# File 'lib/juggernaut/client.rb', line 139

def remove_channels!(channels)
  @connections.each do |em|
    em.remove_channels!(channels)
  end
end

#send_message(msg, channels = nil) ⇒ Object



126
127
128
129
130
# File 'lib/juggernaut/client.rb', line 126

def send_message(msg, channels = nil)
  @connections.each do |em|
    em.broadcast(msg) if !channels or channels.empty? or em.has_channels?(channels)
  end
end

#subscription_request(channels) ⇒ Object



111
112
113
114
# File 'lib/juggernaut/client.rb', line 111

def subscription_request(channels)
  return true unless options[:subscription_url]
  post_request(options[:subscription_url], channels)
end

#to_jsonObject



101
102
103
104
105
# File 'lib/juggernaut/client.rb', line 101

def to_json
  {
    :client_id  => @id, 
  }.to_json
end