mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-27 09:33:55 +08:00
update:为 test 页面增加可配置的本地唤醒词运行时
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
import json
|
||||
import queue
|
||||
from http import HTTPStatus
|
||||
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
|
||||
from pathlib import Path
|
||||
|
||||
from ..bridge import WakewordEventBridge
|
||||
|
||||
|
||||
class TestRuntimeHttpServer:
|
||||
def __init__(self, test_root: Path, host: str = "0.0.0.0", port: int = 8006) -> None:
|
||||
self.test_root = test_root
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.event_bridge = WakewordEventBridge()
|
||||
self._server = self._build_server()
|
||||
|
||||
@property
|
||||
def page_url(self) -> str:
|
||||
return f"http://127.0.0.1:{self.port}/test_page.html"
|
||||
|
||||
@property
|
||||
def events_url(self) -> str:
|
||||
return f"http://127.0.0.1:{self.port}/events"
|
||||
|
||||
def serve_forever(self) -> None:
|
||||
self._server.serve_forever()
|
||||
|
||||
def shutdown(self) -> None:
|
||||
self._server.shutdown()
|
||||
self.event_bridge.close()
|
||||
self._server.server_close()
|
||||
|
||||
def _build_server(self) -> ThreadingHTTPServer:
|
||||
test_root = self.test_root
|
||||
event_bridge = self.event_bridge
|
||||
|
||||
class TestRuntimeHandler(SimpleHTTPRequestHandler):
|
||||
protocol_version = "HTTP/1.1"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, directory=str(test_root), **kwargs)
|
||||
|
||||
def handle(self) -> None:
|
||||
try:
|
||||
super().handle()
|
||||
except (BrokenPipeError, ConnectionResetError, ConnectionAbortedError):
|
||||
pass
|
||||
|
||||
def do_GET(self) -> None:
|
||||
if self.path == "/events":
|
||||
self._handle_events(event_bridge)
|
||||
return
|
||||
|
||||
if self.path == "/health":
|
||||
body = json.dumps({"status": "ok"}).encode("utf-8")
|
||||
self.send_response(HTTPStatus.OK)
|
||||
self.send_header("Content-Type", "application/json; charset=utf-8")
|
||||
self.send_header("Cache-Control", "no-cache")
|
||||
self.send_header("Content-Length", str(len(body)))
|
||||
self.end_headers()
|
||||
self.wfile.write(body)
|
||||
return
|
||||
|
||||
super().do_GET()
|
||||
|
||||
def log_message(self, format: str, *args) -> None:
|
||||
return
|
||||
|
||||
def _handle_events(self, bridge: WakewordEventBridge) -> None:
|
||||
client_queue = bridge.add_client()
|
||||
self.send_response(HTTPStatus.OK)
|
||||
self.send_header("Content-Type", "text/event-stream; charset=utf-8")
|
||||
self.send_header("Cache-Control", "no-cache")
|
||||
self.send_header("Connection", "keep-alive")
|
||||
self.send_header("X-Accel-Buffering", "no")
|
||||
self.end_headers()
|
||||
|
||||
try:
|
||||
ready_message = bridge.build_ready_message()
|
||||
self.wfile.write(f"data: {ready_message}\n\n".encode("utf-8"))
|
||||
self.wfile.flush()
|
||||
|
||||
while bridge.is_running:
|
||||
try:
|
||||
message = client_queue.get(timeout=15)
|
||||
if message == "__bridge_closed__":
|
||||
break
|
||||
self.wfile.write(f"data: {message}\n\n".encode("utf-8"))
|
||||
except queue.Empty:
|
||||
if not bridge.is_running:
|
||||
break
|
||||
self.wfile.write(b": keepalive\n\n")
|
||||
self.wfile.flush()
|
||||
except (BrokenPipeError, ConnectionResetError, ConnectionAbortedError):
|
||||
pass
|
||||
finally:
|
||||
bridge.remove_client(client_queue)
|
||||
|
||||
server = ThreadingHTTPServer((self.host, self.port), TestRuntimeHandler)
|
||||
server.daemon_threads = True
|
||||
return server
|
||||
Reference in New Issue
Block a user