Class: Vines::Router

Inherits:
Object
  • Object
show all
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

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.bare
    @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.bare] || EMPTY
  local = local.select {|stream| stream.user.jid == jid } unless jid.bare?
  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.bare
    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

#sizeObject

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