Hendrik Langer
2 years ago
6 changed files with 151 additions and 17 deletions
@ -0,0 +1,27 @@ |
|||||
|
<script type="text/javascript"> |
||||
|
const ws = new WebSocket(`ws://${location.host}/ws`); |
||||
|
|
||||
|
ws.addEventListener('message', function (event) { |
||||
|
const li = document.createElement("li"); |
||||
|
li.appendChild(document.createTextNode(event.data)); |
||||
|
document.getElementById("messages").appendChild(li); |
||||
|
}); |
||||
|
|
||||
|
function send(event) { |
||||
|
const message = (new FormData(event.target)).get("message"); |
||||
|
if (message) { |
||||
|
ws.send(message); |
||||
|
} |
||||
|
event.target.reset(); |
||||
|
return false; |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<div style="display: flex; height: 100%; flex-direction: column"> |
||||
|
<ul id="messages" style="flex-grow: 1; list-style-type: none"></ul> |
||||
|
|
||||
|
<form onsubmit="return send(event)"> |
||||
|
<input type="text" name="message" minlength="1" /> |
||||
|
<button type="submit">Send</button> |
||||
|
</form> |
||||
|
</div> |
@ -0,0 +1,64 @@ |
|||||
|
import asyncio |
||||
|
from typing import AsyncGenerator |
||||
|
from quart import Quart, render_template, websocket |
||||
|
import logging |
||||
|
|
||||
|
logger = logging.getLogger(__name__) |
||||
|
|
||||
|
|
||||
|
app = Quart(__name__) |
||||
|
connections = set() |
||||
|
|
||||
|
@app.route("/") |
||||
|
async def index(): |
||||
|
return await render_template("index.html") |
||||
|
|
||||
|
@app.route("/api") |
||||
|
async def json(): |
||||
|
return {"hello": "world"} |
||||
|
|
||||
|
|
||||
|
async def _send() -> None: |
||||
|
connection = asyncio.Queue() |
||||
|
connections.add(connection) |
||||
|
|
||||
|
try: |
||||
|
while True: |
||||
|
message = await connection.get() |
||||
|
await websocket.send(message) |
||||
|
finally: |
||||
|
connections.remove(connection) |
||||
|
|
||||
|
async def _receive() -> None: |
||||
|
while True: |
||||
|
message = await websocket.receive() |
||||
|
for connection in connections: |
||||
|
await connection.put(message) |
||||
|
|
||||
|
@app.websocket("/ws") |
||||
|
async def ws() -> None: |
||||
|
producer = asyncio.create_task(_send()) |
||||
|
consumer = asyncio.create_task(_receive()) |
||||
|
await asyncio.gather(producer, consumer) |
||||
|
|
||||
|
#await websocket.send_json({"hello": "world"}) |
||||
|
|
||||
|
|
||||
|
|
||||
|
class WebUI(object): |
||||
|
"""The Web interface.""" |
||||
|
|
||||
|
def __init__(self): |
||||
|
self.shutdown_event = asyncio.Event() |
||||
|
self.task = None |
||||
|
app.config["PROPAGATE_EXCEPTIONS"] = True |
||||
|
pass |
||||
|
|
||||
|
def run_task(self): |
||||
|
return app.run_task(port=5000, debug=True, shutdown_trigger=self.shutdown_event.wait) |
||||
|
|
||||
|
async def stop(self): |
||||
|
self.shutdown_event.set() |
||||
|
self.task.cancel() # or close? |
||||
|
|
||||
|
|
Loading…
Reference in new issue