|
|
|
|
|
const express = require('express'); |
|
|
const http = require('http'); |
|
|
const WebSocket = require('ws'); |
|
|
const { handleIncomingPacket, setClientIdentifier, cleanupClientConnections } = require('./services/packetHandler'); |
|
|
const { authenticateClient, generateSessionKey } = require('./services/authService'); |
|
|
|
|
|
|
|
|
const app = express(); |
|
|
const port = process.env.PORT || 7860; |
|
|
|
|
|
|
|
|
const server = http.createServer(app); |
|
|
|
|
|
|
|
|
const wss = new WebSocket.Server({ server }); |
|
|
|
|
|
|
|
|
const clients = new Set(); |
|
|
|
|
|
|
|
|
wss.on('connection', (ws, req) => { |
|
|
console.log('新的 WebSocket 连接'); |
|
|
|
|
|
|
|
|
clients.add(ws); |
|
|
|
|
|
|
|
|
ws.on('error', (error) => { |
|
|
console.error('WebSocket 错误:', error); |
|
|
}); |
|
|
|
|
|
|
|
|
ws.once('message', (data) => { |
|
|
try { |
|
|
const authMessage = JSON.parse(data); |
|
|
|
|
|
|
|
|
if (authMessage.type === 'auth') { |
|
|
const { clientId, clientSecret } = authMessage.payload; |
|
|
|
|
|
|
|
|
if (authenticateClient(clientId, clientSecret)) { |
|
|
|
|
|
const sessionKey = generateSessionKey(clientId); |
|
|
|
|
|
|
|
|
setClientIdentifier(ws, clientId); |
|
|
|
|
|
|
|
|
ws.send(JSON.stringify({ |
|
|
type: 'auth_success', |
|
|
message: 'Authentication successful', |
|
|
sessionKey: sessionKey |
|
|
})); |
|
|
|
|
|
console.log(`客户端 ${clientId} 认证成功`); |
|
|
} else { |
|
|
|
|
|
ws.send(JSON.stringify({ |
|
|
type: 'auth_failed', |
|
|
message: 'Authentication failed' |
|
|
})); |
|
|
|
|
|
console.log(`客户端 ${clientId} 认证失败`); |
|
|
ws.close(); |
|
|
} |
|
|
} else { |
|
|
|
|
|
ws.send(JSON.stringify({ |
|
|
type: 'error', |
|
|
message: 'Authentication required' |
|
|
})); |
|
|
|
|
|
console.log('未提供认证信息,关闭连接'); |
|
|
ws.close(); |
|
|
} |
|
|
} catch (error) { |
|
|
console.error('处理认证消息时出错:', error.message); |
|
|
ws.close(); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
ws.on('message', async (data) => { |
|
|
|
|
|
try { |
|
|
const message = JSON.parse(data); |
|
|
if (message.type === 'auth') { |
|
|
return; |
|
|
} |
|
|
|
|
|
if (['connect', 'data', 'close'].includes(message.type)) { |
|
|
const { handleControlMessage } = require('./services/packetHandler'); |
|
|
await handleControlMessage(message, ws); |
|
|
return; |
|
|
} |
|
|
} catch (e) { |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await handleIncomingPacket(data, ws); |
|
|
}); |
|
|
|
|
|
|
|
|
ws.on('close', () => { |
|
|
console.log('WebSocket 连接已关闭'); |
|
|
|
|
|
cleanupClientConnections(ws); |
|
|
clients.delete(ws); |
|
|
}); |
|
|
|
|
|
|
|
|
ws.send(JSON.stringify({ type: 'welcome', message: 'Connected to tun2websocket server. Please authenticate.' })); |
|
|
}); |
|
|
|
|
|
|
|
|
app.get('/health', (req, res) => { |
|
|
res.status(200).json({ status: 'ok', timestamp: new Date().toISOString() }); |
|
|
}); |
|
|
|
|
|
|
|
|
server.listen(port, () => { |
|
|
console.log(`服务器运行在端口 ${port}`); |
|
|
}); |
|
|
|
|
|
module.exports = { app, server, wss }; |