def join(self, host, timeout=3): if self.mesh.join_state == JoinState.NONE: parser = JoinResponseParser() self.join_response_parser = parser self.mesh.join_state = JoinState.JOINING self.send_join_request(host) start = time.monotonic() while not parser.complete(): if time.monotonic() - start > timeout: raise RuntimeError("Timeout joining mesh") scheduler.update() if parser.error: raise RuntimeError("Failed to join mesh") self.mesh.set_host_index(parser.host_index) for info in parser.stations: address = info.connection_info.local.local.address station = self.stations.find_by_address( (address.host, address.port), True) self.mesh.add_station(station, info.index) host.connection_id_in = host.connection_id_in_temp host.connection_id_out = host.connection_id_out_temp self.join_response_parser = None self.mesh.join_state = JoinState.WAIT_CONNECTIONS for station in self.mesh.get_stations(): station.wait_connected()
def accept(self, sid): if self.state != STATE_READY: raise RuntimeError("PRUDP socket can only be used once") host, port = self.remote_address() logger.info("Accepting PRUDP connection from %s:%i", host, port) self.state = STATE_ACCEPTING self.local_port = sid self.stream.accept() self.socket_event = scheduler.add_socket(self.handle_packet, self.stream) while self.state == STATE_ACCEPTING: scheduler.update() if self.state != STATE_CONNECTED: return False logger.debug("PRUDP connection accepted successfully") self.start_ping() return True
def wait_connected(self, timeout=3): start = time.monotonic() while self.connection_state != ConnectionState.CONNECTED: if time.monotonic() - start > timeout: raise RuntimeError("Station connection timed out") if self.connection_state == ConnectionState.ERROR: raise RuntimeError("Station connection failed") scheduler.update()
def wait(self, info): rvcid = info.public_station.rvcid while self.results[rvcid] == self.RESULT_NONE: scheduler.update() result = self.results[rvcid] if result == self.RESULT_TIMEOUT: raise ConnectionError("Connection timed out") if result == self.RESULT_DENIED: raise ConnectionError("Connection denied")
def wait(self, timeout): start = time.monotonic() while self.sock and not self.messages: if time.monotonic() - start > timeout: self.cleanup() raise RuntimeError("HTTP request timed out") scheduler.update() if not self.messages: raise RuntimeError("HTTP request failed") return self.messages.pop(0)
def receive_browse_reply(self, timeout, key, challenge): start = time.monotonic() while True: if time.monotonic() - start >= timeout: return None result = self.s.recvfrom() if result: data, addr = result reply = self.parse_browse_reply(data, key, challenge) if reply: return reply scheduler.update()
def receive_browse_reply(self, timeout, max, key, challenge): sessions = [] ids = [] start = time.monotonic() while time.monotonic() - start < timeout: result = self.s.recv() if result: data, addr = result session = self.parse_browse_reply(data, key, challenge) if session and session.session_id not in ids: ids.append(session.session_id) sessions.append(session) scheduler.update() return sessions
def get_response(self, call_id, timeout=5): start = time.monotonic() while call_id not in self.responses: if not self.sock.is_connected(): raise ConnectionError("RMC failed because the PRUDP connection was closed") scheduler.update() now = time.monotonic() if now - start >= timeout: raise RuntimeError("RMC request timed out") result, stream = self.responses.pop(call_id) if result: result.raise_if_error() return stream
def accept(self, stream_id): if self.state != self.READY: raise RuntimeError("PRUDP socket may only be used once") self.state = self.ACCEPTING self.local_port = stream_id self.timeout_event = scheduler.add_timeout(self.handle_silence_timeout, self.silence_timeout) self.socket_event = scheduler.add_socket(self.handle_recv, self.sock) next(self.packet_id_out) while self.state == self.ACCEPTING: scheduler.update() return self.state == self.CONNECTED
def get_response(self, call_id, timeout=5): timer = 0 while call_id not in self.responses: if not self.client.is_connected(): raise ConnectionError("RMC failed because the PRUDP connection was closed") scheduler.update() time.sleep(0.05) timer += 0.05 if timer >= timeout: raise RuntimeError("RMC request timed out") error, stream = self.responses.pop(call_id) if error != -1: raise RuntimeError(error, "RMC failed (%s)" %errors.error_names.get(error, "unknown error")) return stream
def get_response(self, call_id, timeout=5): start = time.monotonic() while call_id not in self.responses: if not self.sock.is_connected(): raise ConnectionError( "RMC failed because the PRUDP connection was closed") scheduler.update() now = time.monotonic() if now - start >= timeout: raise RuntimeError("RMC request timed out") message = self.responses.pop(call_id) if message.error != -1: raise common.RMCError(message.error) return message.body
def join(self, host_station): self.join_state = self.JOIN_WAITING self.protocol.send_join_request(host_station) while self.join_state == self.JOIN_WAITING: scheduler.update() if self.join_state == self.JOIN_DENIED: raise RuntimeError("Join request denied") logger.info("Wait until all stations are connected") all_connected = False while not all_connected: all_connected = True for station in self.stations: if not station.is_connected: all_connected = False scheduler.update() logger.info("Successfully joined a mesh!")
def send(self, packet, block=False): if not packet.flags & FLAG_ACK: packet.packet_id = self.sequence_mgr.assign(packet) packet.payload = self.message_encoder.encode(packet) logger.debug("Sending packet: %s", packet) self.sock.send(self.packet_encoder.encode(packet)) if packet.flags & FLAG_RELIABLE or packet.type == TYPE_SYN: if packet.flags & FLAG_NEED_ACK: key = (packet.type, packet.stream_id, packet.packet_id) event = scheduler.add_timeout(self.handle_timeout, self.resend_timeout, param=(packet, 0)) self.ack_events[key] = (event, block) if block: while key in self.ack_events: scheduler.update() if key in self.ack_packets: return self.ack_packets.pop(key)
def wait_ack(self, message): ack_id = struct.unpack_from(">I", message.payload, -4)[0] while ack_id not in self.messages: scheduler.update()
def wait_ack(self, packet): while self.state != self.DISCONNECTED and packet.packet_id in self.ack_events: scheduler.update() return self.state != self.DISCONNECTED
def wait_completed(self): while not self.completed: scheduler.update()