import socket import selectors import time from msg_montainer import MsgContainer from nmea import NmeaReceiver from msg_sink import MsgSink from msg_source import MsgSource from packetizer import Packetizer class MultiClient(MsgSource): def __init__(self, servers: list[dict]): MsgSource.__init__(self) self.sel = None self.sock_list = [{'name': s['name'], 'addr': (s['host'], s['port'])} for s in servers] self.receivers = {} for server in self.sock_list: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setblocking(False) server['sock'] = sock def register_recv(self, name: str, rx: MsgSink): self.receivers[name] = {'rx': rx} def find_by_addr(self, addr): for sock in self.sock_list: if sock['addr'] == addr: return sock return None def connect(self): 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=1) rx_data = [] for key, mask in events: descr = self.find_by_addr(key.fileobj.getpeername()) name = descr['name'] if name in self.receivers: rx = self.receivers[name]['rx'] 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 = MultiClient(server_list) # NMEA multi source receiver receiver = NmeaReceiver() # receiver.filter_by_msg_type('.*') receiver.filter_by_msg_type('^.?GPGSV.*') receiver.filter_by_msg_type('^.?GNGLL.*') # Packetizer for "zed-x20p" packetizer_0 = Packetizer() packetizer_0.register_recv("zed-x20p", receiver) # Packetizer for "neo-f9p" packetizer_1 = Packetizer() packetizer_1.register_recv("neo-f9p", receiver) # Register both packetizers at multi source receiver mc.register_recv("zed-x20p", packetizer_0) mc.register_recv("neo-f9p", packetizer_1) # Connect all sources mc.connect() # receive and block mc.event_loop() # code never reached mc.disconnect()