s2w / src /server.js
dvc890's picture
Upload 11 files
3c8ff75 verified
// server.js
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');
// 创建 Express 应用
const app = express();
const port = process.env.PORT || 7860;
// 创建 HTTP 服务器
const server = http.createServer(app);
// 创建 WebSocket 服务器
const wss = new WebSocket.Server({ server });
// 存储客户端连接
const clients = new Set();
// WebSocket 连接处理
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) => {
// 尝试解析为 JSON
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) {
// 如果不是 JSON 消息,则继续处理为数据包
}
// console.log('接收到消息,长度:', data.length);
// 处理接收到的数据包
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 };