Coverage for src/aiocoap/util/pyodide_websockets/asyncio/client.py: 0%

32 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 

5import asyncio 

6from .connection import Connection 

7from .. import exceptions 

8 

9 

10class ClientConnection(Connection): 

11 def __init__(self, socket): 

12 # Note that this is an under-implemented constructor -- the real thing 

13 # is in `connect()` which is async enough to do more. 

14 

15 self._socket = socket 

16 # FIXME: This is a workaround for WebSockets' shortcomings, while 

17 # WebSocketStreams are not deployed (see 

18 # https://developer.chrome.com/articles/websocketstream/ for details) 

19 

20 self._queue = asyncio.Queue() 

21 

22 # The initial setting doesn't matter too much because we're not handing 

23 # it out before setting this to True ... still feels cleaner this way. 

24 self.open = False 

25 

26 async def recv(self): 

27 (etype, event) = await self._queue.get() 

28 if etype == "message": 

29 if isinstance(event.data, str): 

30 # FIXME: Test this 

31 return event.data 

32 return bytes((await event.data.arrayBuffer()).to_py()) 

33 elif etype == "close": 

34 raise exceptions.ConnectionClosed() 

35 elif etype == "error": 

36 raise exceptions.WebSocketException("Connection error") 

37 else: 

38 raise RuntimeError("Unknown event in queue") 

39 

40 async def send(self, msg): 

41 from js import Blob, Uint8Array 

42 

43 blob = Blob.new([Uint8Array.new(msg)]) 

44 self._socket.send(blob) 

45 

46 # FIXME: It'd be preferable if we could make this an unassigned property 

47 # that'd raise if anybody tried to access it (for neither do we know the 

48 # value, nor could anything useful be done with it), but as things are, 

49 # we'll have to rely on all users' sensibilities to not send around 

50 # addresses that are not globally usable. (The port, indicating the default 

51 # port, is an outright lie, though.) 

52 local_address = ("localhost", None) 

53 

54 def on_message(self, event): 

55 self._queue.put_nowait(("message", event)) 

56 

57 def on_error(self, event): 

58 self.open = False 

59 self._queue.put_nowait(("error", event)) 

60 

61 def on_close(self, event): 

62 self.open = False 

63 self._queue.put_nowait(("close", event))