def udp_server_discovery(addr='255.255.255.255', port=UDP_PORT, every=3): server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) server.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # Set a timeout so the socket does not block # indefinitely when trying to receive data. server.settimeout(False) start_time = time.time() message = bytes(f"SERVER ON - {NODE_ID}", 'utf-8') while True: elapsed_time = time.time() - start_time logger.debug(f"message = {message}, {(addr, port)}") server.sendto(message, (addr, port)) elapsed_time_str = time.strftime("%H:%M:%S", time.gmtime(elapsed_time)) logger.debug( f"UDP: broadcast {addr, port} - message <<{message}>> sent! {elapsed_time_str}" ) try: data, incoming_addr = server.recvfrom(1024) logger.info("received message: %s from [%s]" % (data, incoming_addr)) except BlockingIOError as e: pass time.sleep(every)
def setup_pub_sub_socket(isServer, server_addr='', server_port=''): context = zmq.Context() socket = None if isServer: socket = context.socket(zmq.PUB) socket.bind("tcp://*:{server_port}") else: socket = context.socket(zmq.SUB) socket.connect("tcp://{server_addr}:{server_port}") logger.info("PUB/SUB set up") socket.setsockopt_string(zmq.SUBSCRIBE, "")
def connectToServer(self, server_addr, port): server_addr = server_addr or self.server port = port or DefaultPorts.XREQ.value context = zmq.Context() syncclient = context.socket(zmq.XREQ) syncclient.setsockopt(zmq.IDENTITY, f'{self._id}'.encode('utf-8')) try: syncclient.connect(f'tcp://{server_addr}:{port}') except zmq.error.ZMQError as err: logger.error(f"Failed to Connect to Server {server_addr}:{port}") self.com_link_status = Status.OFF else: logger.info( f"{self._id} is connected to Server {server_addr}:{port}") self.com_link_status = Status.ON return syncclient
def startService(self, port=None): """ the service that connectToServer will contact """ port = port or DefaultPorts.XREQ.value context = zmq.Context() syncservice = context.socket(zmq.XREP) try: syncservice.bind(f"tcp://*:{port}") except zmq.error.ZMQError as err: logger.error( f"{self._id} Failed to start service on {port}, {err}") self.com_link_status = Status.OFF else: logger.info(f"{self._id} Server Service Started on port {port}") self.com_link_status = Status.ON return syncservice
def start(worker): logger.info(f"{NODE_ID} Started") # progress_callback = worker.signals.progress # progress_callback.emit(0*100/4) disc_timeout = int(sys.argv) if len(sys.argv) > 1 and sys.argv[1] else 3 found = udp_client_discovery(timeout=disc_timeout) # progress_callback.emit(2*100/4) if found: logger.warning( f"{NODE_ID} >> a server was found - Setting up pub/sub to {found}") [(server_addr, port)] = found # progress_callback.emit(4*100/4) # start_as_client(server_addr) setup_pub_sub_socket(server_addr) else: # progress_callback.emit(4*100/4) logger.warning( f"{NODE_ID} -- No Server Found -- Initializing new Server") start_as_server()
def start_as_client(server_addr="localhost"): context = zmq.Context() syncclient = context.socket(zmq.XREQ) syncclient.connect(f'tcp://{server_addr}:5562') logger.info("start_as_client") while True: logger.info('sending XREQ ->') # send a synchronization request syncclient.send(b'HELLO XREQ ') logger.info('Waiting... for resp?') # wait for synchronization reply msg = syncclient.recv_multipart() logger.info(msg)
def udp_client_discovery(port=UDP_PORT, timeout=30, every=3): client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # UDP # client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) # client.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # Set some options to make it multicast-friendly client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) except AttributeError: pass # Some systems don't support SO_REUSEPORT client.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 20) client.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1) client.bind(('', port)) client.setblocking(False) # client.settimeout(3) start_time = time.time() found = [] while True: elapsed_time = time.time() - start_time try: data, addr = client.recvfrom(1024) logger.info("received message: %s from [%s]" % (data, addr)) if addr: found.append(addr) except BlockingIOError as e: logger.info(f"{NODE_ID} >> looking for Server ... [UDP]") finally: elapsed_time_str = time.strftime("%H:%M:%S", time.gmtime(elapsed_time)) logger.info(f"{NODE_ID} -- elapsed time = {elapsed_time_str}") if timeout and elapsed_time > timeout: logger.warning(f"{NODE_ID} >> timeout") return found time.sleep(every)
def printToScreen(self, msg): logger.info(msg)
def _broadcastNODE_IDentity(_q=None, every=3): logger.info( f"[{threading.current_thread().getName()}]-{NODE_ID} >> Broadcasting...: I'm The Server " ) udp_server_discovery(every=every)
def start_as_server(): def _broadcastNODE_IDentity(_q=None, every=3): logger.info( f"[{threading.current_thread().getName()}]-{NODE_ID} >> Broadcasting...: I'm The Server " ) udp_server_discovery(every=every) logger.info(f"{NODE_ID} -- Initializing new Server") logger.info(f"{NODE_ID} -- Setting up PUBLISHER on New Thread") pub_thread = threading.Thread(target=_broadcastNODE_IDentity) # pub_thread.daemon=True logger.info( f"[{threading.current_thread().getName()}]{NODE_ID} -- continiously broadcast That I'm the server unless i receive a TAKEOVER msg" ) pub_thread.start() # Prepare our context and sockets context = zmq.Context() syncservice = context.socket(zmq.XREP) syncservice.bind('tcp://*:5562') logger.info("START_AS_SERVER") POOL["server_thread"] = pub_thread every = 10 while True: logger.info( f"[{threading.current_thread().getName()}]-{NODE_ID} >> Broadcasting...: I'm The Server " ) time.sleep(every) logger.info('waiting got something? ->') # wait for synchronization request msg = syncservice.recv_multipart() logger.info(msg) # send synchronization reply syncservice.send_multipart([msg[0], b'Server Publisher Ready!']) syncservice.send_multipart([msg[0], b'sending this again!'])
f"{NODE_ID} >> a server was found - Setting up pub/sub to {found}") [(server_addr, port)] = found # progress_callback.emit(4*100/4) # start_as_client(server_addr) setup_pub_sub_socket(server_addr) else: # progress_callback.emit(4*100/4) logger.warning( f"{NODE_ID} -- No Server Found -- Initializing new Server") start_as_server() # initialize_new_server() if __name__ == "__main__": logger.info(f"{NODE_ID} Started") disc_timeout = int(sys.argv) if len(sys.argv) > 1 and sys.argv[1] else 3 found = udp_client_discovery(timeout=disc_timeout) if found: logger.warning( f"{NODE_ID} >> a server was found - Setting up pub/sub to {found}") [(server_addr, port)] = found start_as_client(server_addr) else: logger.warning( f"{NODE_ID} -- No Server Found -- Initializing new Server") start_as_server() # initialize_new_server()