feat: Refactor server implementation to support Bun and Node environments

- Introduced `ServerNode` and `BunServer` classes to handle server logic for Node and Bun respectively.
- Updated `App` class to initialize the appropriate server based on the runtime environment.
- Enhanced `parseBody` function to handle request body parsing for both environments.
- Modified WebSocket handling to support Bun's WebSocket upgrade mechanism.
- Improved error handling and response structure across the server implementation.
- Added support for custom middleware in the server's request handling.
- Refactored server base functionality into `ServerBase` for better code organization.
- Updated type definitions to reflect changes in server options and listener handling.
- Added a new demo for testing the server functionality with various request types.
This commit is contained in:
2025-12-20 05:11:51 +08:00
parent e1a53c01ea
commit a6a7e74559
21 changed files with 1173 additions and 454 deletions

View File

@@ -13,7 +13,9 @@
<script>
// const ws = new WebSocket('ws://localhost:4002/api/router');
const ws = new WebSocket('ws://192.168.31.220:4002/api/router');
const ws = new WebSocket('ws://localhost:4002/api/router');
// const ws = new WebSocket('ws://localhost:4002/ws');
// const ws = new WebSocket('ws://192.168.31.220:4002/api/router');
// 当连接成功时
ws.onopen = () => {
@@ -24,12 +26,14 @@
// ws.send(message);
const message = JSON.stringify({
type: 'router',
id: '123556',
data: {
path: 'demo',
key: '01',
}
});
ws.send(message);
// ws.send(JSON.stringify('Hello Server!'));
};
// 接收服务器的消息
@@ -68,6 +72,9 @@
ws.onclose = () => {
console.log('Disconnected from WebSocket server');
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
</script>
</body>

View File

@@ -1,6 +1,6 @@
import { Route, App } from '@kevisual/router';
import { Route, App } from '@kevisual/router/src/app.ts';
const app = new App({ io: true });
const app = new App({ serverOptions: { io: true } });
app.listen(4002);
const route01 = new Route('demo', '01');
route01.run = async (ctx) => {
@@ -25,3 +25,14 @@ app.addRoute(route02);
console.log(`http://localhost:4002/api/router?path=demo&key=02`);
console.log(`http://localhost:4002/api/router?path=demo&key=01`);
app.server.on({
id: 'abc',
path: '/ws',
io: true,
fun: async ({ data }, { end }) => {
console.log('Custom middleware for /ws');
console.log('Data received:', data);
end({ message: 'Hello from /ws middleware' });
}
})

View File

@@ -1,6 +1,6 @@
import { SimpleRouter } from '@kevisual/router/simple';
import { SimpleRouter } from '@kevisual/router/src/router-simple.ts';
const router = new SimpleRouter();
export const router = new SimpleRouter();
router.get('/', async (req, res) => {
console.log('get /');
@@ -8,21 +8,28 @@ router.get('/', async (req, res) => {
router.post('/post', async (req, res) => {
console.log('post /post');
console.log('req body:', req, res);
res.end('post response');
});
router.get('/user/:id', async (req, res) => {
console.log('get /user/:id', req.params);
res.end(`user id is ${req.params.id}`);
});
router.post('/user/:id', async (req, res) => {
console.log('post /user/:id', req.params);
console.log('post /user/:id params', req.params);
const body = await router.getBody(req);
console.log('post body:', body);
res.end(`post user id is ${req.params.id}`);
});
router.post('/user/:id/a', async (req, res) => {
console.log('post /user/:id', req.params);
res.end(`post user id is ${req.params.id} a`);
});
router.parse({ url: 'http://localhost:3000/', method: 'GET' } as any, {} as any);
router.parse({ url: 'http://localhost:3000/post', method: 'POST' } as any, {} as any);
router.parse({ url: 'http://localhost:3000/user/1/a', method: 'GET' } as any, {} as any);
router.parse({ url: 'http://localhost:3000/user/1/a', method: 'POST' } as any, {} as any);
// router.parse({ url: 'http://localhost:3000/', method: 'GET' } as any, {} as any);
// router.parse({ url: 'http://localhost:3000/post', method: 'POST' } as any, {} as any);
// router.parse({ url: 'http://localhost:3000/user/1/a', method: 'GET' } as any, {} as any);
// router.parse({ url: 'http://localhost:3000/user/1/a', method: 'POST' } as any, {} as any);

View File

@@ -0,0 +1,56 @@
import { App } from '@kevisual/router/src/app.ts';
import { router } from './a.ts';
export const app = new App();
app.server.on([{
fun: async (req, res) => {
console.log('Received request:', req.method, req.url);
const p = await router.parse(req, res);
if (p) {
console.log('Router parse result:', p);
}
}
}, {
id: 'abc',
path: '/ws',
io: true,
fun: async (data, end) => {
console.log('Custom middleware for /ws');
console.log('Data received:', data);
end({ message: 'Hello from /ws middleware' });
}
}]);
app.server.listen(3004, () => {
console.log('Server is running on http://localhost:3004');
// fetch('http://localhost:3004/', { method: 'GET' }).then(async (res) => {
// const text = await res.text();
// console.log('Response for GET /:', text);
// });
// fetch('http://localhost:3004/post', {
// method: 'POST',
// headers: { 'Content-Type': 'application/json' },
// body: JSON.stringify({ message: 'Hello, server!' }),
// }).then(async (res) => {
// const text = await res.text();
// console.log('Response for POST /post:', text);
// });
// fetch('http://localhost:3004/user/123', { method: 'GET' }).then(async (res) => {
// const text = await res.text();
// console.log('Response for GET /user/123:', text);
// });
fetch('http://localhost:3004/user/456', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'User456' }),
}).then(async (res) => {
const text = await res.text();
console.log('Response for POST /user/456:', text);
});
});