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