Module: Fix::Engine::ServerConnection

Includes:
Connection
Defined in:
lib/fix/engine/server_connection.rb

Overview

The server connection wrapper, used when accepting a connection

Constant Summary collapse

LOGON_TIMEOUT =

Timespan during which a client must send a logon message after connecting

10

Constants included from Connection

Connection::TEST_REQ_GRACE_TIME

Instance Attribute Summary

Attributes included from Connection

#comp_id, #hrtbt_int, #ip, #last_request_at, #msg_buf, #port, #target_comp_id

Instance Method Summary collapse

Methods included from Connection

#keep_alive, #kill!, #peer_error, #process_msg, #receive_data, #send_heartbeat, #send_msg, #send_test_request, #set_heartbeat_interval

Methods included from Logger

#log, log, logger

Instance Method Details

#clientObject

Returns the currently connected client



47
48
49
# File 'lib/fix/engine/server_connection.rb', line 47

def client
  Client.get(ip, port, self)
end

#logon_timeoutObject

Logs the client out should he fail to authenticate before LOGON_TIMEOUT seconds



36
37
38
39
40
41
42
# File 'lib/fix/engine/server_connection.rb', line 36

def logon_timeout
  unless @target_comp_id
  log("Client #{peer} failed to authenticate before timeout, closing connection")
  close_connection_after_writing
  client.delete
  end
end

#peerObject

The way we refer to our connection peer in various logs and messages



54
55
56
# File 'lib/fix/engine/server_connection.rb', line 54

def peer
  "<#{client.key}>"
end

#post_initObject

Run after a client has connected



22
23
24
25
26
27
28
29
30
31
# File 'lib/fix/engine/server_connection.rb', line 22

def post_init
  super

  @port, @ip  = Socket.unpack_sockaddr_in(get_peername)
  @client     = Client.get(ip, port, self)

  log("Client connected #{peer}, expecting logon message in the next #{LOGON_TIMEOUT}s")

  EM.add_timer(LOGON_TIMEOUT) { logon_timeout }
end

#run_message_handler(msg) ⇒ Object

We override FE::Connection#run_message_handlers to add some session-related logic



69
70
71
72
73
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/fix/engine/server_connection.rb', line 69

def run_message_handler(msg)
  if !@target_comp_id && msg.is_a?(FP::Messages::Logon)
    log("Peer authenticated as <#{msg.username}> with heartbeat interval of <#{msg.heart_bt_int}s> and message sequence number start <#{msg.msg_seq_num}>")
    client.username = msg.username
    @target_comp_id = msg.sender_comp_id
    set_heartbeat_interval(msg.heart_bt_int)

    logon                     = FP::Messages::Logon.new
    logon.username            = msg.username
    logon.target_comp_id      = msg.sender_comp_id
    logon.sender_comp_id      = msg.target_comp_id 
    logon.reset_seq_num_flag  = true

    send_msg(logon)

  elsif @target_comp_id && msg.is_a?(FP::Messages::Logon)
    log("Received second logon message, reset_seq_num_flag <#{msg.reset_seq_num_flag}>")
    if msg.reset_seq_num_flag = 'Y'
      @send_seq_num = 1
      @messages = []
    end

  elsif !@target_comp_id
    peer_error("The session must be started with a logon message", msg.msg_seq_num, target_comp_id: msg.sender_comp_id)

  else
    super(msg)

  end
end

#unbindObject

Deletes the FE::Client instance after the connection is terminated



61
62
63
64
# File 'lib/fix/engine/server_connection.rb', line 61

def unbind
  super
  client.delete
end