lib/vines/router.rb in vines-0.1.0 vs lib/vines/router.rb in vines-0.1.1
- old
+ new
@@ -6,71 +6,71 @@
# the 'to' attribute. Router is a singleton, shared by all streams, that must
# be accessed with +Router.instance+, not +Router.new+.
class Router
ROUTABLE_STANZAS = %w[message iq presence].freeze
+ STREAM_TYPES = [:client, :server, :component].freeze
+ STREAM_TYPES.each do |name|
+ define_method "#{name}s" do
+ @streams[name]
+ end
+ end
+
@@instance = nil
def self.instance
- @@instance ||= Router.new
+ @@instance ||= self.new
end
def initialize
@config = nil
@streams = Hash.new {|h,k| h[k] = [] }
@pending = Hash.new {|h,k| h[k] = [] }
end
- %w[Client Server Component].each do |klass|
- name = klass.split(/(?=[A-Z])/).join('_').downcase
- define_method(name + 's') do
- @streams["Vines::Stream::#{klass}"]
- end
- end
-
- def http_states
- @streams["Vines::Stream::Http::HttpState"]
- end
-
# Returns streams for all connected resources for this JID. A
# resource is considered connected after it has completed authentication
# and resource binding.
def connected_resources(jid)
jid = JID.new(jid)
- (clients + http_states).select do |stream|
+ clients.select do |stream|
stream.connected? && jid == (jid.bare? ? stream.user.jid.bare : stream.user.jid)
end
end
# Returns streams for all available resources for this JID. A
# resource is marked available after it sends initial presence.
# This method accepts a single JID or a list of JIDs.
def available_resources(*jid)
ids = jid.flatten.map {|jid| JID.new(jid).bare }
- (clients + http_states).select do |stream|
+ clients.select do |stream|
stream.available? && ids.include?(stream.user.jid.bare)
end
end
# Returns streams for all interested resources for this JID. A
# resource is marked interested after it requests the roster.
# This method accepts a single JID or a list of JIDs.
def interested_resources(*jid)
ids = jid.flatten.map {|jid| JID.new(jid).bare }
- (clients + http_states).select do |stream|
+ clients.select do |stream|
stream.interested? && ids.include?(stream.user.jid.bare)
end
end
- # Add the connection to the routing table.
+ # Add the connection to the routing table. The connection must return
+ # :client, :server, or :component from its +stream_type+ method so the
+ # router can properly route stanzas to the stream.
def <<(connection)
+ type = stream_type(connection)
@config ||= connection.config
- @streams[connection.class.to_s] << connection
+ @streams[type] << connection
end
# Remove the connection from the routing table.
def delete(connection)
- @streams[connection.class.to_s].delete(connection)
+ type = stream_type(connection)
+ @streams[type].delete(connection)
end
# Send the stanza to the appropriate remote server-to-server stream
# or an external component stream.
def route(stanza)
@@ -117,9 +117,17 @@
private
def connection_to(domain)
(components + servers).find do |stream|
stream.ready? && stream.remote_domain == domain
+ end
+ end
+
+ def stream_type(connection)
+ connection.stream_type.tap do |type|
+ unless STREAM_TYPES.include?(type)
+ raise ArgumentError, "unexpected stream type: #{type}"
+ end
end
end
end
end