@lzpong/httpm 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/httpm.js +7 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -224,6 +224,7 @@ app.ws('/chat/:room', (ws, req) => {
|
|
|
224
224
|
```javascript
|
|
225
225
|
app.wss.broadcast('/chat', 'Hello everyone'); // 按路径分组广播
|
|
226
226
|
app.wss.broadcast('/chat', 'Hello', ws); // 排除指定连接(传 ws 对象)
|
|
227
|
+
app.wss.broadcastAll('Hello everyone'); // 全局广播
|
|
227
228
|
app.wss.getConnections(); // 获取所有连接
|
|
228
229
|
```
|
|
229
230
|
|
|
@@ -237,6 +238,13 @@ app.wss.getConnections(); // 获取所有连接
|
|
|
237
238
|
| `close` | 连接关闭,回调参数 `(code, reason)` |
|
|
238
239
|
| `error` | 连接错误 |
|
|
239
240
|
|
|
241
|
+
### WebSocket 方法
|
|
242
|
+
|
|
243
|
+
| 方法 | 说明 |
|
|
244
|
+
|------|------|
|
|
245
|
+
| `ws.send(data)` | 发送消息(自动区分文本/JSON/二进制) |
|
|
246
|
+
| `ws.close(code, reason)` | 关闭连接,可选状态码和原因 |
|
|
247
|
+
|
|
240
248
|
### data 事件使用
|
|
241
249
|
|
|
242
250
|
```javascript
|
|
@@ -382,6 +390,15 @@ const app = httpm({
|
|
|
382
390
|
});
|
|
383
391
|
```
|
|
384
392
|
|
|
393
|
+
## 关闭服务
|
|
394
|
+
|
|
395
|
+
```javascript
|
|
396
|
+
// 关闭 HTTP/HTTPS 服务器并断开所有 WebSocket 连接
|
|
397
|
+
app.close(() => {
|
|
398
|
+
console.log('Server closed');
|
|
399
|
+
});
|
|
400
|
+
```
|
|
401
|
+
|
|
385
402
|
## 导出接口
|
|
386
403
|
|
|
387
404
|
```javascript
|
package/httpm.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* httpm - 基于 Node.js 原生模块的单文件、零依赖 HTTP 服务库
|
|
3
3
|
*
|
|
4
4
|
* @name httpm
|
|
5
|
-
* @version 1.2.
|
|
5
|
+
* @version 1.2.1
|
|
6
6
|
* @description 兼容 Express API,内置路由、中间件、静态文件服务、
|
|
7
7
|
* WebSocket、SSE、流式上传、日志系统等功能
|
|
8
8
|
* @license MIT
|
|
@@ -2191,6 +2191,8 @@ class Application extends Router {
|
|
|
2191
2191
|
* 错误处理:查找错误处理中间件(4 个参数)
|
|
2192
2192
|
*/
|
|
2193
2193
|
_handleError(err, req, res, stack, startIdx) {
|
|
2194
|
+
// 无错误时直接返回(错误处理中间件调用 next() 无参数表示错误已处理)
|
|
2195
|
+
if (!err) return;
|
|
2194
2196
|
// 从当前栈中查找错误处理中间件
|
|
2195
2197
|
for (let i = startIdx; i < stack.length; i++) {
|
|
2196
2198
|
const handler = stack[i].handler;
|
|
@@ -2384,23 +2386,20 @@ class Application extends Router {
|
|
|
2384
2386
|
*/
|
|
2385
2387
|
_renderDirectoryHTML(requestPath, items) {
|
|
2386
2388
|
// requestPath 已去掉前导 /,空字符串表示根目录
|
|
2387
|
-
// path.dirname('subdir') 返回 '.',应映射为根目录 ''
|
|
2388
|
-
let parentPath = requestPath ? path.dirname(requestPath) : '/';
|
|
2389
|
-
if (parentPath === '.') parentPath = '';
|
|
2390
2389
|
// 根目录时显示 '/',否则显示请求路径
|
|
2391
2390
|
const displayPath = requestPath || '/';
|
|
2392
2391
|
let html = `<!DOCTYPE html><html><head><meta charset="utf-8"><title>Directory: ${escapeHtml(displayPath)}</title>`;
|
|
2393
2392
|
html += `<style>body{font-family:-apple-system,sans-serif;margin:20px;background:#f5f5f5}h1{font-size:18px;color:#333}table{width:100%;border-collapse:collapse;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.1)}th{text-align:left;padding:10px 12px;background:#f8f8f8;border-bottom:2px solid #ddd;font-size:13px;color:#666}td{padding:8px 12px;border-bottom:1px solid #eee;font-size:13px}a{color:#0066cc;text-decoration:none}a:hover{text-decoration:underline}.dir{font-weight:bold}.size{color:#999}</style>`;
|
|
2394
2393
|
html += `</head><body><h1>Directory: ${escapeHtml(displayPath)}</h1><table><tr><th>Name</th><th>Size</th><th>Modified</th></tr>`;
|
|
2395
2394
|
|
|
2396
|
-
//
|
|
2395
|
+
// 父目录链接:使用相对路径 .. 返回上一级(根目录时不显示)
|
|
2397
2396
|
if (requestPath && requestPath !== '/') {
|
|
2398
|
-
html += `<tr><td><a href="
|
|
2397
|
+
html += `<tr><td><a href=".." class="dir">../</a></td><td class="size">-</td><td>-</td></tr>`;
|
|
2399
2398
|
}
|
|
2400
2399
|
|
|
2401
2400
|
for (const item of items) {
|
|
2402
|
-
//
|
|
2403
|
-
const href =
|
|
2401
|
+
// 仅使用文件名作为相对 href,页面 URL 本身已包含目录路径
|
|
2402
|
+
const href = item.name;
|
|
2404
2403
|
const name = item.isDirectory ? item.name + '/' : item.name;
|
|
2405
2404
|
const size = item.isDirectory ? '-' : fmtSize(item.size);
|
|
2406
2405
|
const cls = item.isDirectory ? 'dir' : '';
|