Class: Frostbitten::Connection

Inherits:
Object
  • Object
show all
Defined in:
lib/frostbitten/connection.rb

Constant Summary collapse

DEFAULTS =
{
  # connect/read/write timeout for socket operations
  :socket_timeout => 0.5,
  
  :keepalive => true
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(uri, options = {}) ⇒ Connection

Initialize class with URI ‘fbrcon://password@ip:port’ Also accept options { :keepalive = true/false, :socket_timeout => 1 }



26
27
28
29
30
31
32
33
34
35
36
# File 'lib/frostbitten/connection.rb', line 26

def initialize(uri, options={})
  server_parsed = URI.parse(uri)
  self.hostname = server_parsed.host
  self.password = server_parsed.user
  self.port = server_parsed.port ||= 47200

  @sock = nil 
  @sequence = options[:sequence] ||= 0

  @options = DEFAULTS.merge(options)
end

Instance Attribute Details

#hostnameObject

Returns the value of attribute hostname.



19
20
21
# File 'lib/frostbitten/connection.rb', line 19

def hostname
  @hostname
end

#passwordObject

Returns the value of attribute password.



19
20
21
# File 'lib/frostbitten/connection.rb', line 19

def password
  @password
end

#portObject

Returns the value of attribute port.



19
20
21
# File 'lib/frostbitten/connection.rb', line 19

def port
  @port
end

#sequenceObject (readonly)

Returns the value of attribute sequence.



20
21
22
# File 'lib/frostbitten/connection.rb', line 20

def sequence
  @sequence
end

#sockObject (readonly)

Returns the value of attribute sock.



20
21
22
# File 'lib/frostbitten/connection.rb', line 20

def sock
  @sock
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



20
21
22
# File 'lib/frostbitten/connection.rb', line 20

def timeout
  @timeout
end

Instance Method Details

#alive?Boolean

Returns if the socket is alive of closed

Returns:

  • (Boolean)


39
40
41
42
# File 'lib/frostbitten/connection.rb', line 39

def alive?
  return true if @sock
  return false
end

#closeObject

Close socket



62
63
64
65
66
# File 'lib/frostbitten/connection.rb', line 62

def close
  return unless alive?
  @sock.close
  @sock = nil
end

#connectObject

Connects socket



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/frostbitten/connection.rb', line 45

def connect
  return if alive?
  @sock = TCPSocket.open(self.hostname, self.port);
  if @options[:socket_timeout]
          secs = Integer(@options[:socket_timeout])
          usecs = Integer((@options[:socket_timeout] - secs) * 1_000_000)
          optval = [secs, usecs].pack("l_2")
          @sock.setsockopt Socket::SOL_SOCKET, Socket::SO_RCVTIMEO, optval
          @sock.setsockopt Socket::SOL_SOCKET, Socket::SO_SNDTIMEO, optval
        end

        if @options[:keepalive]
          @sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
        end
end

#send(message) ⇒ Object

Accepts a Frostbitten::Mesage and sends it over socket updates message.header.sequence with a incremented version of server sequence counter. can raise NameError, ArgumentError or StandardError based on return data from server.



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/frostbitten/connection.rb', line 74

def send(message) 
  connect unless self.alive?
  unless message.header.is_response?
    @sequence += 1
  end

  message.header.sequence = self.sequence
  message.write @sock

  m = Message.new()
  m.read @sock

  unless m.words.first == "OK"
    m.words.first.tap do |word|
      if word == "UnknownCommand"
        raise NameError, "UnknownCommand raised by server"
      elsif word == "InvalidArguments"
        raise ArgumentError, "InvalidArguments raised by server"
      else
        raise StandardError, "Server returned #{word}"
      end
     end
  end
  return m
end