Class: Vines::Router
- Inherits:
-
Object
- Object
- Vines::Router
- Defined in:
- lib/vines/router.rb
Overview
The router tracks all stream connections to the server for all clients, servers, and components. It sends stanzas to the correct stream based on the ‘to’ attribute. Router is a singleton, shared by all streams, that must be accessed with Config#router.
Constant Summary collapse
- EMPTY =
[].freeze
- STREAM_TYPES =
[:client, :server, :component].freeze
Instance Method Summary collapse
-
#<<(stream) ⇒ Object
Add the connection to the routing table.
-
#available_resources(*jids, from) ⇒ Object
Returns streams for all available resources for this JID.
-
#connected_resources(jid, from, proxies = true) ⇒ Object
Returns streams for all connected resources for this JID.
-
#delete(stream) ⇒ Object
Remove the connection from the routing table.
-
#initialize(config) ⇒ Router
constructor
A new instance of Router.
-
#interested_resources(*jids, from) ⇒ Object
Returns streams for all interested resources for this JID.
-
#route(stanza) ⇒ Object
Send the stanza to the appropriate remote server-to-server stream or an external component stream.
-
#size ⇒ Object
Returns the total number of streams connected to the server.
Constructor Details
#initialize(config) ⇒ Router
Returns a new instance of Router.
13 14 15 16 17 |
# File 'lib/vines/router.rb', line 13 def initialize(config) @config = config @clients, @servers, @components = {}, [], [] @pending = Hash.new {|h,k| h[k] = [] } end |
Instance Method Details
#<<(stream) ⇒ Object
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.
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/vines/router.rb', line 51 def <<(stream) case stream_type(stream) when :client then return unless stream.connected? jid = stream.user.jid. @clients[jid] ||= [] @clients[jid] << stream when :server then @servers << stream when :component then @components << stream end end |
#available_resources(*jids, from) ⇒ Object
Returns streams for all available resources for this JID. A resource is marked available after it sends initial presence.
34 35 36 37 38 |
# File 'lib/vines/router.rb', line 34 def available_resources(*jids, from) clients(jids, from) do |stream| stream.available? end end |
#connected_resources(jid, from, proxies = true) ⇒ Object
Returns streams for all connected resources for this JID. A resource is considered connected after it has completed authentication and resource binding.
22 23 24 25 26 27 28 29 30 |
# File 'lib/vines/router.rb', line 22 def connected_resources(jid, from, proxies=true) jid, from = JID.new(jid), JID.new(from) return [] unless @config.allowed?(jid, from) local = @clients[jid.] || EMPTY local = local.select {|stream| stream.user.jid == jid } unless jid. remote = proxies ? proxies(jid) : EMPTY [local, remote].flatten end |
#delete(stream) ⇒ Object
Remove the connection from the routing table.
64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/vines/router.rb', line 64 def delete(stream) case stream_type(stream) when :client then return unless stream.connected? jid = stream.user.jid. streams = @clients[jid] || [] streams.delete(stream) @clients.delete(jid) if streams.empty? when :server then @servers.delete(stream) when :component then @components.delete(stream) end end |
#interested_resources(*jids, from) ⇒ Object
Returns streams for all interested resources for this JID. A resource is marked interested after it requests the roster.
42 43 44 45 46 |
# File 'lib/vines/router.rb', line 42 def interested_resources(*jids, from) clients(jids, from) do |stream| stream.interested? end end |
#route(stanza) ⇒ Object
Send the stanza to the appropriate remote server-to-server stream or an external component stream.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/vines/router.rb', line 79 def route(stanza) to, from = %w[to from].map {|attr| JID.new(stanza[attr]) } return unless @config.allowed?(to, from) key = [to.domain, from.domain] if stream = connection_to(to, from) stream.write(stanza) elsif @pending.key?(key) @pending[key] << stanza elsif @config.s2s?(to.domain) @pending[key] << stanza Vines::Stream::Server.start(@config, to.domain, from.domain) do |stream| stream ? send_pending(key, stream) : return_pending(key) @pending.delete(key) end else raise StanzaErrors::RemoteServerNotFound.new(stanza, 'cancel') end end |
#size ⇒ Object
Returns the total number of streams connected to the server.
100 101 102 103 |
# File 'lib/vines/router.rb', line 100 def size clients = @clients.values.inject(0) {|sum, arr| sum + arr.size } clients + @servers.size + @components.size end |