Receive a single JSON message from the socket.
(self, timeout: Optional[float] = None)
| 80 | self._buffer = b"" |
| 81 | |
| 82 | def _recv_message(self, timeout: Optional[float] = None) -> dict: |
| 83 | """Receive a single JSON message from the socket.""" |
| 84 | if not self._socket: |
| 85 | raise RuntimeError("Not connected") |
| 86 | |
| 87 | timeout = timeout or self.timeout |
| 88 | end_time = time.time() + timeout |
| 89 | |
| 90 | while True: |
| 91 | newline_pos = self._buffer.find(b"\n") |
| 92 | if newline_pos != -1: |
| 93 | line = self._buffer[:newline_pos] |
| 94 | self._buffer = self._buffer[newline_pos + 1 :] |
| 95 | |
| 96 | if line.strip(): |
| 97 | return json.loads(line.decode("utf-8")) |
| 98 | continue |
| 99 | |
| 100 | remaining = end_time - time.time() |
| 101 | if remaining <= 0: |
| 102 | raise TimeoutError("Timeout waiting for response") |
| 103 | |
| 104 | self._socket.settimeout(min(remaining, 0.1)) |
| 105 | try: |
| 106 | chunk = self._socket.recv(65536) |
| 107 | if not chunk: |
| 108 | raise ConnectionError("Connection closed by server") |
| 109 | self._buffer += chunk |
| 110 | except socket.timeout: |
| 111 | continue |
| 112 | |
| 113 | def _send_message(self, message: dict) -> None: |
| 114 | """Send a JSON message to the server.""" |