-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathapp.js
103 lines (92 loc) · 3.3 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
const fs = require('fs/promises');
const path = require('path');
const http = require('http');
const Koa = require('koa');
const logger = require('koa-logger');
// const koaBody = require('koa-body');
const router = require('@koa/router')();
const { WebSocket } = require('ws');
const { main: autoSayHello, logs } = require('boss-zhipin-robot-core');
const { parseMime, getContent, openUrlOnce, handleQueryStr, parsePostData } = require('./util');
const isDev = process.env.NODE_ENV !== 'production';
const staticPath = 'dist';
const app = new Koa();
app.use(logger());
// todo 改为中间件
// 处理跨域
app.use(async (ctx, next) => {
ctx.set('Access-Control-Allow-Origin', '*');
ctx.set('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept');
ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
if (ctx.method == 'OPTIONS') {
ctx.body = 0;
}
await next();
});
// 处理路由
router.get('/', async ctx => {
ctx.set('content-type', 'text/html');
if (isDev) {
ctx.redirect('http://127.0.0.1:5173');
} else {
ctx.body = await fs.readFile(`${__dirname}/dist/index.html`);
}
});
router.post('/api/send', async (ctx, next) => {
let postData = await parsePostData(ctx);
postData.queryParams = handleQueryStr(postData.queryParams); // string => obj
postData.timeout = postData.timeout * 1000;
await autoSayHello(postData);
ctx.body = { code: 0, msg: 'ok' };
});
app.use(router.routes());
// 处理静态资源
app.use(async (ctx, next) => {
if (ctx.path.startsWith('/api')) return await next();
if (!['HEAD', 'GET'].includes(ctx.method)) {
return await next();
}
let fullStaticPath = path.join(__dirname, staticPath);
// 获取静态资源内容,文件内容,目录,或404
let content = await getContent(ctx, fullStaticPath); // 请求到了这里没有走路由. getContent 又拼接 /dist + ctx.url,相当于所有请求都尝试找资源
let mime = parseMime(ctx.url);
if (mime) ctx.type = mime;
// 输出静态资源内容
if (mime.indexOf('image/') >= 0) {
// 如果是图片,则用node原生res,输出二进制数据
ctx.res.writeHead(200);
ctx.res.write(content, 'binary');
ctx.res.end();
} else {
// 其他则输出文本
ctx.body = content;
}
await next();
});
let wss = new WebSocket.Server({ clientTracking: false, noServer: true });
const server = http.createServer(app.callback());
// const server = http.createServer(app);
server.on('upgrade', function (request, socket, head) {
wss.handleUpgrade(request, socket, head, function (ws) {
wss.emit('connection', ws, request);
});
});
server.listen(3000);
openUrlOnce(`http://localhost:${isDev ? 5173 : 3000}`);
// wss.once('connection', function (ws) { });
let subscribeLogs;
wss.on('connection', function (ws, request) {
console.log('成功连接');
subscribeLogs = txt => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(txt);
}
};
});
logs.push = function monitor(txt) {
if (typeof subscribeLogs !== 'function') {
return console.error('客户端未连接,请刷新页面');
}
subscribeLogs(txt); // 利用闭包实现手动发消息
// [].push.apply(this, [txt]);
};