import socket import selectors import time from msg_container import MsgContainer from packetizer import Packetizer from transceiver import Transceiver from a_backend import ABackend from nmea.GLL import Gll from nmea.GSA import Gsa from nmea.GSV import Gsv class NetworkBackend(ABackend): def __init__(self, servers: list[dict]): self.sel = None self.sock_list = [{'name': s['name'], 'addr': (s['host'], s['port']), 'xcvr': None} for s in servers] def create_xcvr(self, name: str) -> Transceiver: obj = Transceiver(self, name) if not self.register_xcvr(obj): raise Exception(f"No socket found for \"{name}\"") return obj self.sel.register(name, selectors.EVENT_READ, data=None) def register_xcvr(self, xcvr: Transceiver): found = False for sock in self.sock_list: if xcvr.name in sock['name']: found = True sock['xcvr'] = xcvr break return found def find_by_addr(self, addr): for sock in self.sock_list: if sock['addr'] == addr: return sock return None def find_by_name(self, name: str): for sock in self.sock_list: if sock['name'] == name: return sock return None def _prepare(self): for server in self.sock_list: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setblocking(False) server['sock'] = sock def connect(self): self._prepare() self.sel = selectors.DefaultSelector() events = selectors.EVENT_READ for sock in self.sock_list: print(f"Starting connection {sock['name']} to {sock['addr']}") self.sel.register(sock['sock'], events, data=None) sock['sock'].connect_ex(sock['addr']) def disconnect(self): for sock in self.sock_list: sock['sock'].close() def event_loop(self): try: while True: events = self.sel.select(timeout=100) for key, mask in events: descr = self.find_by_addr(key.fileobj.getpeername()) name = descr['name'] sock = self.find_by_name(name) rx = sock['xcvr'] if mask & selectors.EVENT_READ: timestamp = time.time() data = key.fileobj.recv(16) rx.on_recv(MsgContainer(name, timestamp, data)) except KeyboardInterrupt: print("Caught keyboard interrupt, exiting") finally: self.sel.close() if __name__ == "__main__": server_list = [ {'name': "neo-f9p", 'host': "192.168.22.93", 'port': 8721}, {'name': "zed-x20p", 'host': "192.168.22.93", 'port': 8731} ] # TCPIP multi source receiver mc = NetworkBackend(server_list) xcvr_1 = mc.create_xcvr("neo-f9p") xcvr_2 = mc.create_xcvr("zed-x20p") # Packetizer for "zed-x20p" packetizer_0 = Packetizer() # Packetizer for "neo-f9p" packetizer_1 = Packetizer() xcvr_1.register_recv(packetizer_0) xcvr_2.register_recv(packetizer_1) rx_list = [ Gll('Rx', '--'), Gsa('Rx', '--'), Gsv('Rx', '--') ] # Register all Rx to all sources for rx in rx_list: packetizer_0.register_recv(rx) packetizer_1.register_recv(rx) # Connect all sources mc.connect() # receive and block mc.event_loop() # code never reached mc.disconnect()