Jelajahi Sumber

Example: Add zeromq example (#2941)

* Example: Add zeromq example

This change adds a basic zeromq implementation with nicegui.

In order to do this, the zmq python library is used to create a publisher and a subscriber. The main interesting aspect is that the zmq.async library is used to create a subscriber that can be used in an asyncio loop, which is necessary to run the NiceGUI server.

* code review

* fix end of file

---------

Co-authored-by: Falko Schindler <falko@zauberzeug.com>
Keenan Johnson 1 tahun lalu
induk
melakukan
64b9f40b44

+ 37 - 0
examples/zeromq/README.md

@@ -0,0 +1,37 @@
+# Zeromq Example
+
+This example is a basic Zeromq implementation with NiceGUI.
+It shows how to stream data from a ZeroMQ socket to a NiceGUI plot.
+
+In order to do this, the zmq Python library is used to create a publisher and a subscriber.
+The main interesting aspect is that the zmq.async library is used to create a subscriber that can be used in an asyncio loop, which is necessary to run the NiceGUI server.
+
+## Running the example
+
+There are two components to this example: the publisher and the NiceGUI server.
+
+In addition to the normal NiceGUI dependencies, the zmq library must be installed (see requirements.txt).
+
+### Running the publisher
+
+The publisher is a simple Python script that sends random data to a ZeroMQ socket.
+To run it, simply execute the following command:
+
+```bash
+python zmq-server.py
+```
+
+### Running the NiceGUI server
+
+The NiceGUI server is a Python script that creates a plot and updates it with data from the ZeroMQ socket.
+To run it, execute the following command:
+
+```bash
+python main.py
+```
+
+### Results
+
+Once both the publisher and GUI server are running, you will see an updating plot on the UI.
+
+![plot](images/plot.png)

TEMPAT SAMPAH
examples/zeromq/images/plot.png


+ 30 - 0
examples/zeromq/main.py

@@ -0,0 +1,30 @@
+#!/usr/bin/env python3
+from datetime import datetime
+
+import zmq
+import zmq.asyncio
+
+from nicegui import app, ui
+
+context = zmq.asyncio.Context()
+socket = context.socket(zmq.PULL)
+socket.connect('tcp://localhost:5555')
+
+poller = zmq.asyncio.Poller()
+poller.register(socket, zmq.POLLIN)
+
+
+async def read_loop() -> None:
+    while not app.is_stopped:
+        events = await poller.poll()
+        if socket in dict(events):
+            data = await socket.recv()
+            number = float(data)
+            print(f'Received number {number}')
+            line_plot.push([datetime.now()], [[number]])
+
+line_plot = ui.line_plot(n=1, limit=100, figsize=(10, 4))
+
+app.on_startup(read_loop)
+
+ui.run()

+ 1 - 0
examples/zeromq/requirements.txt

@@ -0,0 +1 @@
+pyzmq >= 26.0

+ 21 - 0
examples/zeromq/zmq-server.py

@@ -0,0 +1,21 @@
+#!/usr/bin/env python3
+import asyncio
+import random
+
+import zmq
+import zmq.asyncio
+
+context = zmq.asyncio.Context()
+socket = context.socket(zmq.PUSH)
+socket.bind('tcp://localhost:5555')
+
+
+async def send_loop():
+    while True:
+        number = random.randint(0, 100)
+        print(f'Sending number {number}')
+        await socket.send(str(number).encode('ascii'))
+        await asyncio.sleep(0.1)
+
+
+asyncio.run(send_loop())

+ 1 - 0
website/examples.py

@@ -65,4 +65,5 @@ examples: List[Example] = [
     Example('Webserial', 'communicate with a serial device using the WebSerial API'),
     Example('Websockets', 'use [websockets library](https://websockets.readthedocs.io/) to start a websocket server'),
     Example('Audio Recorder', 'Record audio, play it back or download it'),
+    Example('ZeroMQ', 'Simple ZeroMQ PUSH/PULL server and client'),
 ]