Coverage for src/aiocoap/util/pyodide_websockets/__init__.py: 0%
17 statements
« prev ^ index » next coverage.py v7.7.0, created at 2025-03-20 17:26 +0000
« prev ^ index » next coverage.py v7.7.0, created at 2025-03-20 17:26 +0000
1# SPDX-FileCopyrightText: Christian Amsüss and the aiocoap contributors
2#
3# SPDX-License-Identifier: MIT
5"""This module provides a slimmed-down replacement of the websockets_ module
6(that regularly powers :mod:`aiocoap.transports.ws`) -- but implemented through
7pyodide_'s JavaScript adapter towards the WebSocket module of the hosting
8browser. It aims to be a drop-in replacement that provides the parts that can
9be implemented in the browser, and to provide practical errors on the used
10entry points. It will not go out of its way to mimick every aspect of the
11websockets module, but restrain itself to what ``.ws`` needs.
13**Future developement:** The module can probably be extended to cover all the
14implementable functionality of websockets, and provide meaningful errors on all
15its items. When that happens, it should be split out of aiocoap.
17.. _websockets: https://websockets.readthedocs.io/
18.. _pyodide: https://pyodide.org/
19"""
21# Re-exporting because aiocoap.transports.ws otherwise has a hard time getting
22# the import right
23from . import asyncio as asyncio, exceptions as exceptions
26async def connect(
27 uri, subprotocols=None, ping_interval=20, ssl=None
28) -> asyncio.connection.Connection:
29 from pyodide.ffi.wrappers import add_event_listener
30 from js import WebSocket
32 if ssl is not None:
33 raise ValueError("SSL can not be configured within the browser WebSocket API")
35 socket = WebSocket.new(uri, subprotocols)
37 # Ignoring ping_interval: We can't tell what the browser does, and it may
38 # be right nor not.
40 proto = asyncio.client.ClientConnection(socket)
42 add_event_listener(
43 socket, "open", lambda e, q=proto._queue: q.put_nowait(("open", e))
44 )
45 add_event_listener(socket, "message", proto.on_message)
46 add_event_listener(socket, "error", proto.on_error)
47 add_event_listener(socket, "close", proto.on_close)
48 (etype, event) = await proto._queue.get()
49 if etype != "open":
50 raise exceptions.WebSocketException("Failed to connect")
51 proto.open = True
53 return proto