Spaces:
Running
Running
File size: 4,523 Bytes
1d45897 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
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}`);
});
|