mirror of
https://github.com/zimplexing/OrionTV.git
synced 2026-02-04 03:36:29 +08:00
147 lines
5.1 KiB
TypeScript
147 lines
5.1 KiB
TypeScript
import TCPHttpServer from './tcpHttpServer';
|
|
|
|
const getRemotePageHTML = () => {
|
|
return `
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>OrionTV Remote</title>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
|
<style>
|
|
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; margin: 0; background-color: #121212; color: white; }
|
|
h3 { color: #eee; }
|
|
#container { display: flex; flex-direction: column; align-items: center; width: 90%; max-width: 400px; }
|
|
#text { width: 100%; padding: 15px; font-size: 16px; border-radius: 8px; border: 1px solid #333; background-color: #2a2a2a; color: white; margin-bottom: 20px; box-sizing: border-box; }
|
|
button { width: 100%; padding: 15px; font-size: 18px; font-weight: bold; border: none; border-radius: 8px; background-color: #007AFF; color: white; cursor: pointer; }
|
|
button:active { background-color: #0056b3; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="container">
|
|
<h3>Send a message to TV</h3>
|
|
<input id="text" placeholder="Type here..." />
|
|
<button onclick="send()">Send</button>
|
|
</div>
|
|
<script>
|
|
window.addEventListener('DOMContentLoaded', () => {
|
|
fetch('/handshake', { method: 'POST' }).catch(console.error);
|
|
});
|
|
function send() {
|
|
const input = document.getElementById("text");
|
|
const value = input.value;
|
|
if (value) {
|
|
fetch("/message", {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ message: value })
|
|
})
|
|
.catch(err => console.error(err));
|
|
input.value = '';
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|
|
`;
|
|
};
|
|
|
|
class RemoteControlService {
|
|
private httpServer: TCPHttpServer;
|
|
private onMessage: (message: string) => void = () => {};
|
|
private onHandshake: () => void = () => {};
|
|
|
|
constructor() {
|
|
this.httpServer = new TCPHttpServer();
|
|
this.setupRequestHandler();
|
|
}
|
|
|
|
private setupRequestHandler() {
|
|
this.httpServer.setRequestHandler((request) => {
|
|
console.log('[RemoteControl] Received request:', request.method, request.url);
|
|
|
|
try {
|
|
if (request.method === 'GET' && request.url === '/') {
|
|
return {
|
|
statusCode: 200,
|
|
headers: { 'Content-Type': 'text/html' },
|
|
body: getRemotePageHTML()
|
|
};
|
|
} else if (request.method === 'POST' && request.url === '/message') {
|
|
try {
|
|
const parsedBody = JSON.parse(request.body || '{}');
|
|
const message = parsedBody.message;
|
|
if (message) {
|
|
this.onMessage(message);
|
|
}
|
|
return {
|
|
statusCode: 200,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ status: 'ok' })
|
|
};
|
|
} catch (parseError) {
|
|
console.error('[RemoteControl] Failed to parse message body:', parseError);
|
|
return {
|
|
statusCode: 400,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ error: 'Invalid JSON' })
|
|
};
|
|
}
|
|
} else if (request.method === 'POST' && request.url === '/handshake') {
|
|
this.onHandshake();
|
|
return {
|
|
statusCode: 200,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ status: 'ok' })
|
|
};
|
|
} else {
|
|
return {
|
|
statusCode: 404,
|
|
headers: { 'Content-Type': 'text/plain' },
|
|
body: 'Not Found'
|
|
};
|
|
}
|
|
} catch (error) {
|
|
console.error('[RemoteControl] Request handler error:', error);
|
|
return {
|
|
statusCode: 500,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ error: 'Internal Server Error' })
|
|
};
|
|
}
|
|
});
|
|
}
|
|
|
|
public init(actions: { onMessage: (message: string) => void; onHandshake: () => void }) {
|
|
this.onMessage = actions.onMessage;
|
|
this.onHandshake = actions.onHandshake;
|
|
}
|
|
|
|
public async startServer(): Promise<string> {
|
|
console.log('[RemoteControl] Attempting to start server...');
|
|
|
|
if (this.httpServer.getIsRunning()) {
|
|
console.log('[RemoteControl] Server is already running.');
|
|
throw new Error('Server is already running.');
|
|
}
|
|
|
|
try {
|
|
const url = await this.httpServer.start();
|
|
console.log(`[RemoteControl] Server started successfully at: ${url}`);
|
|
return url;
|
|
} catch (error) {
|
|
console.error('[RemoteControl] Failed to start server:', error);
|
|
throw new Error(error instanceof Error ? error.message : 'Failed to start server');
|
|
}
|
|
}
|
|
|
|
public stopServer() {
|
|
console.log('[RemoteControl] Stopping server...');
|
|
this.httpServer.stop();
|
|
}
|
|
|
|
public isRunning(): boolean {
|
|
return this.httpServer.getIsRunning();
|
|
}
|
|
}
|
|
|
|
export const remoteControlService = new RemoteControlService(); |