Рефактор. Сетевой модуль.
This commit is contained in:
@@ -34,8 +34,8 @@ class Serial extends SerialPort:
|
||||
return Error.OK
|
||||
|
||||
|
||||
class Socket extends PacketPeerUDP:
|
||||
func send_to(addr, data):
|
||||
class SocketUDP extends PacketPeerUDP:
|
||||
func send_to(addr: Array, data: PackedByteArray):
|
||||
set_dest_address(addr[0], addr[1])
|
||||
var rc: = put_packet(data)
|
||||
if rc != Error.OK:
|
||||
@@ -45,7 +45,7 @@ class Socket extends PacketPeerUDP:
|
||||
class SocketTCP extends TCPServer:
|
||||
const RX_TIMEOUT: int = 1000 ## Время сброса счётчика принятия части пакета.
|
||||
var peerstream: = PacketPeerStream.new()
|
||||
var unit_key: StringName ## Ключ юнита.
|
||||
var unit_name: StringName ## Уникальное имя устройства
|
||||
var head_len: int = 8 ## Длина заголовка команды.
|
||||
var len_place: int = 4 ## Номер начального байта с длинной блока данных.
|
||||
var type_len: int = 4 ## Количество байт в размере длинны.
|
||||
@@ -55,52 +55,53 @@ class SocketTCP extends TCPServer:
|
||||
var rx_data: PackedByteArray ## Принятые данные.
|
||||
var data_len: int ## Размер ожидаемых данных.
|
||||
|
||||
func send_to(data):
|
||||
func send_to(data: PackedByteArray):
|
||||
var peer = peerstream.get_stream_peer()
|
||||
peer.put_data(data)
|
||||
|
||||
|
||||
var poll_sockets: Array[Socket]
|
||||
var tcp_sockets: Array[Array]
|
||||
var units: Dictionary[StringName, unit.Unit]
|
||||
var units_udp: Dictionary[StringName, unit.Unit]
|
||||
var units_udprx: Dictionary[StringName, unit.Unit]
|
||||
var units_tcp: Dictionary[StringName, unit.Unit]
|
||||
var units_serial: Dictionary[StringName, unit.Unit]
|
||||
var units_modbus: Dictionary[StringName, unit.Unit]
|
||||
var serials: Dictionary[StringName, Serial] # Последовательные порты
|
||||
var mbcs: Dictionary[StringName, unit.Unit] # Клиенты modbus
|
||||
var dst_ports: Dictionary[StringName, int]
|
||||
var dst_addrs: Dictionary[StringName, StringName]
|
||||
var unit_keys: Dictionary[int, StringName]
|
||||
var sock_unicast: Socket
|
||||
var sock_capsrpb: Socket
|
||||
var logger_page: Node
|
||||
var send_sockets: Dictionary[StringName, Socket] # Таблица <имяустройста>: <сокет> для отправки сообщений
|
||||
var addr_port_to_unit_name: Dictionary[StringName, StringName]
|
||||
var poll_sockets: Array[SocketUDP] ## Сокеты для непрерывного опроса наличия новых данных
|
||||
var tcp_sockets: Array[Array] ## Сокеты для TCP-соединений
|
||||
var units: Dictionary[StringName, unit.Unit] ## Экземпляры всех сетевых устройств
|
||||
var units_udp: Dictionary[StringName, unit.Unit] ## Экземпляры устройств с udp-соединением которым нужно передавать данные
|
||||
var units_udprx: Dictionary[StringName, unit.Unit] ## Экземпляры устройств с udp-соединением от которых приходят данные
|
||||
var units_tcp: Dictionary[StringName, unit.Unit] ## Экземпляры устройств с tcp-соединением
|
||||
var units_serial: Dictionary[StringName, unit.Unit] ## Экземпляры устройств с uart-соединением
|
||||
var units_modbus: Dictionary[StringName, unit.Unit] ## Экземпляры устройств с modbusserial-соединением
|
||||
var serials: Dictionary[StringName, Serial] ## Последовательные порты (uart)
|
||||
var dst_ports: Dictionary[StringName, int] ## Преобразование имя устройства в порт назначения
|
||||
var dst_addrs: Dictionary[StringName, StringName] ## Преобразование имя устройства в адрес назначения
|
||||
var unit_keys: Dictionary[int, StringName] ## Преобразование порта назначения в имя устройства
|
||||
var sock_unicast: SocketUDP ## Сокет для приёма широковещательных сообщений от ЯУ-07
|
||||
var sock_capsrpb: SocketUDP ## Сокет для приёма сообщений от КАСПРПБ
|
||||
var logger_page: Node ## Ссылка на журнал работы
|
||||
var send_sockets: Dictionary[StringName, SocketUDP] ## Таблица <имяустройста>: <сокет> для отправки сообщений
|
||||
var addr_port_to_unit_name: Dictionary[StringName, StringName] ## Преобразование адрес:порт в имя устройства
|
||||
|
||||
|
||||
func on_serial_data(data, unit): unit.parse(data, tick)
|
||||
|
||||
|
||||
func create_socket(nm) -> Socket:
|
||||
var addr = settings.UnitProfiles[nm][1]
|
||||
var port = settings.UnitProfiles[nm][2][0]
|
||||
var broad = settings.UnitProfiles[nm][3]
|
||||
var bind = settings.UnitProfiles[nm][4]
|
||||
var sock: = Socket.new()
|
||||
## [param unit_name] - Уникальное имя устройства[br]
|
||||
func create_socket_udp(unit_name: StringName) -> SocketUDP:
|
||||
var addr = settings.UnitProfiles[unit_name][1]
|
||||
var port = settings.UnitProfiles[unit_name][2][0]
|
||||
var broad = settings.UnitProfiles[unit_name][3]
|
||||
var bind = settings.UnitProfiles[unit_name][4]
|
||||
var sock: = SocketUDP.new()
|
||||
sock.set_broadcast_enabled(broad)
|
||||
var rc = Error.OK if not bind else sock.bind(port, addr)
|
||||
var errlevel = log.INFO if rc == Error.OK else log.ERROR
|
||||
log.message(errlevel, '\"%s\" привязан к %s:%d? - %s, результат: %s' % [nm, addr, port, ['нет', 'да'][int(bind)], error_string(rc)])
|
||||
log.message(errlevel, '\"%s\" привязан к %s:%d? - %s, результат: %s' % [unit_name, addr, port, ['нет', 'да'][int(bind)], error_string(rc)])
|
||||
return sock
|
||||
|
||||
|
||||
func create_tcpsocket(unit_name: StringName) -> SocketTCP:
|
||||
## [param unit_name] - Уникальное имя устройства[br]
|
||||
func create_socket_tcp(unit_name: StringName) -> SocketTCP:
|
||||
var addr = settings.UnitProfiles[unit_name][1]
|
||||
var port = settings.UnitProfiles[unit_name][2][0]
|
||||
var sock: = SocketTCP.new()
|
||||
sock.unit_key = unit_name
|
||||
sock.unit_name = unit_name
|
||||
var rc: = sock.listen(port, addr)
|
||||
if rc == Error.OK:
|
||||
log.message(log.INFO, '\"%s\" слушает на %s:%d' % [unit_name, addr, port])
|
||||
@@ -109,26 +110,28 @@ func create_tcpsocket(unit_name: StringName) -> SocketTCP:
|
||||
return sock
|
||||
|
||||
|
||||
func create_serial(nm) -> Serial:
|
||||
var port = settings.UnitProfiles[nm][1]
|
||||
var baud = settings.UnitProfiles[nm][2][0]
|
||||
var sp: = Serial.new()
|
||||
sp.port = port
|
||||
sp.baudrate = baud
|
||||
sp.timeout = 20000
|
||||
return sp
|
||||
## [param unit_name] - Уникальное имя устройства[br]
|
||||
func create_serial(unit_name: StringName) -> Serial:
|
||||
var port = settings.UnitProfiles[unit_name][1]
|
||||
var baud = settings.UnitProfiles[unit_name][2][0]
|
||||
var serial: = Serial.new()
|
||||
serial.port = port
|
||||
serial.baudrate = baud
|
||||
serial.timeout = 20000
|
||||
return serial
|
||||
|
||||
|
||||
func create_modbus(nm) -> sch_3.Sch3:
|
||||
var unit_sch3: = sch_3.Sch3.new(nm)
|
||||
return unit_sch3
|
||||
## [param unit_name] - Уникальное имя устройства[br]
|
||||
func create_modbus(unit_name: StringName) -> sch_3.Sch3:
|
||||
var unit_modbus: = sch_3.Sch3.new(unit_name)
|
||||
return unit_modbus
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
poll_sockets.append(create_socket('уарэп-яу07-частный'))
|
||||
poll_sockets.append(create_socket('уарэп-яу07-общий'))
|
||||
poll_sockets.append(create_socket('уарэп-капсрпб'))
|
||||
poll_sockets.append(create_socket('навигация'))
|
||||
poll_sockets.append(create_socket_udp('уарэп-яу07-частный'))
|
||||
poll_sockets.append(create_socket_udp('уарэп-яу07-общий'))
|
||||
poll_sockets.append(create_socket_udp('уарэп-капсрпб'))
|
||||
poll_sockets.append(create_socket_udp('навигация'))
|
||||
sock_unicast = poll_sockets[0]
|
||||
sock_capsrpb = poll_sockets[2]
|
||||
|
||||
@@ -153,28 +156,28 @@ func _ready() -> void:
|
||||
var bind_modbuses: = []
|
||||
|
||||
for unit_name in settings.UnitProfiles:
|
||||
var st = settings.UnitProfiles[unit_name]
|
||||
var proto = st[0]
|
||||
var unit_profile = settings.UnitProfiles[unit_name]
|
||||
var proto = unit_profile[0]
|
||||
|
||||
if proto in UDPRX_PROTO:
|
||||
var new_unit = UDPRX_PROTO[proto].new(unit_name)
|
||||
units[unit_name] = new_unit
|
||||
units_udprx[unit_name] = new_unit
|
||||
dst_ports[unit_name] = st[2][0]
|
||||
dst_ports[unit_name] = unit_profile[2][0]
|
||||
|
||||
if proto in UDPTX_PROTO:
|
||||
var new_unit = UDPTX_PROTO[proto].new(unit_name)
|
||||
units[unit_name] = new_unit
|
||||
units_udp[unit_name] = new_unit
|
||||
dst_ports[unit_name] = st[2][0]
|
||||
dst_addrs[unit_name] = st[1]
|
||||
dst_ports[unit_name] = unit_profile[2][0]
|
||||
dst_addrs[unit_name] = unit_profile[1]
|
||||
|
||||
if proto in UDPJSON_PROTO:
|
||||
var new_unit = UDPJSON_PROTO[proto].new(unit_name)
|
||||
units[unit_name] = new_unit
|
||||
units_udp[unit_name] = new_unit
|
||||
dst_ports[unit_name] = st[2][1]
|
||||
dst_addrs[unit_name] = st[1]
|
||||
dst_ports[unit_name] = unit_profile[2][1]
|
||||
dst_addrs[unit_name] = unit_profile[1]
|
||||
|
||||
if proto in TCP_PROTO:
|
||||
var unit_tcp = TCP_PROTO[proto].new(unit_name)
|
||||
@@ -183,22 +186,22 @@ func _ready() -> void:
|
||||
|
||||
if proto in MODBUS_PROTO:
|
||||
var unit_modbus = MODBUS_PROTO[proto].new(unit_name)
|
||||
unit_modbus.port = settings.UnitProfiles[unit_name][1] # TODO: убрать это отсюда (обращение к глобальным данным из экземпляра)
|
||||
unit_modbus.params = settings.UnitProfiles[unit_name][2] # TODO: убрать это отсюда (обращение к глобальным данным из экземпляра)
|
||||
unit_modbus.port = unit_profile[1]
|
||||
unit_modbus.params = unit_profile[2]
|
||||
units[unit_name] = unit_modbus
|
||||
units_modbus[unit_name] = unit_modbus
|
||||
bind_modbuses.append([unit_modbus, unit_name])
|
||||
|
||||
if proto in SERIAL_PROTO:
|
||||
var unit_serial = SERIAL_PROTO[proto].new(unit_name)
|
||||
var serial = create_serial(unit_name)
|
||||
var serial: = create_serial(unit_name)
|
||||
units_serial[unit_name] = unit_serial
|
||||
units[unit_name] = unit_serial
|
||||
serials[unit_name] = serial
|
||||
|
||||
ProjectSettings.connect('settings_changed', Callable(self, '_on_settings_changed_serial').bind(bind_serials))
|
||||
|
||||
tcp_sockets.append([create_tcpsocket('уарэп-5п28'), units_tcp['уарэп-5п28']])
|
||||
tcp_sockets.append([create_socket_tcp('уарэп-5п28'), units_tcp['уарэп-5п28']])
|
||||
for key: StringName in dst_ports:
|
||||
unit_keys[dst_ports[key]] = key
|
||||
if logger_page:
|
||||
@@ -235,7 +238,7 @@ func _on_settings_changed_serial(bind_serials: Array):
|
||||
log.message(log.INFO, '%s для \"%s\"' % [serial, unit_name])
|
||||
|
||||
|
||||
func poll_receive_udp(sock: Socket) -> bool:
|
||||
func poll_receive_udp(sock: SocketUDP) -> bool:
|
||||
while sock.get_available_packet_count() > 0:
|
||||
var data: = sock.get_packet()
|
||||
var addr: = sock.get_packet_ip()
|
||||
@@ -246,9 +249,9 @@ func poll_receive_udp(sock: Socket) -> bool:
|
||||
units[unit_name].parse(data, tick)
|
||||
continue
|
||||
if unit_keys.has(port):
|
||||
var unit_key: = unit_keys[port]
|
||||
if units.has(unit_key):
|
||||
units[unit_key].parse(data, tick)
|
||||
var unit_name: = unit_keys[port]
|
||||
if units.has(unit_name):
|
||||
units[unit_name].parse(data, tick)
|
||||
continue
|
||||
var local_port: = sock.get_local_port()
|
||||
if unit_keys.has(local_port):
|
||||
@@ -267,15 +270,17 @@ func poll_receive_tcp(sock: SocketTCP) -> bool:
|
||||
log.info('подключен: %s:%d к порту: %d' % [ client.get_connected_host(), client.get_connected_port(), client.get_local_port() ] )
|
||||
var peer = sock.peerstream.get_stream_peer()
|
||||
if peer:
|
||||
var peer_len_data = peer.get_available_bytes()
|
||||
if peer_len_data > 0:
|
||||
get_client_data(sock, peer_len_data, peer)
|
||||
if sock.unit_key in units_tcp and sock.rx_all:
|
||||
units_tcp[sock.unit_key].parse(sock.rx_data, tick)
|
||||
while true:
|
||||
var peer_len_data: = peer.get_available_bytes()
|
||||
if peer_len_data <= 0:
|
||||
break
|
||||
get_client_data(sock, peer, peer_len_data)
|
||||
if sock.unit_name in units_tcp and sock.rx_all:
|
||||
units_tcp[sock.unit_name].parse(sock.rx_data, tick)
|
||||
return false
|
||||
|
||||
|
||||
func get_client_data(sock: SocketTCP, peer_len_data, peer):
|
||||
func get_client_data(sock: SocketTCP, peer: StreamPeer, peer_len_data: int) -> void:
|
||||
if tick - sock.rx_tick > sock.RX_TIMEOUT:
|
||||
sock.rx_all = true
|
||||
sock.rx_tick = tick
|
||||
@@ -299,35 +304,35 @@ func get_client_data(sock: SocketTCP, peer_len_data, peer):
|
||||
get_tcp_data(sock, peer, len_rx)
|
||||
|
||||
|
||||
func get_tcp_data(sock: SocketTCP, peer, len_rx):
|
||||
func get_tcp_data(sock: SocketTCP, peer: StreamPeer, len_rx: int):
|
||||
var temp_data = peer.get_data(len_rx)[1]
|
||||
sock.rx_data.append_array(temp_data)
|
||||
sock.rx_len += len_rx
|
||||
if sock.rx_len >= sock.head_len + sock.data_len:
|
||||
if sock.rx_len == sock.head_len + sock.data_len:
|
||||
sock.rx_all = true
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
tick = Time.get_ticks_msec()
|
||||
RenderingServer.global_shader_parameter_set('tick_curent', tick)
|
||||
for key: StringName in units_udp:
|
||||
var unit_udp: = units_udp[key]
|
||||
for unit_name: StringName in units_udp:
|
||||
var unit_udp: = units_udp[unit_name]
|
||||
if Error.OK == unit_udp.process(tick):
|
||||
var sock: = send_sockets[unit_udp.name]
|
||||
var tx_data: = unit_udp.tx_data.slice(0, unit_udp.tx_len)
|
||||
var dst_port: = dst_ports[key]
|
||||
var dst_addr: = dst_addrs[key]
|
||||
var dst_port: = dst_ports[unit_name]
|
||||
var dst_addr: = dst_addrs[unit_name]
|
||||
sock.send_to([dst_addr, dst_port], tx_data)
|
||||
for key: StringName in units_udprx:
|
||||
var unit_udprx: = units_udprx[key]
|
||||
for unit_name: StringName in units_udprx:
|
||||
var unit_udprx: = units_udprx[unit_name]
|
||||
unit_udprx.process(tick)
|
||||
for key: StringName in units_serial:
|
||||
var unit_serial: = units_serial[key]
|
||||
var serial: = serials[key]
|
||||
for unit_name: StringName in units_serial:
|
||||
var unit_serial: = units_serial[unit_name]
|
||||
var serial: = serials[unit_name]
|
||||
if Error.OK == unit_serial.process(tick):
|
||||
serial.send_to(unit_serial.tx_data)
|
||||
for key: StringName in units_modbus:
|
||||
var unit_modbus: = units_modbus[key]
|
||||
for unit_name: StringName in units_modbus:
|
||||
var unit_modbus: = units_modbus[unit_name]
|
||||
unit_modbus.process(tick)
|
||||
for sock_unit: Array in tcp_sockets:
|
||||
var sock = sock_unit[0]
|
||||
@@ -338,6 +343,7 @@ func _process(_delta: float) -> void:
|
||||
poll_sockets.any(poll_receive_udp)
|
||||
|
||||
|
||||
## [param unit_name] - Уникальное имя устройства[br]
|
||||
func get_unit_instance(unit_name: StringName) -> unit.Unit:
|
||||
tools.allways(unit_name in units, 'нет такого устройства: \"%s\"' % unit_name)
|
||||
return units[unit_name]
|
||||
|
||||
Reference in New Issue
Block a user