robotics-visual-lab / ws_bridge.py
askuric's picture
askuric HF Staff
should be working
ac54616
# WebSocket bridge: browser <-> bridge (:8765) <-> MeshCat WS (:7000)
# Compatible with websockets >= 11 (incl. 15.0.1). One-arg handler.
import asyncio
import logging
import websockets
UPSTREAM = "ws://127.0.0.1:7000/"
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
async def pump(src, dst, label):
try:
async for msg in src:
await dst.send(msg)
except websockets.ConnectionClosedOK:
logging.info("%s closed cleanly", label)
except websockets.ConnectionClosed as e:
logging.info("%s closed: code=%s reason=%s", label, e.code, e.reason)
except Exception:
logging.exception("%s error", label)
async def handler(client_ws):
# Connect to MeshCat’s WS; disable compression to avoid deflate quirks
async with websockets.connect(
UPSTREAM,
ping_interval=20,
ping_timeout=20,
max_size=None,
compression=None,
) as upstream_ws:
logging.info("Bridge connected: client <-> %s", UPSTREAM)
# bidirectional forwarding
c2u = asyncio.create_task(pump(client_ws, upstream_ws, "client->upstream"))
u2c = asyncio.create_task(pump(upstream_ws, client_ws, "upstream->client"))
done, pending = await asyncio.wait({c2u, u2c}, return_when=asyncio.FIRST_COMPLETED)
for t in pending:
t.cancel()
async def main():
async with websockets.serve(
handler,
"127.0.0.1",
8765,
ping_interval=20,
ping_timeout=20,
max_size=None,
compression=None,
):
logging.info("WS bridge listening on ws://127.0.0.1:8765/")
await asyncio.Future() # run forever
if __name__ == "__main__":
asyncio.run(main())