Spaces:
Runtime error
Runtime error
| import React, { useEffect, useRef, useState } from "react"; | |
| export default function App() { | |
| const canvasRef = useRef(null); | |
| const wsRef = useRef(null); | |
| const [connected, setConnected] = useState(false); | |
| const [playerPos, setPlayerPos] = useState([50, 50]); | |
| const [status, setStatus] = useState("Disconnected"); | |
| useEffect(() => { | |
| // Connect to backend WebSocket. When deploying to HF Spaces, | |
| // use the absolute URL or relative path ("/ws"). | |
| const proto = window.location.protocol === "https:" ? "wss" : "ws"; | |
| const host = window.location.host; // same host as Space | |
| const wsUrl = `${proto}://${host}/ws`; | |
| const ws = new WebSocket(wsUrl); | |
| wsRef.current = ws; | |
| ws.addEventListener("open", () => { | |
| setConnected(true); | |
| setStatus("Connected"); | |
| // ask for initial frame | |
| ws.send(JSON.stringify({ type: "noop" })); | |
| }); | |
| ws.addEventListener("message", (ev) => { | |
| const msg = JSON.parse(ev.data); | |
| if (msg.type === "frame") { | |
| drawFrame(msg.image_b64); | |
| if (Array.isArray(msg.player_pos)) setPlayerPos(msg.player_pos); | |
| } else if (msg.type === "status") { | |
| setStatus(msg.text); | |
| } | |
| }); | |
| ws.addEventListener("close", () => { | |
| setConnected(false); | |
| setStatus("Disconnected"); | |
| }); | |
| return () => { | |
| ws.close(); | |
| }; | |
| }, []); | |
| // draw base64 png on canvas | |
| function drawFrame(image_b64) { | |
| const canvas = canvasRef.current; | |
| if (!canvas) return; | |
| const ctx = canvas.getContext("2d"); | |
| const img = new Image(); | |
| img.onload = () => { | |
| ctx.clearRect(0, 0, canvas.width, canvas.height); | |
| ctx.drawImage(img, 0, 0, canvas.width, canvas.height); | |
| }; | |
| img.src = `data:image/png;base64,${image_b64}`; | |
| } | |
| // send action down the websocket | |
| function sendAction(action) { | |
| if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) return; | |
| wsRef.current.send(JSON.stringify({ type: "action", action })); | |
| } | |
| } |