pythonasyncioeventletgeventlong-pollinglow-latencysocket-iosocketiosocketio-serverweb-serverwebsocket
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
63 lines
1.8 KiB
63 lines
1.8 KiB
import threading
|
|
import time
|
|
|
|
import requests
|
|
import uvicorn
|
|
|
|
import socketio
|
|
|
|
|
|
class SocketIOWebServer:
|
|
"""A simple web server used for running Socket.IO servers in tests.
|
|
|
|
:param sio: a Socket.IO server instance.
|
|
|
|
Note 1: This class is not production-ready and is intended for testing.
|
|
Note 2: This class only supports the "asgi" async_mode.
|
|
"""
|
|
|
|
def __init__(self, sio, on_shutdown=None):
|
|
if sio.async_mode != "asgi":
|
|
raise ValueError('The async_mode must be "asgi"')
|
|
|
|
async def http_app(scope, receive, send):
|
|
await send(
|
|
{
|
|
"type": "http.response.start",
|
|
"status": 200,
|
|
"headers": [("Content-Type", "text/plain")],
|
|
}
|
|
)
|
|
await send({"type": "http.response.body", "body": b"OK"})
|
|
|
|
self.sio = sio
|
|
self.app = socketio.ASGIApp(sio, http_app, on_shutdown=on_shutdown)
|
|
self.httpd = None
|
|
self.thread = None
|
|
|
|
def start(self, port=8900):
|
|
"""Start the web server.
|
|
|
|
:param port: the port to listen on. Defaults to 8900.
|
|
|
|
The server is started in a background thread.
|
|
"""
|
|
self.httpd = uvicorn.Server(config=uvicorn.Config(self.app, port=port))
|
|
self.thread = threading.Thread(target=self.httpd.run)
|
|
self.thread.start()
|
|
|
|
# wait for the server to start
|
|
while True:
|
|
try:
|
|
r = requests.get(f"http://localhost:{port}/")
|
|
r.raise_for_status()
|
|
if r.text == "OK":
|
|
break
|
|
except:
|
|
time.sleep(0.1)
|
|
|
|
def stop(self):
|
|
"""Stop the web server."""
|
|
self.httpd.should_exit = True
|
|
self.thread.join()
|
|
self.thread = None
|
|
|