(sock: socket.socket, data: Union[bytes, str])
| 156 | |
| 157 | |
| 158 | def send(sock: socket.socket, data: Union[bytes, str]) -> int: |
| 159 | if isinstance(data, str): |
| 160 | data = data.encode("utf-8") |
| 161 | |
| 162 | if not sock: |
| 163 | raise WebSocketConnectionClosedException("socket is already closed.") |
| 164 | |
| 165 | def _send() -> int: |
| 166 | try: |
| 167 | return sock.send(data) |
| 168 | except SSLEOFError: |
| 169 | raise WebSocketConnectionClosedException("socket is already closed.") |
| 170 | except SSLWantWriteError: |
| 171 | pass |
| 172 | except socket.error as exc: |
| 173 | error_code = extract_error_code(exc) |
| 174 | if error_code is None: |
| 175 | raise |
| 176 | if error_code not in [errno.EAGAIN, errno.EWOULDBLOCK]: |
| 177 | raise |
| 178 | |
| 179 | sel = selectors.DefaultSelector() |
| 180 | sel.register(sock, selectors.EVENT_WRITE) |
| 181 | |
| 182 | w = sel.select(sock.gettimeout()) |
| 183 | sel.close() |
| 184 | |
| 185 | if w: |
| 186 | return sock.send(data) |
| 187 | return 0 |
| 188 | |
| 189 | try: |
| 190 | if sock.gettimeout() == 0: |
| 191 | return sock.send(data) |
| 192 | else: |
| 193 | return _send() |
| 194 | except socket.timeout as e: |
| 195 | message = extract_err_message(e) |
| 196 | raise WebSocketTimeoutException(message) |
| 197 | except (OSError, SSLError) as e: |
| 198 | message = extract_err_message(e) |
| 199 | if isinstance(message, str) and "timed out" in message: |
| 200 | raise WebSocketTimeoutException(message) |
| 201 | else: |
| 202 | raise |
searching dependent graphs…