ws icon indicating copy to clipboard operation
ws copied to clipboard

HandshakeError after run 'ws listen ws://localhost:8000/hello' on macOS

Open sangshuduo opened this issue 2 years ago • 2 comments

ws --version ws version 0.1.0

python3 --version Python 3.10.13

`ws listen ws://localhost:8000/hello  ✔  9657  21:58:08 ExceptionGroup: all attempts to connect to localhost:8000 failed (2 sub-exceptions)

The above exception was the direct cause of the following exception:

╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/trio_websocket/_impl.py:120 in │ │ open_websocket │ │ │ │ 117 │ async with trio.open_nursery() as new_nursery: │ │ 118 │ │ try: │ │ 119 │ │ │ with trio.fail_after(connect_timeout): │ │ ❱ 120 │ │ │ │ connection = await connect_websocket(new_nursery, host, port, │ │ 121 │ │ │ │ │ resource, use_ssl=use_ssl, subprotocols=subprotocols, │ │ 122 │ │ │ │ │ extra_headers=extra_headers, │ │ 123 │ │ │ │ │ message_queue_size=message_queue_size, │ │ │ │ ╭───────────────────────── locals ──────────────────────────╮ │ │ │ connect_timeout = 5.0 │ │ │ │ disconnect_timeout = 5.0 │ │ │ │ extra_headers = None │ │ │ │ host = 'localhost' │ │ │ │ max_message_size = 1048576 │ │ │ │ message_queue_size = 1 │ │ │ │ new_nursery = <trio.Nursery object at 0x105ddcbb0> │ │ │ │ port = 8000 │ │ │ │ resource = '/hello' │ │ │ │ subprotocols = None │ │ │ │ use_ssl = False │ │ │ ╰───────────────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/trio_websocket/_impl.py:183 in │ │ connect_websocket │ │ │ │ 180 │ logger.debug('Connecting to ws%s://%s:%d%s', │ │ 181 │ │ '' if ssl_context is None else 's', host, port, resource) │ │ 182 │ if ssl_context is None: │ │ ❱ 183 │ │ stream = await trio.open_tcp_stream(host, port) │ │ 184 │ else: │ │ 185 │ │ stream = await trio.open_ssl_over_tcp_stream(host, port, │ │ 186 │ │ │ ssl_context=ssl_context, https_compatible=True) │ │ │ │ ╭───────────────────────── locals ──────────────────────────╮ │ │ │ extra_headers = None │ │ │ │ host = 'localhost' │ │ │ │ max_message_size = 1048576 │ │ │ │ message_queue_size = 1 │ │ │ │ nursery = <trio.Nursery object at 0x105ddcbb0> │ │ │ │ port = 8000 │ │ │ │ resource = '/hello' │ │ │ │ ssl_context = None │ │ │ │ subprotocols = None │ │ │ │ use_ssl = False │ │ │ ╰───────────────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/trio/_highlevel_open_tcp_stream.py:403 │ │ in open_tcp_stream │ │ │ │ 400 │ │ if winning_socket is None: │ │ 401 │ │ │ assert len(oserrors) == len(targets) │ │ 402 │ │ │ msg = f"all attempts to connect to {format_host_port(host, port)} failed" │ │ ❱ 403 │ │ │ raise OSError(msg) from ExceptionGroup(msg, oserrors) │ │ 404 │ │ else: │ │ 405 │ │ │ stream = trio.SocketStream(winning_socket) │ │ 406 │ │ │ open_sockets.remove(winning_socket) │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ _ = '' │ │ │ │ addr = ('127.0.0.1', 8000) │ │ │ │ address_family = <AddressFamily.AF_INET: 2> │ │ │ │ attempt_connect = <function open_tcp_stream..attempt_connect at 0x105dd8700> │ │ │ │ attempt_failed = Event(_tasks=set(), _flag=True) │ │ │ │ happy_eyeballs_delay = 0.25 │ │ │ │ host = 'localhost' │ │ │ │ local_address = None │ │ │ │ msg = 'all attempts to connect to localhost:8000 failed' │ │ │ │ nursery = <trio.Nursery object at 0x105ddc4f0> │ │ │ │ open_sockets = { │ │ │ │ │ <trio.socket.socket [closed] fd=-1, │ │ │ │ family=AddressFamily.AF_INET6, type=SocketKind.SOCK_STREAM, proto=6>, │ │ │ │ │ <trio.socket.socket [closed] fd=-1, family=AddressFamily.AF_INET, │ │ │ │ type=SocketKind.SOCK_STREAM, proto=6> │ │ │ │ } │ │ │ │ oserrors = [ │ │ │ │ │ ConnectionRefusedError(61, "Error connecting to ('::1', 8000, 0, │ │ │ │ 0): Connection refused"), │ │ │ │ │ ConnectionRefusedError(61, "Error connecting to ('127.0.0.1', │ │ │ │ 8000): Connection refused") │ │ │ │ ] │ │ │ │ port = 8000 │ │ │ │ proto = 6 │ │ │ │ socket_type = <SocketKind.SOCK_STREAM: 1> │ │ │ │ targets = [ │ │ │ │ │ ( │ │ │ │ │ │ <AddressFamily.AF_INET6: 30>, │ │ │ │ │ │ <SocketKind.SOCK_STREAM: 1>, │ │ │ │ │ │ 6, │ │ │ │ │ │ '', │ │ │ │ │ │ ('::1', 8000, 0, 0) │ │ │ │ │ ), │ │ │ │ │ ( │ │ │ │ │ │ <AddressFamily.AF_INET: 2>, │ │ │ │ │ │ <SocketKind.SOCK_STREAM: 1>, │ │ │ │ │ │ 6, │ │ │ │ │ │ '', │ │ │ │ │ │ ('127.0.0.1', 8000) │ │ │ │ │ ) │ │ │ │ ] │ │ │ │ winning_socket = None │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ OSError: all attempts to connect to localhost:8000 failed

The above exception was the direct cause of the following exception:

╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮ │ /Users/sangshuduo/anaconda3/bin/ws:8 in │ │ │ │ 5 from ws.main import cli │ │ 6 if name == 'main': │ │ 7 │ sys.argv[0] = re.sub(r'(-script.pyw|.exe)?$', '', sys.argv[0]) │ │ ❱ 8 │ sys.exit(cli()) │ │ 9 │ │ │ │ ╭────────────────────────────────── locals ───────────────────────────────────╮ │ │ │ cli = <DYMGroup cli> │ │ │ │ re = <module 're' from '/Users/sangshuduo/anaconda3/lib/python3.10/re.py'> │ │ │ │ sys = <module 'sys' (built-in)> │ │ │ ╰─────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/click/core.py:1157 in call │ │ │ │ 1154 │ │ │ 1155 │ def call(self, *args: t.Any, **kwargs: t.Any) -> t.Any: │ │ 1156 │ │ """Alias for :meth:main.""" │ │ ❱ 1157 │ │ return self.main(*args, **kwargs) │ │ 1158 │ │ 1159 │ │ 1160 class Command(BaseCommand): │ │ │ │ ╭──────── locals ─────────╮ │ │ │ args = () │ │ │ │ kwargs = {} │ │ │ │ self = <DYMGroup cli> │ │ │ ╰─────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/click/core.py:1078 in main │ │ │ │ 1075 │ │ try: │ │ 1076 │ │ │ try: │ │ 1077 │ │ │ │ with self.make_context(prog_name, args, **extra) as ctx: │ │ ❱ 1078 │ │ │ │ │ rv = self.invoke(ctx) │ │ 1079 │ │ │ │ │ if not standalone_mode: │ │ 1080 │ │ │ │ │ │ return rv │ │ 1081 │ │ │ │ │ # it's not safe to ctx.exit(rv) here! │ │ │ │ ╭───────────────────────────── locals ─────────────────────────────╮ │ │ │ args = ['listen', 'ws://localhost:8000/hello'] │ │ │ │ complete_var = None │ │ │ │ ctx = <click.core.Context object at 0x1027953f0> │ │ │ │ extra = {} │ │ │ │ prog_name = 'ws' │ │ │ │ self = <DYMGroup cli> │ │ │ │ standalone_mode = True │ │ │ │ windows_expand_args = True │ │ │ ╰──────────────────────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/click/core.py:1688 in invoke │ │ │ │ 1685 │ │ │ │ super().invoke(ctx) │ │ 1686 │ │ │ │ sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) │ │ 1687 │ │ │ │ with sub_ctx: │ │ ❱ 1688 │ │ │ │ │ return _process_result(sub_ctx.command.invoke(sub_ctx)) │ │ 1689 │ │ │ │ 1690 │ │ # In chain mode we create the contexts step by step, but after the │ │ 1691 │ │ # base command has been invoked. Because at that point we do not │ │ │ │ ╭───────────────────────────────────────── locals ─────────────────────────────────────────╮ │ │ │ _process_result = <function MultiCommand.invoke.._process_result at 0x10265fd90> │ │ │ │ args = [] │ │ │ │ cmd = <Command listen> │ │ │ │ cmd_name = 'listen' │ │ │ │ ctx = <click.core.Context object at 0x1027953f0> │ │ │ │ self = <DYMGroup cli> │ │ │ │ sub_ctx = <click.core.Context object at 0x105dddd80> │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/click/core.py:1434 in invoke │ │ │ │ 1431 │ │ │ echo(style(message, fg="red"), err=True) │ │ 1432 │ │ │ │ 1433 │ │ if self.callback is not None: │ │ ❱ 1434 │ │ │ return ctx.invoke(self.callback, **ctx.params) │ │ 1435 │ │ │ 1436 │ def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: │ │ 1437 │ │ """Return a list of completions for the incomplete value. Looks │ │ │ │ ╭───────────────────── locals ──────────────────────╮ │ │ │ ctx = <click.core.Context object at 0x105dddd80> │ │ │ │ self = <Command listen> │ │ │ ╰───────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/click/core.py:783 in invoke │ │ │ │ 780 │ │ │ │ 781 │ │ with augment_usage_errors(__self): │ │ 782 │ │ │ with ctx: │ │ ❱ 783 │ │ │ │ return __callback(*args, **kwargs) │ │ 784 │ │ │ 785 │ def forward( │ │ 786 │ │ __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any # noqa: B902 │ │ │ │ ╭──────────────────────────── locals ─────────────────────────────╮ │ │ │ _Context__callback = <function listen at 0x105764d30> │ │ │ │ _Context__self = <click.core.Context object at 0x105dddd80> │ │ │ │ args = () │ │ │ │ ctx = <click.core.Context object at 0x105dddd80> │ │ │ │ kwargs = { │ │ │ │ │ 'url': 'ws://localhost:8000/hello', │ │ │ │ │ 'is_json': False, │ │ │ │ │ 'duration': None, │ │ │ │ │ 'filename': None │ │ │ │ } │ │ │ ╰─────────────────────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/ws/commands/listen.py:76 in listen │ │ │ │ 73 @filename_option │ │ 74 def listen(url: str, is_json: bool, duration: float, filename: str): │ │ 75 │ """Listens messages on a given URL.""" │ │ ❱ 76 │ trio.run(main, url, is_json, duration, filename) │ │ 77 │ │ │ │ ╭──────────────── locals ────────────────╮ │ │ │ duration = None │ │ │ │ filename = None │ │ │ │ is_json = False │ │ │ │ url = 'ws://localhost:8000/hello' │ │ │ ╰────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/trio/_core/_run.py:2275 in run │ │ │ │ 2272 │ if isinstance(runner.main_task_outcome, Value): │ │ 2273 │ │ return cast(RetT, runner.main_task_outcome.value) │ │ 2274 │ elif isinstance(runner.main_task_outcome, Error): │ │ ❱ 2275 │ │ raise runner.main_task_outcome.error │ │ 2276 │ else: # pragma: no cover │ │ 2277 │ │ raise AssertionError(runner.main_task_outcome) │ │ 2278 │ │ │ │ ╭─────────────────────────────────────────── locals ───────────────────────────────────────────╮ │ │ │ args = ( │ │ │ │ │ 'ws://localhost:8000/hello', │ │ │ │ │ False, │ │ │ │ │ None, │ │ │ │ │ None │ │ │ │ ) │ │ │ │ async_fn = <function main at 0x105764b80> │ │ │ │ clock = None │ │ │ │ gen = <generator object unrolled_run at 0x105df06d0> │ │ │ │ instruments = () │ │ │ │ next_send = [] │ │ │ │ prev_library = None │ │ │ │ restrict_keyboard_interrupt_to_checkpoints = False │ │ │ │ runner = Runner( │ │ │ │ │ clock=SystemClock( │ │ │ │ │ │ offset=162718.46147645527 │ │ │ │ │ ), │ │ │ │ │ instruments={'_all': {}}, │ │ │ │ │ io_manager=KqueueIOManager( │ │ │ │ │ │ _kqueue=<select.kqueue object at │ │ │ │ 0x1025ffbf0>, │ │ │ │ │ │ _registered={}, │ │ │ │ │ │ │ │ │ │ _force_wakeup=<trio._core._wakeup_socketpair.W… │ │ │ │ object at 0x105ddce20>, │ │ │ │ │ │ _force_wakeup_fd=4 │ │ │ │ │ ), │ │ │ │ │ ki_manager=KIManager(handler=None), │ │ │ │ │ strict_exception_groups=False, │ │ │ │ │ _locals={ │ │ │ │ │ │ <RunVar name='limiter'>: │ │ │ │ <trio.CapacityLimiter at 0x105dde710, 0/40 with │ │ │ │ 0 waiting> │ │ │ │ │ }, │ │ │ │ │ runq=deque(), │ │ │ │ │ tasks=set(), │ │ │ │ │ deadlines=Deadlines(_heap=[], _active=0), │ │ │ │ │ init_task=Task( │ │ │ │ │ │ _parent_nursery=None, │ │ │ │ │ │ coro=<coroutine object Runner.init at │ │ │ │ 0x105df0740>, │ │ │ │ │ │ _runner=..., │ │ │ │ │ │ name='', │ │ │ │ │ │ context=<_contextvars.Context object at │ │ │ │ 0x105deaa80>, │ │ │ │ │ │ _counter=0, │ │ │ │ │ │ _next_send_fn=None, │ │ │ │ │ │ _next_send=None, │ │ │ │ │ │ _abort_func=None, │ │ │ │ │ │ custom_sleep_data=None, │ │ │ │ │ │ _child_nurseries=[], │ │ │ │ │ │ _eventual_parent_nursery=None, │ │ │ │ │ │ _cancel_points=3, │ │ │ │ │ │ _schedule_points=4 │ │ │ │ │ ), │ │ │ │ │ system_nursery=<trio.Nursery object at │ │ │ │ 0x105dde1d0>, │ │ │ │ │ system_context=<_contextvars.Context object │ │ │ │ at 0x105dea180>, │ │ │ │ │ main_task=Task( │ │ │ │ │ │ _parent_nursery=<trio.Nursery object at │ │ │ │ 0x105dde260>, │ │ │ │ │ │ coro=<coroutine object main at │ │ │ │ 0x105df07b0>, │ │ │ │ │ │ _runner=..., │ │ │ │ │ │ name='ws.commands.listen.main', │ │ │ │ │ │ context=<_contextvars.Context object at │ │ │ │ 0x105deac80>, │ │ │ │ │ │ _counter=1, │ │ │ │ │ │ _next_send_fn=None, │ │ │ │ │ │ _next_send=None, │ │ │ │ │ │ _abort_func=None, │ │ │ │ │ │ custom_sleep_data=None, │ │ │ │ │ │ _child_nurseries=[], │ │ │ │ │ │ _eventual_parent_nursery=None, │ │ │ │ │ │ _cancel_points=1, │ │ │ │ │ │ _schedule_points=1 │ │ │ │ │ ), │ │ │ │ │ main_task_outcome=Error( │ │ │ │ │ │ _unwrapped=False, │ │ │ │ │ │ error=HandshakeError() │ │ │ │ │ ), │ │ │ │ │ entry_queue=EntryQueue( │ │ │ │ │ │ queue=deque(), │ │ │ │ │ │ idempotent_queue={}, │ │ │ │ │ │ │ │ │ │ wakeup=<trio._core._wakeup_socketpair.WakeupSo… │ │ │ │ object at 0x105ddd300>, │ │ │ │ │ │ done=True, │ │ │ │ │ │ lock=<unlocked _thread.RLock object │ │ │ │ owner=0 count=0 at 0x105dea6c0> │ │ │ │ │ ), │ │ │ │ │ trio_token=TrioToken( │ │ │ │ │ │ _reentry_queue=EntryQueue( │ │ │ │ │ │ │ queue=deque(), │ │ │ │ │ │ │ idempotent_queue={}, │ │ │ │ │ │ │ │ │ │ │ wakeup=<trio._core._wakeup_socketpair.WakeupSo… │ │ │ │ object at 0x105ddd300>, │ │ │ │ │ │ │ done=True, │ │ │ │ │ │ │ lock=<unlocked _thread.RLock object │ │ │ │ owner=0 count=0 at 0x105dea6c0> │ │ │ │ │ │ ) │ │ │ │ │ ), │ │ │ │ │ asyncgens=AsyncGenerators( │ │ │ │ │ │ alive=set(), │ │ │ │ │ │ trailing_needs_finalize=set(), │ │ │ │ │ │ │ │ │ │ prev_hooks=asyncgen_hooks(firstiter=None, │ │ │ │ finalizer=None) │ │ │ │ │ ), │ │ │ │ │ clock_autojump_threshold=inf, │ │ │ │ │ is_guest=False, │ │ │ │ │ guest_tick_scheduled=False, │ │ │ │ │ ki_pending=False, │ │ │ │ │ waiting_for_idle=SortedDict({}) │ │ │ │ ) │ │ │ │ strict_exception_groups = False │ │ │ │ timeout = 0 │ │ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/ws/commands/listen.py:60 in main │ │ │ │ 57 │ │ 58 │ │ 59 async def main(url: str, is_json: bool, duration: Optional[float] = None, filename: Opti │ │ ❱ 60 │ async with trio.open_nursery() as nursery: │ │ 61 │ │ nursery.start_soon(function_runner, nursery.cancel_scope, listen_messages, url, │ │ 62 │ │ nursery.start_soon(signal_handler, nursery.cancel_scope) │ │ 63 │ │ nursery.start_soon(sleep_until, nursery.cancel_scope, duration) │ │ │ │ ╭────────────────────────────── locals ──────────────────────────────╮ │ │ │ @TRIO_KI_PROTECTION_ENABLED = False │ │ │ │ duration = None │ │ │ │ filename = None │ │ │ │ is_json = False │ │ │ │ nursery = <trio.Nursery object at 0x105ddd4e0> │ │ │ │ url = 'ws://localhost:8000/hello' │ │ │ ╰────────────────────────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/trio/_core/_run.py:971 in aexit │ │ │ │ 968 │ │ │ # allow us to encapsulate this context fixup. │ │ 969 │ │ │ old_context = combined_error_from_nursery.context │ │ 970 │ │ │ try: │ │ ❱ 971 │ │ │ │ raise combined_error_from_nursery │ │ 972 │ │ │ finally: │ │ 973 │ │ │ │ _, value, _ = sys.exc_info() │ │ 974 │ │ │ │ assert value is combined_error_from_nursery │ │ │ │ ╭───────────────────────────────────────── locals ──────────────────────────────────────────╮ │ │ │ @TRIO_KI_PROTECTION_ENABLED = True │ │ │ │ etype = None │ │ │ │ exc = None │ │ │ │ old_context = OSError('all attempts to connect to localhost:8000 failed') │ │ │ │ self = NurseryManager(strict_exception_groups=False) │ │ │ │ tb = None │ │ │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/ws/utils/io.py:22 in function_runner │ │ │ │ 19 │ │ 20 │ │ 21 async def function_runner(scope: trio.CancelScope, function: Callable, *args: Any) -> No │ │ ❱ 22 │ await function(*args) │ │ 23 │ # noinspection PyAsyncCall │ │ 24 │ scope.cancel() │ │ 25 │ │ │ │ ╭───────────────────────────────── locals ─────────────────────────────────╮ │ │ │ @TRIO_KI_PROTECTION_ENABLED = False │ │ │ │ args = ('ws://localhost:8000/hello', False, None) │ │ │ │ function = <function listen_messages at 0x105764af0> │ │ │ │ scope = CancelScope( │ │ │ │ │ _cancel_status=None, │ │ │ │ │ _has_been_entered=True, │ │ │ │ │ _registered_deadline=inf, │ │ │ │ │ _cancel_called=True, │ │ │ │ │ cancelled_caught=True, │ │ │ │ │ _deadline=inf, │ │ │ │ │ _shield=False │ │ │ │ ) │ │ │ ╰──────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/ws/commands/listen.py:47 in │ │ listen_messages │ │ │ │ 44 async def listen_messages(url: str, is_json: bool, filename: Optional[str] = None) -> No │ │ 45 │ configure_console_recording(console, get_settings(), filename) │ │ 46 │ │ │ ❱ 47 │ async with websocket_client(url) as client: │ │ 48 │ │ while True: │ │ 49 │ │ │ message = await client.get_message() │ │ 50 │ │ │ is_bytes = isinstance(message, bytes) │ │ │ │ ╭──────────────── locals ────────────────╮ │ │ │ filename = None │ │ │ │ is_json = False │ │ │ │ url = 'ws://localhost:8000/hello' │ │ │ ╰────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/contextlib.py:199 in aenter │ │ │ │ 196 │ │ # they are only needed for recreation, which is not possible anymore │ │ 197 │ │ del self.args, self.kwds, self.func │ │ 198 │ │ try: │ │ ❱ 199 │ │ │ return await anext(self.gen) │ │ 200 │ │ except StopAsyncIteration: │ │ 201 │ │ │ raise RuntimeError("generator didn't yield") from None │ │ 202 │ │ │ │ ╭──────────────────────────────── locals ─────────────────────────────────╮ │ │ │ self = <contextlib._AsyncGeneratorContextManager object at 0x105ddc850> │ │ │ ╰─────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/ws/client.py:92 in websocket_client │ │ │ │ 89 │ ) │ │ 90 │ │ │ 91 │ try: │ │ ❱ 92 │ │ async with open_websocket_url(url, ssl_context=ssl_context, **arguments) as ws: │ │ 93 │ │ │ yield ws │ │ 94 │ except ConnectionTimeout: │ │ 95 │ │ console.print(f'[error]Unable to connect to {url}') │ │ │ │ ╭──────────────────── locals ────────────────────╮ │ │ │ arguments = { │ │ │ │ │ 'connect_timeout': 5.0, │ │ │ │ │ 'disconnect_timeout': 5.0, │ │ │ │ │ 'message_queue_size': 1, │ │ │ │ │ 'max_message_size': 1048576, │ │ │ │ │ 'extra_headers': None │ │ │ │ } │ │ │ │ settings = Settings( │ │ │ │ │ connect_timeout=5.0, │ │ │ │ │ disconnect_timeout=5.0, │ │ │ │ │ response_timeout=5.0, │ │ │ │ │ message_queue_size=1, │ │ │ │ │ max_message_size=1048576, │ │ │ │ │ extra_headers=None, │ │ │ │ │ terminal_width=180, │ │ │ │ │ tls_ca_file=None, │ │ │ │ │ tls_certificate_file=None, │ │ │ │ │ tls_key_file=None, │ │ │ │ │ tls_password=None │ │ │ │ ) │ │ │ │ ssl_context = None │ │ │ │ url = 'ws://localhost:8000/hello' │ │ │ ╰────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/contextlib.py:199 in aenter │ │ │ │ 196 │ │ # they are only needed for recreation, which is not possible anymore │ │ 197 │ │ del self.args, self.kwds, self.func │ │ 198 │ │ try: │ │ ❱ 199 │ │ │ return await anext(self.gen) │ │ 200 │ │ except StopAsyncIteration: │ │ 201 │ │ │ raise RuntimeError("generator didn't yield") from None │ │ 202 │ │ │ │ ╭──────────────────────────────── locals ─────────────────────────────────╮ │ │ │ self = <contextlib._AsyncGeneratorContextManager object at 0x105ddc8b0> │ │ │ ╰─────────────────────────────────────────────────────────────────────────╯ │ │ │ │ /Users/sangshuduo/anaconda3/lib/python3.10/site-packages/trio_websocket/_impl.py:128 in │ │ open_websocket │ │ │ │ 125 │ │ except trio.TooSlowError: │ │ 126 │ │ │ raise ConnectionTimeout from None │ │ 127 │ │ except OSError as e: │ │ ❱ 128 │ │ │ raise HandshakeError from e │ │ 129 │ │ try: │ │ 130 │ │ │ yield connection │ │ 131 │ │ finally: │ │ │ │ ╭───────────────────────── locals ──────────────────────────╮ │ │ │ connect_timeout = 5.0 │ │ │ │ disconnect_timeout = 5.0 │ │ │ │ extra_headers = None │ │ │ │ host = 'localhost' │ │ │ │ max_message_size = 1048576 │ │ │ │ message_queue_size = 1 │ │ │ │ new_nursery = <trio.Nursery object at 0x105ddcbb0> │ │ │ │ port = 8000 │ │ │ │ resource = '/hello' │ │ │ │ subprotocols = None │ │ │ │ use_ssl = False │ │ │ ╰───────────────────────────────────────────────────────────╯ │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ HandshakeError`

sangshuduo avatar Jan 24 '24 03:01 sangshuduo

Hello, First of all, are you sure your server was started before the client run? Did you try to upgrade the websocket version to the latest one?

lewoudar avatar Jan 24 '24 06:01 lewoudar

Maybe I confuse the difference between echo-server and listen command. Since I can't see any response from echo-server when I send a text to the echo-server. However, even when I ran echo-server first, then run ws listen it still exit with ConnectionClosed error. Could you please introduce a typical scenario of how to set up a server can respond explicitly to the screen after receiving the text from a client? Thanks.

sangshuduo avatar Jan 24 '24 17:01 sangshuduo