Skip to content

Commit 83e6a68

Browse files
committed
refactor: migrate WebSocket implementation to Hono's built-in WebSocket handler
1 parent 0c44d41 commit 83e6a68

File tree

1 file changed

+14
-115
lines changed

1 file changed

+14
-115
lines changed

src/index.js

Lines changed: 14 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ import { fileURLToPath } from 'url';
66
import dotenvFlow from 'dotenv-flow';
77
import fs from 'fs';
88
import { WebSocketServer } from 'ws';
9-
9+
import { createNodeWebSocket } from '@hono/node-ws'
1010
import { registerRoutes } from './routes/index.js';
1111
import { errorHandler } from './middleware/error-handler.js';
1212
import { enableSafeHttpDebugging } from './utils/safe-http-debug.js';
1313

14+
15+
1416
// Enable HTTP debugging for detailed request/response logging
1517
console.log('Enabling HTTP debugging for detailed request/response logging');
1618
enableSafeHttpDebugging();
@@ -36,6 +38,7 @@ if (fs.existsSync(publicPath)) {
3638

3739
// Create Hono app for both static files and API endpoints
3840
const app = new Hono();
41+
const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app })
3942

4043
// Add CORS middleware
4144
app.use('*', async (c, next) => {
@@ -221,6 +224,13 @@ app.get('/', async (c) => {
221224
});
222225
});
223226

227+
app.get(
228+
'/ws',
229+
upgradeWebSocket((c) => ({
230+
// https://hono.dev/helpers/websocket
231+
}))
232+
);
233+
224234
// Serve static files from the public directory, but skip API routes
225235
app.use('*', async (c, next) => {
226236
const reqPath = c.req.path;
@@ -285,7 +295,7 @@ app.get('*', async (c) => {
285295
const port = process.env.PORT || 3000;
286296
const startServer = (portToUse) => {
287297
try {
288-
serve({
298+
const server = serve({
289299
fetch: app.fetch,
290300
port: portToUse
291301
}, (info) => {
@@ -303,11 +313,8 @@ const startServer = (portToUse) => {
303313
console.log(`- Payment Callback: http://localhost:${info.port}/api/1/payments/cryptapi/callback`);
304314
console.log(`- Payment Logs: http://localhost:${info.port}/api/1/payments/cryptapi/logs`);
305315
console.log(`- Web interface: http://localhost:${info.port}`);
306-
307-
// Create a separate WebSocket server on a different port
308-
const wsPort = parseInt(portToUse) + 1;
309-
startWebSocketServer(wsPort);
310316
});
317+
injectWebSocket(server);
311318
} catch (err) {
312319
if (err.code === 'EADDRINUSE') {
313320
console.log(`Port ${portToUse} is already in use, trying ${portToUse + 2}...`);
@@ -319,112 +326,4 @@ const startServer = (portToUse) => {
319326
};
320327

321328
// Try to start the server on the initial port
322-
startServer(port);
323-
324-
// Function to start the WebSocket server
325-
function startWebSocketServer(wsPort) {
326-
try {
327-
// Create a separate WebSocket server
328-
const wss = new WebSocketServer({ port: wsPort });
329-
330-
// Store connected clients
331-
const clients = new Set();
332-
333-
// Handle WebSocket connections
334-
wss.on('connection', (ws) => {
335-
console.log('WebSocket connection established');
336-
337-
// Add client to the set
338-
clients.add(ws);
339-
340-
// Send a welcome message
341-
const welcomeMessage = JSON.stringify({
342-
type: 'system',
343-
content: 'Connected to WebSocket server'
344-
});
345-
ws.send(welcomeMessage);
346-
347-
// Handle messages
348-
ws.on('message', (message) => {
349-
try {
350-
console.log(`Received message: ${message}`);
351-
352-
// Parse the message
353-
const parsedMessage = JSON.parse(message);
354-
355-
// Handle different message types
356-
switch (parsedMessage.type) {
357-
case 'key_exchange':
358-
// Forward key exchange message to all other clients
359-
forwardMessage(ws, parsedMessage);
360-
break;
361-
362-
case 'chat_message':
363-
// Forward chat message to all other clients
364-
forwardMessage(ws, parsedMessage);
365-
break;
366-
367-
default:
368-
console.warn('Unknown message type:', parsedMessage.type);
369-
ws.send(JSON.stringify({
370-
type: 'system',
371-
content: `Unknown message type: ${parsedMessage.type}`
372-
}));
373-
}
374-
} catch (error) {
375-
console.error('Error handling WebSocket message:', error);
376-
ws.send(JSON.stringify({
377-
type: 'system',
378-
content: `Error: ${error.message}`
379-
}));
380-
}
381-
});
382-
383-
// Handle connection close
384-
ws.on('close', () => {
385-
console.log('WebSocket connection closed');
386-
// Remove client from the set
387-
clients.delete(ws);
388-
});
389-
390-
// Handle errors
391-
ws.on('error', (error) => {
392-
console.error('WebSocket error:', error);
393-
clients.delete(ws);
394-
});
395-
});
396-
397-
console.log(`WebSocket server running at ws://localhost:${wsPort}`);
398-
399-
// Handle WebSocket server errors
400-
wss.on('error', (error) => {
401-
if (error.code === 'EADDRINUSE') {
402-
console.log(`WebSocket port ${wsPort} is already in use, trying ${wsPort + 2}...`);
403-
startWebSocketServer(wsPort + 2);
404-
} else {
405-
console.error('WebSocket server error:', error);
406-
}
407-
});
408-
} catch (error) {
409-
console.error('Error starting WebSocket server:', error);
410-
if (error.code === 'EADDRINUSE') {
411-
console.log(`WebSocket port ${wsPort} is already in use, trying ${wsPort + 2}...`);
412-
startWebSocketServer(wsPort + 2);
413-
}
414-
}
415-
/**
416-
* Forward a message to all other connected clients
417-
* @param {WebSocket} sender - The client that sent the message
418-
* @param {Object} message - The message to forward
419-
*/
420-
function forwardMessage(sender, message) {
421-
const messageStr = JSON.stringify(message);
422-
423-
// Send to all clients except the sender
424-
clients.forEach(client => {
425-
if (client !== sender && client.readyState === WebSocket.OPEN) {
426-
client.send(messageStr);
427-
}
428-
});
429-
}
430-
}
329+
startServer(port);

0 commit comments

Comments
 (0)