class TacviewClient::Client

The actual client to be instantiated to connect to a Tacview Server

Constants

HANDSHAKE_TERMINATOR

A null terminator used by Tacview to terminate handshake packages

PASSWORD_HASHER

Passwords sent between Tacview clients and servers are hashed using this algorithm

STREAM_PROTOCOL

The underlying stream protocol used by Tacview. Needs to be in-sync between the client and the server.

TACVIEW_PROTOCOL

The application level protocol used by Tacview. Needs to be in-sync between the client and the server.

Public Class Methods

new(host:, port: 42_674, password: nil, processor:, client_name: 'ruby_tacview_client') click to toggle source

Returns a new instance of a Client

This is the entry point into the gem. Instantiate an instance of this class to setup the prerequisite data for a connection to a Tacview server. Once done call {#connect} to start processing the Tacview ACMI stream.

@param host [String] Server hostname or IP @param port [Integer] Server port @param password [String] Plaintext password required to connect to a

password protected Tacview server. Is hashed before transmission.

@param client_name [String] Client name to send to the server @param processor [BaseProcessor] The object that processes the events

emitted by the {Reader}. Must implement the methods defined by the
{BaseProcessor} and can optionally inherit from it.
# File lib/tacview_client/client.rb, line 40
def initialize(host:,
               port: 42_674,
               password: nil,
               processor:,
               client_name: 'ruby_tacview_client')
  @host = host
  @port = port
  @password = password
  @processor = processor
  @client_name = client_name
end

Public Instance Methods

connect() click to toggle source

Connect to the Tacview server

Actually opens a TCP connection to the Tacview server and starts streaming ACMI lines to an instance of the {Reader} class.

This method will only return when the TCP connection has be killed either by a client-side signal or by the server closing the TCP connection.

# File lib/tacview_client/client.rb, line 60
def connect
  @connection = TCPSocket.open(@host, @port)

  read_handshake

  send_handshake

  start_reader
end

Private Instance Methods

abort_connection() click to toggle source
# File lib/tacview_client/client.rb, line 97
def abort_connection
  @connection.close
  exit(1)
end
hash_password() click to toggle source
# File lib/tacview_client/client.rb, line 111
def hash_password
  return 0 unless @password

  PASSWORD_HASHER.crc(@password)
end
read_handshake() click to toggle source

See www.tacview.net/documentation/realtime/en/ for information on connection negotiation

# File lib/tacview_client/client.rb, line 74
def read_handshake
  stream_protocol = read_handshake_header :stream_protocol
  validate_handshake_header STREAM_PROTOCOL, stream_protocol

  tacview_protocol = read_handshake_header :tacview_protocol
  validate_handshake_header TACVIEW_PROTOCOL, tacview_protocol

  read_handshake_header :host

  @connection.gets HANDSHAKE_TERMINATOR
end
read_handshake_header(_header) click to toggle source

Header parameter included for logging purposes

# File lib/tacview_client/client.rb, line 87
def read_handshake_header(_header)
  @connection.gets.chomp
end
send_handshake() click to toggle source
# File lib/tacview_client/client.rb, line 102
def send_handshake
  @connection.print [
    STREAM_PROTOCOL,
    TACVIEW_PROTOCOL,
    @client_name,
    hash_password
  ].join("\n") + HANDSHAKE_TERMINATOR
end
start_reader() click to toggle source
# File lib/tacview_client/client.rb, line 117
def start_reader
  reader = Reader.new(input_source: @connection,
                      processor: @processor)
  reader.start_reading
end
validate_handshake_header(expected, actual) click to toggle source
# File lib/tacview_client/client.rb, line 91
def validate_handshake_header(expected, actual)
  return if expected == actual

  abort_connection
end