Пример #1
0
    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
Пример #2
0
    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