Class: GamespyQuery::SocketMaster
- Inherits:
-
Base
- Object
- Base
- GamespyQuery::SocketMaster
- Defined in:
- lib/gamespy_query/socket_master.rb
Overview
Provides mass processing of Gamespy UDP sockets, by using Socket/IO select
Constant Summary
- FILL_UP_ON_SPACE =
Should the current queue be extended to the maximum amount of connections, or should the queue be emptied first, before adding more?
true- DEFAULT_MAX_CONNECTIONS =
Default maximum concurrent connections
128
Constants included from Funcs
Funcs::RX_F, Funcs::RX_I, Funcs::RX_S
Instance Attribute Summary (collapse)
-
- (Object) max_connections
Configurable max concurrenct connections.
-
- (Object) timeout
Configurable timeout in seconds.
Class Method Summary (collapse)
-
+ (Object) process_master(game = "arma2oapc", geo = nil, remote = nil)
Fetch the gamespy master browser list Connect to each individual server to receive player data etc.
Instance Method Summary (collapse)
-
- (SocketMaster) initialize(addrs)
constructor
Initializes the object.
-
- (Object) process!
Process the list of addresses.
Methods included from Funcs
#clean, #encode_string, #handle_chr, #strip_tags
Constructor Details
- (SocketMaster) initialize(addrs)
Initializes the object
19 20 21 22 23 |
# File 'lib/gamespy_query/socket_master.rb', line 19 def initialize addrs @addrs = addrs @timeout, @max_connections = Socket::DEFAULT_TIMEOUT, DEFAULT_MAX_CONNECTIONS # Per select iteration end |
Instance Attribute Details
- (Object) max_connections
Configurable max concurrenct connections
15 16 17 |
# File 'lib/gamespy_query/socket_master.rb', line 15 def max_connections @max_connections end |
- (Object) timeout
Configurable timeout in seconds
12 13 14 |
# File 'lib/gamespy_query/socket_master.rb', line 12 def timeout @timeout end |
Class Method Details
+ (Object) process_master(game = "arma2oapc", geo = nil, remote = nil)
Fetch the gamespy master browser list Connect to each individual server to receive player data etc
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/gamespy_query/socket_master.rb', line 76 def process_master(game = "arma2oapc", geo = nil, remote = nil) master = GamespyQuery::Master.new(geo, game) list = if remote Net::HTTP.start(remote[0]) do |http| resp = http.get(remote[1]) resp.body.split("\n") end else master.get_server_list(nil, true, geo) end dat = master.process list sm = GamespyQuery::SocketMaster.new(dat.keys) sockets = sm.process! sockets.select{|s| s.valid? }.each do |s| begin data = dat[s.addr] data[:ip], data[:port] = s.addr.split(":") data[:gamename] = game data[:gamedata].merge!(s.sync(s.data)) rescue => e Tools.log_exception e end end dat.values end |
Instance Method Details
- (Object) process!
Process the list of addresses
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/gamespy_query/socket_master.rb', line 26 def process! sockets = [] until @addrs.empty? addrs = @addrs.shift @max_connections queue = addrs.map { |addr| Socket.new(addr) } sockets += queue until queue.empty? # Fill up the Sockets pool until max_conn if FILL_UP_ON_SPACE && queue.size < @max_connections addrs = @addrs.shift (@max_connections - queue.size) socks = addrs.map { |addr| Socket.new(addr) } queue += socks sockets += socks end write_sockets, read_sockets = queue.reject {|s| s.valid? }.partition {|s| s.handle_state } unless ready = IO.select(read_sockets, write_sockets, nil, @timeout) Tools.logger.warn "Timeout, no usable sockets in current queue, within timeout period (#{@timeout}s)" queue.each{|s| s.close unless s.closed?} queue = [] next end Tools.debug {"Sockets: #{queue.size}, AddrsLeft: #{@addrs.size}, ReadReady: #{"#{ready[0].size} / #{read_sockets.size}, WriteReady: #{ready[1].size} / #{write_sockets.size}, ExcReady: #{ready[2].size} / #{queue.size}" unless ready.nil?}"} # Read ready[0].each { |s| queue.delete(s) unless s.handle_read() } # Write ready[1].each { |s| queue.delete(s) unless s.handle_write() } # Exceptions #ready[2].each { |s| queue.delete(s) unless s.handle_exc } end end return sockets end |