placemenext / temp.js
GitHub Actions
Initial commit
1d45897
const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const path = require('path');
const app = express();
const port = 8080;
// Serve static files (if any)
app.use(express.static('public'));
// Data structures to store client data
const clients = {};
// HTTP server
const server = http.createServer(app);
// WebSocket server
const wss = new WebSocket.Server({ server });
// Handle new WebSocket connections
wss.on('connection', (ws) => {
let clientId = null;
ws.on('message', (message) => {
try {
const data = JSON.parse(message);
if (!clientId && data.clientId) {
clientId = data.clientId;
clients[clientId] = {
ws: ws,
html: '',
css: '',
url: ''
};
console.log(`Client ${clientId} connected`);
}
if (data.type === 'pageContent') {
clients[clientId].html = data.html;
clients[clientId].css = data.css;
clients[clientId].url = data.url;
} else if (data.type === 'keyboardEvent') {
// Relay the keyboard event to other clients
relayKeyboardEvent(data, clientId);
}
} catch (e) {
console.error('Error parsing message:', e);
}
});
ws.on('close', () => {
console.log(`Client ${clientId} disconnected`);
delete clients[clientId];
});
});
// Function to relay keyboard events to other clients
function relayKeyboardEvent(data, senderId) {
// Send the keyboard event to all connected clients except the sender
for (const [id, client] of Object.entries(clients)) {
if (id !== senderId) {
client.ws.send(JSON.stringify(data));
}
}
}
// Route to list all active clients
app.get('/clients', (req, res) => {
res.json(Object.keys(clients));
});
// Route to render the client's page
app.get('/client/:id', (req, res) => {
const client = clients[req.params.id];
if (client) {
let htmlContent = client.html;
// Inject the CSS into a style tag in the head
const cssTag = `<style>${client.css}</style>`;
htmlContent = htmlContent.replace('</head>', `${cssTag}</head>`);
// Inject the script to establish WebSocket connection
const scriptTag = `
<script>
(function() {
const socket = new WebSocket('ws://' + location.host);
const clientId = '${req.params.id}-page';
socket.addEventListener('open', () => {
console.log('WebSocket connection opened from rendered page');
});
socket.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
// Ignore messages originating from this client
if (data.clientId === clientId) return;
if (data.type === 'keyboardEvent') {
simulateKeyboardEvent(data.event);
}
});
// Send keyboard events to the server
function sendKeyboardEvent(event) {
const data = {
type: 'keyboardEvent',
event: serializeKeyboardEvent(event),
clientId: clientId
};
socket.send(JSON.stringify(data));
}
// Serialize keyboard event properties
function serializeKeyboardEvent(event) {
return {
type: event.type,
key: event.key,
code: event.code,
keyCode: event.keyCode,
charCode: event.charCode,
which: event.which,
altKey: event.altKey,
ctrlKey: event.ctrlKey,
metaKey: event.metaKey,
shiftKey: event.shiftKey,
repeat: event.repeat,
isComposing: event.isComposing,
};
}
// Simulate keyboard event
function simulateKeyboardEvent(eventData) {
const event = new KeyboardEvent(eventData.type, eventData);
document.activeElement.dispatchEvent(event);
}
// Listen for keyboard events
['keydown', 'keypress', 'keyup'].forEach(eventType => {
document.addEventListener(eventType, sendKeyboardEvent, true);
});
})();
</script>
`;
htmlContent = htmlContent.replace('</body>', `${scriptTag}</body>`);
res.send(htmlContent);
} else {
res.status(404).send('Client not found');
}
});
// Start the server
server.listen(port, () => {
console.log(`Server is listening on http://localhost:${port}`);
});