目录结构
project/ │ ├── src/ │ ├── app.ts │ ├── routes/ │ │ ├── userRoutes.ts │ │ └── index.ts │ ├── entities/ │ │ └── User.ts │ ├── utils/ │ │ └── parseQuery.ts │ └── index.ts │ ├── ormconfig.json └── package.json
User 实体 (User.ts)
// src/entities/User.ts import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; @Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column() name: string; @Column() email: string; }
ORM 配置 (ormconfig.json)
// ormconfig.json { "type": "postgres", "host": "localhost", "port": 5432, "username": "postgres", "password": "password", "database": "test", "entities": ["src/entities/*.ts"], "synchronize": true }
请求参数解析函数 (parseQuery.ts)
// src/utils/parseQuery.ts export const parseQuery = (req: any): Promise<any> => { return new Promise((resolve, reject) => { let body = ''; req.on('data', (chunk: string) => { body += chunk; }); req.on('end', () => { try { const params = JSON.parse(body); resolve(params); } catch (error) { reject(new Error('Failed to parse request body')); } }); }); };
路由处理函数 (userRoutes.ts)
// src/routes/userRoutes.ts import { User } from '../entities/User'; import { Connection } from 'typeorm'; import { parseQuery } from '../utils/parseQuery'; export const userRoutes = (dbConnection: Connection) => ({ '/user': { POST: (res, req) => { parseQuery(req).then(async (params) => { try { const user = new User(); user.name = params.name; user.email = params.email; await dbConnection.manager.save(user); res.end(JSON.stringify(user)); } catch (error) { res.writeStatus('500 Internal Server Error').end(error.message); } }).catch(error => { res.writeStatus('400 Bad Request').end(error.message); }); }, // 其他处理函数... }, // 其他路由和对应的处理函数... });
路由入口 (index.ts)
// src/routes/index.ts import { userRoutes } from './userRoutes'; // 可以在这里导入其他路由模块 export const routes = (dbConnection: Connection) => ({ ...userRoutes(dbConnection), // ...其他路由模块 });
uWebSockets.js 应用 (app.ts)
// src/app.ts import { create } from 'uWebSockets.js'; import { Connection, createConnection } from 'typeorm'; import { routes } from './routes'; import { parseQuery } from './utils/parseQuery'; let dbConnection: Connection; createConnection().then(async connection => { dbConnection = connection; console.log('Connected to the database'); const app = create({ keyFile: './ssl/key.pem', certFile: './ssl/cert.pem', }); // 设置路由 const routeHandlers = routes(dbConnection); for (const route in routeHandlers) { for (const method in routeHandlers[route]) { app[method.toLowerCase()](route, routeHandlers[route][method]); } } app.listen(3000, token => { if (token) { console.log('Listening to port 3000'); } else { console.log('Failed to listen to port 3000'); } }); });
主入口文件 (index.ts)
// src/index.ts import './app'; // 引入主应用文件 // 这个文件可以留空,或者添加一些其他的逻辑
定时事务
// src/utils/timedTransactions.ts export function startTimedTransactions() { // 每6秒执行一次的事务 setInterval(() => { // 这里调用你的事务处理函数 console.log('Running 6-second transaction'); // runSixSecondTransaction(); }, 6000); // 每33分钟执行一次的事务 setInterval(() => { // 这里调用你的事务处理函数 console.log('Running 33-minute transaction'); // runThirtyThreeMinuteTransaction(); }, 33 * 60 * 1000); // 每天早上1点到5点之间执行的事务 const now = new Date(); const todayMidnight = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0); const nextRun = new Date(todayMidnight.getTime() + (now.getHours() >= 1 && now.getHours() < 5 ? 0 : 1) * 24 * 60 * 60 * 1000); setTimeout(() => { // 这里调用你的事务处理函数 console.log('Running daily transaction'); // runDailyTransaction(); // 设置第二天的时间 const tomorrowMidnight = new Date(todayMidnight.getTime() + 24 * 60 * 60 * 1000); setInterval(() => { // 这里调用你的事务处理函数 console.log('Running daily transaction'); // runDailyTransaction(); }, tomorrowMidnight.getTime() - todayMidnight.getTime()); }, nextRun.getTime() - now.getTime()); }
跨域处理
在uWebSockets.js中,跨域可以通过设置响应头来处理。
// 设置跨域 function setCrossDomainHeaders(res: any) { res.writeHeader('Access-Control-Allow-Origin', '*'); res.writeHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS'); res.writeHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); } // 在app.ts中使用 app.options('/user', (res, req) => { setCrossDomainHeaders(res); res.end(); // 对于OPTIONS请求,结束响应 });
Token验证中间件
中间件可以通过拦截请求并在传递给路由处理程序之前执行一些逻辑来实现。
// src/middlewares/tokenValidator.ts export function tokenValidator(req: any, res: any, next: Function) { const token = req.getHeader('Authorization'); if (!token) { res.writeStatus('401 Unauthorized').end('Access denied'); return; } // 假设我们有解析token的函数,这里获取用户信息 // const userInfo = decodeToken(token); const userInfo = { id: 'user123', name: 'John Doe' }; // 假的用户信息 req.userInfo = userInfo; // 将用户信息附加到请求对象 next(); // 调用下一个中间件或路由处理程序 }
将所有内容整合到app.ts
// src/app.ts import { create } from 'uWebSockets.js'; import { Connection, createConnection } from 'typeorm'; import { routes } from './routes'; import { parseQuery } from './utils/parseQuery'; import { tokenValidator } from './middlewares/tokenValidator'; import { startTimedTransactions } from './utils/timedTransactions'; let dbConnection: Connection; createConnection().then(async connection => { dbConnection = connection; console.log('Connected to the database'); const app = create({ keyFile: './ssl/key.pem', certFile: './ssl/cert.pem', }); // 设置路由,使用中间件进行token验证 const routeHandlers = routes(dbConnection); for (const route in routeHandlers) { for (const method in routeHandlers[route]) { const originalHandler = routeHandlers[route][method]; routeHandlers[route][method] = (res, req) => { tokenValidator(req, res, () => originalHandler(res, req)); }; } } // 设置跨域 app.any('/*', (res, req) => { setCrossDomainHeaders(res); // 继续处理请求 app.run(req, res); }); // 设置路由 for (const route in routeHandlers) { for (const method in routeHandlers[route]) { app[method.toLowerCase()](route, routeHandlers[route][method]); } app.listen(3000, token => { if (token) { console.log('Listening to port 3000'); } else { console.log('Failed to listen to port 3000'); } }); });