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

1# SPDX-FileCopyrightText: Christian Amsüss and the aiocoap contributors 

2# 

3# SPDX-License-Identifier: MIT 

4 

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. 

12 

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. 

16 

17.. _websockets: https://websockets.readthedocs.io/ 

18.. _pyodide: https://pyodide.org/ 

19""" 

20 

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 

24 

25 

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 

31 

32 if ssl is not None: 

33 raise ValueError("SSL can not be configured within the browser WebSocket API") 

34 

35 socket = WebSocket.new(uri, subprotocols) 

36 

37 # Ignoring ping_interval: We can't tell what the browser does, and it may 

38 # be right nor not. 

39 

40 proto = asyncio.client.ClientConnection(socket) 

41 

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 

52 

53 return proto