module TAC class TACNET class Client CHUNK_SIZE = 4096 attr_reader :uuid, :read_queue, :write_queue, :socket, :packets_sent, :packets_received, :data_sent, :data_received attr_accessor :sync_interval def initialize @uuid = SecureRandom.uuid @read_queue = [] @write_queue = [] @sync_interval = 100 @packets_sent, @packets_received = 0, 0 @data_sent, @data_received = 0, 0 end def socket=(socket) @socket = socket listen end def listen Thread.new do while connected? # Read from socket while message_in = read if message_in.empty? break else @read_queue << message_in @packets_received += 1 @data_received += message_in.length end end # Write to socket while message_out = @write_queue.shift write(message_out) @packets_sent += 1 @data_sent += message_out.length end sleep @sync_interval / 1000.0 end end end def sync(&block) block.call end def handle_read_queue message = gets while message puts(message) message = gets end end def connected? !closed? end def bound? @socket.bound? if @socket end def closed? @socket.closed? if @socket end def write(message) @socket.puts("#{message}\r\n\n") end def read message = "" begin data = @socket.readpartial(CHUNK_SIZE) message += message end until message.end_with?("\r\n\n") return message end def puts(message) @write_queue << message end def gets @read_queue.shift end def encode(message) return message end def decode(blob) return blob end def flush @socket.flush if socket end def close(reason = nil) write(reason) if reason @socket.close if @socket end end end end