Reputation: 11
I'm building a drone control interface using React and TypeScript with socket.io-client to communicate with a Tello drone. When I initialize the TelloSocketClient
class (which wraps the socket connection), the browser shows a blank white screen. However, if I skip initializing the client, the pages (Connect and ControlPanel) render correctly.
Github Repo here -> Tello Web Command Panel
App.tsx
(Root component managing connection state):// ... imports ...
function App() {
const [isConnected, setIsConnected] = useState(false);
const telloClient = new TelloSocketClient("http://localhost:5001", ["websocket"]);
return (
<>
{isConnected ? (
<ControlPanel tello={telloClient}/>
) : (
<Connect onConnect={() => {
telloClient.connect();
setIsConnected(telloClient.socket.connected)
}}/>
)
}
</>
)
}
TelloSocketClient.ts
(Socket client class):import {io, Socket} from "socket.io-client";
import winstonLogger from "@/services/Logger.ts";
const logger = winstonLogger({logName: "TelloSocketClient", level: "debug"});
interface ServerToClientEvents {
noArg: () => void;
basicEmit: (a: number, b: string, c: Buffer) => void;
withAck: (d: string, callback: (e: number) => void) => void;
connection_status: (payload: string) => void;
move_status: (payload: string) => void;
rotate_status: (payload: string) => void;
flip_status: (payload: string) => void;
state_update: (payload: string) => void;
}
interface ClientToServerEvents {
hello: () => void;
}
interface ServerMessage {
status: string;
message: string;
}
type Transport = "polling" | "websocket" | "webtransport";
type ValidMoves = "up" | "down" | "left" | "right" | "forward" | "back";
type ValidRotations = "cw" | "ccw";
type ValidFlips = "left" | "right" | "forward" | "backward";
class TelloSocketClient {
readonly socket: Socket<ServerToClientEvents, ClientToServerEvents>;
constructor(domain: string, transport: Transport[]) {
this.socket = io(domain, {
autoConnect: false,
transports: transport,
reconnection: true,
withCredentials: true,
timeout: 5000,
});
}
@logMethodOperations
public connect() {
this.socket.connect();
}
@logMethodOperations
public disconnect() {
this.socket.disconnect();
}
@logMethodOperations
public move(direction: ValidMoves) {
this.socket.send("move", direction);
}
// Other methods
private registerEventHandler(event: keyof ServerToClientEvents, callback?: (message: ServerMessage) => void) {
this.socket.on(event, (payload: string) => {
const message = this.parseMessageFromServer(payload);
logger.info(`Received message from ${event}: ${JSON.stringify(message)}`);
if (message.status === "error") {
logger.error(`Error: ${message.message}`);
} else {
logger.info(`Success: ${message.message}`);
}
if (callback) {
callback(message);
}
});
}
// Other methods
}
function logMethodOperations(originalMethod: any, context: ClassMethodDecoratorContext) {
const methodName = String(context.name);
function wrapper(this: any, ...args: any[]) {
logger.info(`Entering method '${methodName}'.`);
const result = originalMethod.call(this, ...args);
logger.info(`Exiting method '${methodName}'.`);
return result;
}
return wrapper;
}
export default TelloSocketClient;
Connect Page
and Control interface
On clicking "Connect" in the Connect component, the app should switch to the ControlPanel with a live connection to the drone.Pages work as expected if the client is not initialized (e.g., commenting out tello.connect()).
Upvotes: 0
Views: 11