Class: Cosmos::TcpipServerInterface
- Inherits:
-
StreamInterface
- Object
- Interface
- StreamInterface
- Cosmos::TcpipServerInterface
- Defined in:
- lib/cosmos/interfaces/tcpip_server_interface.rb
Overview
TCP/IP Server which can both read and write on a single port or two independent ports. A listen thread is setup which waits for client connections. For each connection to the read port, a thread is spawned that calls the read method from the interface. This data is then available by calling the TcpipServer read method. For each connection to the write port, a thread is spawned that calls the write method from the interface when data is send to the TcpipServer via the write method.
Direct Known Subclasses
Defined Under Namespace
Classes: InterfaceInfo
Constant Summary
Constants included from ApiShared
ApiShared::DEFAULT_TLM_POLLING_RATE
Constants included from Extract
Extract::SCANNING_REGULAR_EXPRESSION
Instance Attribute Summary collapse
-
#auto_system_meta ⇒ boolean
Automatically send SYSTEM META on connect - Default false - Can be CMD/TLM.
-
#listen_address ⇒ String
The ip address to bind to.
-
#raw_logger_pair ⇒ RawLoggerPair
RawLoggerPair instance or nil.
-
#read_connection_callback ⇒ Object
Callback method to call when a new client connects to the read port.
-
#write_connection_callback ⇒ Object
Callback method to call when a new client connects to the write port.
Attributes inherited from StreamInterface
Attributes inherited from Interface
#auto_reconnect, #bytes_read, #bytes_written, #cmd_routers, #connect_on_startup, #disable_disconnect, #interfaces, #name, #options, #override_tlm, #packet_log_writer_pairs, #protocol_info, #read_count, #read_protocols, #read_raw_data, #read_raw_data_time, #reconnect_delay, #routers, #stored_packet_log_writer_pairs, #target_names, #thread, #write_count, #write_protocols, #written_raw_data, #written_raw_data_time
Instance Method Summary collapse
-
#connect ⇒ Object
Create the read and write port listen threads.
-
#connected? ⇒ Boolean
Whether the server is listening for connections.
-
#disconnect ⇒ Object
Shutdowns the listener threads for both the read and write ports as well as any client connections.
-
#graceful_kill ⇒ Object
Gracefully kill all the threads.
-
#initialize(write_port, read_port, write_timeout, read_timeout, protocol_type = nil, *protocol_args) ⇒ TcpipServerInterface
constructor
A new instance of TcpipServerInterface.
-
#num_clients ⇒ Integer
The number of connected clients.
-
#read ⇒ Packet
Latest packet read from any of the connected clients.
-
#read_queue_size ⇒ Integer
The number of packets waiting on the read queue.
-
#set_option(option_name, option_values) ⇒ Object
Supported Options LISTEN_ADDRESS - Ip address of the interface to accept connections on - Default: 0.0.0.0 AUTO_SYSTEM_META - Automatically send SYSTEM META on connect - Default false (see Interface#set_option).
-
#start_raw_logging ⇒ Object
Start raw logging for this interface.
-
#stop_raw_logging ⇒ Object
Stop raw logging for this interface.
- #write(packet) ⇒ Object
-
#write_queue_size ⇒ Integer
The number of packets waiting on the write queue.
- #write_raw(data) ⇒ Object
Methods inherited from StreamInterface
#read_interface, #write_interface
Methods inherited from Interface
#_normalize_tlm, #_override, #_override_tlm, #_override_tlm_raw, #_write, #add_protocol, #convert_data_to_packet, #convert_packet_to_data, #copy_to, #read_allowed?, #read_interface, #read_interface_base, #write_allowed?, #write_interface, #write_interface_base, #write_raw_allowed?
Methods included from Api
#cmd, #cmd_no_checks, #cmd_no_hazardous_check, #cmd_no_range_check, #cmd_raw, #cmd_raw_no_checks, #cmd_raw_no_hazardous_check, #cmd_raw_no_range_check, #cmd_tlm_clear_counters, #cmd_tlm_reload, #connect_interface, #connect_router, #disable_limits, #disable_limits_group, #disconnect_interface, #disconnect_router, #enable_limits, #enable_limits_group, #get_all_cmd_info, #get_all_interface_info, #get_all_packet_logger_info, #get_all_router_info, #get_all_target_info, #get_all_tlm_info, #get_background_tasks, #get_cmd_buffer, #get_cmd_cnt, #get_cmd_hazardous, #get_cmd_list, #get_cmd_log_filename, #get_cmd_param_list, #get_cmd_time, #get_cmd_value, #get_interface_info, #get_interface_names, #get_interface_targets, #get_limits, #get_limits_event, #get_limits_groups, #get_limits_set, #get_limits_sets, #get_out_of_limits, #get_output_logs_filenames, #get_overall_limits_state, #get_packet, #get_packet_data, #get_packet_logger_info, #get_packet_loggers, #get_router_info, #get_router_names, #get_saved_config, #get_screen_definition, #get_screen_list, #get_server_message, #get_server_message_log_filename, #get_server_status, #get_stale, #get_target_ignored_items, #get_target_ignored_parameters, #get_target_info, #get_target_list, #get_tlm_buffer, #get_tlm_cnt, #get_tlm_details, #get_tlm_item_list, #get_tlm_list, #get_tlm_log_filename, #get_tlm_packet, #get_tlm_values, #inject_tlm, #interface_state, #limits_enabled?, #map_target_to_interface, #normalize_tlm, #override_tlm, #override_tlm_raw, #replay_move_end, #replay_move_index, #replay_move_start, #replay_play, #replay_reverse_play, #replay_select_file, #replay_set_playback_delay, #replay_status, #replay_step_back, #replay_step_forward, #replay_stop, #router_state, #send_raw, #set_limits, #set_limits_set, #set_tlm, #set_tlm_raw, #start_background_task, #start_cmd_log, #start_logging, #start_new_server_message_log, #start_raw_logging_interface, #start_raw_logging_router, #start_tlm_log, #stop_background_task, #stop_cmd_log, #stop_logging, #stop_raw_logging_interface, #stop_raw_logging_router, #stop_tlm_log, #subscribe_limits_events, #subscribe_packet_data, #subscribe_server_messages, #tlm, #tlm_formatted, #tlm_raw, #tlm_variable, #tlm_with_units, #unsubscribe_limits_events, #unsubscribe_packet_data, #unsubscribe_server_messages
Constructor Details
#initialize(write_port, read_port, write_timeout, read_timeout, protocol_type = nil, *protocol_args) ⇒ TcpipServerInterface
Returns a new instance of TcpipServerInterface.
64 65 66 67 68 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 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 64 def initialize(write_port, read_port, write_timeout, read_timeout, protocol_type = nil, *protocol_args) super(protocol_type, protocol_args) @write_port = ConfigParser.handle_nil(write_port) @write_port = Integer(write_port) if @write_port @read_port = ConfigParser.handle_nil(read_port) @read_port = Integer(read_port) if @read_port @write_timeout = ConfigParser.handle_nil(write_timeout) @write_timeout = @write_timeout.to_f if @write_timeout @read_timeout = ConfigParser.handle_nil(read_timeout) @read_timeout = @read_timeout.to_f if @read_timeout @listen_sockets = [] @listen_pipes = [] @listen_threads = [] @read_threads = [] @write_thread = nil @write_raw_thread = nil @write_interface_infos = [] @read_interface_infos = [] @write_queue = nil @write_queue = Queue.new if @write_port @write_raw_queue = nil @write_raw_queue = Queue.new if @write_port @read_queue = nil @read_queue = Queue.new if @read_port @write_condition_variable = nil @write_condition_variable = ConditionVariable.new if @write_port @write_raw_mutex = nil @write_raw_mutex = Mutex.new if @write_port @write_raw_condition_variable = nil @write_raw_condition_variable = ConditionVariable.new if @write_port @write_connection_callback = nil @read_connection_callback = nil @raw_logger_pair = nil @raw_logging_enabled = false @connection_mutex = Mutex.new @listen_address = "0.0.0.0" @auto_system_meta = false @read_allowed = false unless ConfigParser.handle_nil(read_port) @write_allowed = false unless ConfigParser.handle_nil(write_port) @write_raw_allowed = false unless ConfigParser.handle_nil(write_port) @connected = false end |
Instance Attribute Details
#auto_system_meta ⇒ boolean
Returns Automatically send SYSTEM META on connect - Default false - Can be CMD/TLM.
50 51 52 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 50 def @auto_system_meta end |
#listen_address ⇒ String
Returns The ip address to bind to. Default to ANY (0.0.0.0).
48 49 50 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 48 def listen_address @listen_address end |
#raw_logger_pair ⇒ RawLoggerPair
Returns RawLoggerPair instance or nil.
46 47 48 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 46 def raw_logger_pair @raw_logger_pair end |
#read_connection_callback ⇒ Object
Callback method to call when a new client connects to the read port. This method will be called with the Interface as the only argument.
44 45 46 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 44 def read_connection_callback @read_connection_callback end |
#write_connection_callback ⇒ Object
Callback method to call when a new client connects to the write port. This method will be called with the Interface as the only argument.
41 42 43 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 41 def write_connection_callback @write_connection_callback end |
Instance Method Details
#connect ⇒ Object
Create the read and write port listen threads. Incoming connections will spawn separate threads to process the reads and writes.
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 116 def connect @cancel_threads = false @read_queue.clear if @read_queue if @write_port == @read_port # One socket start_listen_thread(@read_port, true, true) else start_listen_thread(@write_port, true, false) if @write_port start_listen_thread(@read_port, false, true) if @read_port end if @write_port @write_thread = Thread.new do begin loop do write_thread_body() break if @cancel_threads end rescue Exception => err shutdown_interfaces(@write_interface_infos) Logger.instance.error("#{@name}: Tcpip server write thread unexpectedly died") Logger.instance.error(err.formatted) end end @write_raw_thread = Thread.new do begin loop do write_raw_thread_body() break if @cancel_threads end rescue Exception => err shutdown_interfaces(@write_interface_infos) Logger.instance.error("#{@name}: Tcpip server write raw thread unexpectedly died") Logger.instance.error(err.formatted) end end else @write_thread = nil @write_raw_thread = nil end @connected = true end |
#connected? ⇒ Boolean
Returns Whether the server is listening for connections.
159 160 161 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 159 def connected? @connected end |
#disconnect ⇒ Object
Shutdowns the listener threads for both the read and write ports as well as any client connections.
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 165 def disconnect @cancel_threads = true @read_queue << nil if @read_queue @listen_pipes.each do |pipe| begin pipe.write('.') rescue Exception # Oh well end end @listen_pipes.clear # Shutdown listen thread(s) @listen_threads.each { |listen_thread| Cosmos.kill_thread(self, listen_thread) } @listen_threads.clear # Shutdown listen socket(s) @listen_sockets.each do |listen_socket| begin Cosmos.close_socket(listen_socket) rescue IOError # Ok may have been closed by the thread end end @listen_sockets.clear # This will unblock read threads shutdown_interfaces(@read_interface_infos) @read_threads.each { |thread| Cosmos.kill_thread(self, thread) } @read_threads.clear if @write_thread Cosmos.kill_thread(self, @write_thread) @write_thread = nil end if @write_raw_thread Cosmos.kill_thread(self, @write_raw_thread) @write_raw_thread = nil end shutdown_interfaces(@write_interface_infos) @connected = false end |
#graceful_kill ⇒ Object
Gracefully kill all the threads
210 211 212 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 210 def graceful_kill # This method is just here to prevent warnings end |
#num_clients ⇒ Integer
Returns The number of connected clients.
253 254 255 256 257 258 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 253 def num_clients interfaces = [] @write_interface_infos.each {|wii| interfaces << wii.interface} @read_interface_infos.each {|rii| interfaces << rii.interface} interfaces.uniq.length end |
#read ⇒ Packet
Returns Latest packet read from any of the connected clients. Note this method blocks until data is available.
216 217 218 219 220 221 222 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 216 def read raise "Interface not connected for read: #{@name}" unless connected? && read_allowed? packet = @read_queue.pop return nil unless packet @read_count += 1 packet end |
#read_queue_size ⇒ Integer
Returns The number of packets waiting on the read queue.
243 244 245 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 243 def read_queue_size @read_queue ? @read_queue.size : 0 end |
#set_option(option_name, option_values) ⇒ Object
Supported Options LISTEN_ADDRESS - Ip address of the interface to accept connections on - Default: 0.0.0.0 AUTO_SYSTEM_META - Automatically send SYSTEM META on connect - Default false (see Interface#set_option)
276 277 278 279 280 281 282 283 284 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 276 def set_option(option_name, option_values) super(option_name, option_values) case option_name.upcase when 'LISTEN_ADDRESS' @listen_address = option_values[0] when 'AUTO_SYSTEM_META' @auto_system_meta = ConfigParser.handle_true_false(option_values[0]) end end |
#start_raw_logging ⇒ Object
Start raw logging for this interface
261 262 263 264 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 261 def start_raw_logging @raw_logging_enabled = true change_raw_logging(:start) end |
#stop_raw_logging ⇒ Object
Stop raw logging for this interface
267 268 269 270 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 267 def stop_raw_logging @raw_logging_enabled = false change_raw_logging(:stop) end |
#write(packet) ⇒ Object
226 227 228 229 230 231 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 226 def write(packet) raise "Interface not connected for write: #{@name}" unless connected? && write_allowed? @write_count += 1 @write_queue << packet.clone @write_condition_variable.broadcast end |
#write_queue_size ⇒ Integer
Returns The number of packets waiting on the write queue.
248 249 250 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 248 def write_queue_size @write_queue ? @write_queue.size : 0 end |
#write_raw(data) ⇒ Object
235 236 237 238 239 240 |
# File 'lib/cosmos/interfaces/tcpip_server_interface.rb', line 235 def write_raw(data) raise "Interface not connected for write_raw: #{@name}" unless connected? && write_raw_allowed? @write_raw_queue << data @write_raw_condition_variable.broadcast return data end |