async def _broadcaster_evaluate(self, addr, commands): search_replies = [] version_requested = False for command in commands: if isinstance(command, ca.VersionRequest): version_requested = True elif isinstance(command, ca.SearchRequest): pv_name = command.name try: known_pv = self[pv_name] is not None except KeyError: known_pv = False if known_pv: # responding with an IP of `None` tells client to get IP # address from the datagram. search_replies.append( ca.SearchResponse(self.port, None, command.cid, ca.DEFAULT_PROTOCOL_VERSION) ) if search_replies: if version_requested: bytes_to_send = self.broadcaster.send(ca.VersionResponse(13), *search_replies) else: bytes_to_send = self.broadcaster.send(*search_replies) for udp_sock in self.udp_socks.values(): try: await udp_sock.sendto(bytes_to_send, addr) except OSError as exc: host, port = addr raise CaprotoNetworkError(f"Failed to send to {host}:{port}") from exc
async def _broadcaster_queue_iteration(self, addr, messages): self.broadcaster.process_commands(messages) found_pv_to_cid = {} saw_empty_channel_list = False for message in messages: if isinstance(message, pva.SearchRequest): if len(message.channels) == 0: # This is apparently a special "I'm looking for servers" # message saw_empty_channel_list = True for channel in message.channels: try: channel['id'] name = channel['channel_name'] self[name] except KeyError: ... else: found_pv_to_cid[name] = channel['id'] if found_pv_to_cid or saw_empty_channel_list: search_replies = [ self.broadcaster.search_response(pv_to_cid=found_pv_to_cid, ) ] bytes_to_send = self.broadcaster.send(*search_replies) # TODO: why send this back on all sockets? for udp_sock in self.udp_socks.values(): try: await udp_sock.sendto(bytes_to_send, addr) except OSError as exc: host, port = addr raise CaprotoNetworkError( f"Failed to send to {host}:{port}") from exc