Skip to content

Commit b8a3561

Browse files
committed
Modified Websocket example to use asyncio
1 parent ed41a3f commit b8a3561

File tree

3 files changed

+43
-19
lines changed

3 files changed

+43
-19
lines changed

docs/examples.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,12 +315,15 @@ the client and the server.
315315
Remember, that because Websockets also receive data, you have to explicitly call ``.receive()`` on the ``Websocket`` object to get the message.
316316
This is anologous to calling ``.poll()`` on the ``Server`` object.
317317

318+
The following example uses ``asyncio``, which has to be installed separately. It is not necessary to use ``asyncio`` to use Websockets,
319+
but it is recommended as it makes it easier to handle multiple tasks. It can be used in any of the examples, but here it is particularly useful.
320+
318321
**Because of the limited number of concurrently open sockets, it is not possible to process more than one Websocket response at the same time.
319322
This might change in the future, but for now, it is recommended to use Websocket only with one client at a time.**
320323

321324
.. literalinclude:: ../examples/httpserver_websocket.py
322325
:caption: examples/httpserver_websocket.py
323-
:emphasize-lines: 12,21,67-73,83,90
326+
:emphasize-lines: 12,20,65-72,88,99
324327
:linenos:
325328

326329
Multiple servers

examples/httpserver_sse.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# SPDX-FileCopyrightText: 2023 Dan Halbert for Adafruit Industries
1+
# SPDX-FileCopyrightText: 2023 Michał Pokusa
22
#
33
# SPDX-License-Identifier: Unlicense
44

examples/httpserver_websocket.py

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# SPDX-FileCopyrightText: 2023 Dan Halbert for Adafruit Industries
1+
# SPDX-FileCopyrightText: 2023 Michał Pokusa
22
#
33
# SPDX-License-Identifier: Unlicense
44

5-
from time import monotonic
5+
from asyncio import create_task, gather, run, sleep as async_sleep
66
import board
77
import microcontroller
88
import neopixel
@@ -17,9 +17,7 @@
1717

1818
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1)
1919

20-
2120
websocket: Websocket = None
22-
next_message_time = monotonic()
2321

2422
HTML_TEMPLATE = """
2523
<html lang="en">
@@ -75,17 +73,40 @@ def connect_client(request: Request):
7573

7674

7775
server.start(str(wifi.radio.ipv4_address))
78-
while True:
79-
server.poll()
8076

81-
# Check for incoming messages from client
82-
if websocket is not None:
83-
if (data := websocket.receive(True)) is not None:
84-
r, g, b = int(data[1:3], 16), int(data[3:5], 16), int(data[5:7], 16)
85-
pixel.fill((r, g, b))
86-
87-
# Send a message every second
88-
if websocket is not None and next_message_time < monotonic():
89-
cpu_temp = round(microcontroller.cpu.temperature, 2)
90-
websocket.send_message(str(cpu_temp))
91-
next_message_time = monotonic() + 1
77+
78+
async def handle_http_requests():
79+
while True:
80+
server.poll()
81+
82+
await async_sleep(0)
83+
84+
85+
async def handle_websocket_requests():
86+
while True:
87+
if websocket is not None:
88+
if (data := websocket.receive(fail_silently=True)) is not None:
89+
r, g, b = int(data[1:3], 16), int(data[3:5], 16), int(data[5:7], 16)
90+
pixel.fill((r, g, b))
91+
92+
await async_sleep(0)
93+
94+
95+
async def send_websocket_messages():
96+
while True:
97+
if websocket is not None:
98+
cpu_temp = round(microcontroller.cpu.temperature, 2)
99+
websocket.send_message(str(cpu_temp), fail_silently=True)
100+
101+
await async_sleep(1)
102+
103+
104+
async def main():
105+
await gather(
106+
create_task(handle_http_requests()),
107+
create_task(handle_websocket_requests()),
108+
create_task(send_websocket_messages()),
109+
)
110+
111+
112+
run(main())

0 commit comments

Comments
 (0)