Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/flarestart/egg-websocket-plugin
A standard WebSocket plugin for egg.js
https://github.com/flarestart/egg-websocket-plugin
egg egg-websocket plugin websocket ws
Last synced: 3 months ago
JSON representation
A standard WebSocket plugin for egg.js
- Host: GitHub
- URL: https://github.com/flarestart/egg-websocket-plugin
- Owner: flarestart
- License: mit
- Created: 2020-01-01T07:51:47.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2023-04-26T15:09:05.000Z (over 1 year ago)
- Last Synced: 2024-07-13T06:34:30.134Z (4 months ago)
- Topics: egg, egg-websocket, plugin, websocket, ws
- Language: TypeScript
- Homepage:
- Size: 311 KB
- Stars: 52
- Watchers: 3
- Forks: 4
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
- awesome-github-star - egg-websocket-plugin
README
# egg-websocket-plugin
[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![Test coverage][codecov-image]][codecov-url]
[![David deps][david-image]][david-url]
[![Known Vulnerabilities][snyk-image]][snyk-url]
[![npm download][download-image]][download-url][npm-image]: https://img.shields.io/npm/v/egg-websocket-plugin.svg?style=flat-square
[npm-url]: https://npmjs.org/package/egg-websocket-plugin
[travis-image]: https://img.shields.io/travis/flarestart/egg-websocket-plugin.svg?style=flat-square
[travis-url]: https://travis-ci.org/flarestart/egg-websocket-plugin
[codecov-image]: https://img.shields.io/codecov/c/github/flarestart/egg-websocket-plugin.svg?style=flat-square
[codecov-url]: https://codecov.io/github/flarestart/egg-websocket-plugin?branch=master
[david-image]: https://img.shields.io/david/flarestart/egg-websocket-plugin.svg?style=flat-square
[david-url]: https://david-dm.org/flarestart/egg-websocket-plugin
[snyk-image]: https://snyk.io/test/npm/egg-websocket-plugin/badge.svg?style=flat-square
[snyk-url]: https://snyk.io/test/npm/egg-websocket-plugin
[download-image]: https://img.shields.io/npm/dm/egg-websocket-plugin.svg?style=flat-square
[download-url]: https://npmjs.org/package/egg-websocket-plugin## 依赖说明
### 依赖的 egg 版本
✅ egg 2.x 安装 [email protected]
✅ egg 3.x 安装 [email protected]+## 特性支持
- [x] 兼容 egg 自身的 controller
- [x] 兼容 egg 路由中间件
- [x] 不需要像 socket.io 一样开启 `sticky` 模式
- [x] 支持消息广播订阅## 使用方式
```bash
yarn add egg-websocket-plugin
```### 1. 开启插件
```js
// config/plugin.js
exports.websocket = {
enable: true,
package: 'egg-websocket-plugin',
};
```### 2. 配置 WebSocket 路由
```js
// app/router.js
app.ws.route('/ws', app.controller.home.hello);// 可使用路由参数,使用方式同 egg 自身路由
app.ws.route('/foo/:id', app.controller.home.foo);
```### 3. 配置 WebSocket 全局中间件【可选】
**注意**:配置 WebSocket 全局中间件应当在所有 `app.ws.route` 注册路由之前进行,否则之前的路由不会应用到全局中间件,且插件会生成一条警告日志```js
// app/router.js// 配置 WebSocket 全局中间件
app.ws.use(async (ctx, next) => {
console.log('websocket open');
await next();
console.log('websocket closed');
});
```### 4. 配置路由中间件【可选】
**路由会依次用到 app.use, app.ws.use, 以及 app.ws.router 中配置的中间件**
```js
// app/router.js
async function middleware(ctx, next) {
console.log('open', ctx.starttime);
await next();
}
// 配置路由中间件
app.ws.route('/ws', middleware, app.controller.home.hello);
```### 5. 禁用 App 全局中间件
> 插件默认会使用 app.use(...) 注册的中间件,如果你不想使用它们,或者这些插件与 websocket 有冲突,你可以在 `config.default.js` 中禁用它们
```js
config.websocket = {
useAppMiddlewares: false,
};
```### 6. 在控制器中使用 websocket
websocket 是一个 `ws` 插件的实例,可阅读 [ws](https://www.npmjs.com/package/ws) 插件的说明文档或 TypeScript 的定义
```js
// app/controller/home.js
import { Controller } from 'egg';export default class HomeController extends Controller {
async hello() {
const { ctx, app } = this;
if (!ctx.websocket) {
throw new Error('this function can only be use in websocket router');
}console.log('client connected');
ctx.websocket
.on('message', (msg) => {
console.log('receive', msg);
})
.on('close', (code, reason) => {
console.log('websocket closed', code, reason);
});
}
}```
## 支持 Redis 消息发布订阅【可选】
### 开启消息广播
**注意**:`egg-websocket-plugin` 依赖于 `ioredis` 但可与其他插件如 `egg-redis` 共用一个 `ioredis` 依赖
开启广播相关的 API 需要在 config.default.js 中配置 `redis` 连接,配置项可参见 [ioredis](https://www.npmjs.com/package/ioredis)
```typescript
config.websocket = {
// 配置 websocket 使用 redis 作消息广播,配置项目参见 ioredis
redis: {
host: '127.0.0.1',
port: 6379,
},
};
```### 房间消息广播 API
> 开启 redis 配置后,即可使用下面的广播 API
#### 1. app.ws.sendTo(room, data)
> 发送消息到某个房间,将 data 原样发送到客户端连接
- `room` <string>: 房间名
- `data` <string | Buffer>: 发送内容,原样发送#### 2. app.ws.sendJsonTo(room, data)
> 发送消息到某个房间,会自动使用 JSON.stringify 对 data 进行序列化
- `room` <string> 房间名
- `data` <any> 发送内容,可进行 JSON 序列化的任意对象#### 3. ctx.websocket.room.join(room, fn?)
> 将当前连接加入房间- `room` <string> 要加入的房间名
- `fn` <function({room, message})> 可选参数,用于配置房间消息处理函数,配置详情见 [自定义房间消息处理函数](#roomhandler)
- `room` <string> 消息所属房间名
- `message` 房间内的广播消息,消息类型取决于 `sendTo()` 发送时的类型
- 忽略此参数,则该房间的消息将直接发送到客户端连接
- 配置这个参数,则可以手动处理消息发送逻辑,不再自动将房间内的消息发送到客户端连接#### 4. ctx.websocket.room.leave(room)
> 当前连接离开房间,当前连接关闭后,将自动退出当前连接加入过的房间,因此关闭连接前无需要手动离开房间- `room` <string> 房间名
#### 5. ctx.websocket.room.sendTo(room, data)
> 发送消息到某个房间,将 data 原样发送到客户端连接,功能与 app.ws.sendTo 相同
#### 6. ctx.websocket.room.sendJsonTo(room, data)
> 发送消息到某个房间,会自动使用 JSON.stringify 对 data 进行序列化,功能与 `app.ws.sendTo` 相同
```typescript
// 当前连接加入房间 foo,收到房间的消息将直接发送到当前客户端连接
ctx.websocket.room.join('foo');// 当前连接加入房间 bar,并设置该房间消息处理函数,设置了处理函数将不再直接发送消息到当前客户端
// room: string, message: Buffer | string
ctx.websocket.room.join('bar', ({ room, message }) => {
console.log(room, message);
});// 当前连接离开房间
ctx.websocket.room.leave('foo');// 通过当前 ctx 广播消息,所有加入房间的连接会收到这条消息
ctx.websocket.room.sendTo('foo', 'hello foo');// 也可以通过通过 app 对象来广播消息
app.ws.sendTo('bar', 'hello bar');
```**注意**:使用 `room.join()` 函数,忽略第二个参数的情况下,房间内的消息会直接发送到当前客户端连接。
如果你需要自定义这部分的处理逻辑,那么可配置 `room.join()` 的第二个参数。
```typescript
ctx.websocket.room.join('foo', ({ room, message }) => {
// room: string 房间名
// message: Buffer | string 消息内容
// message 的类型取决于使用 sendTo 发送的是 string 还是 Buffer
console.log(room, message);
});
```### 例子
router.ts
```typescript
import { Application } from 'egg';export default (app: Application) => {
const { controller, router } = app;// 配置 http 路由
router.get('/', controller.home.index);
// 配置 websocket 路由,websocket 可与 http 使用同一个 url,不会导致冲突
app.ws.route('/', controller.home.ws);
};
```controller/home.ts
```typescript
import { Controller } from 'egg';export default class HomeController extends Controller {
public async index() {
const { ctx, app } = this;
// 向房间 foo 发送消息
app.ws.sendTo('foo', 'hello from index');
ctx.body = 'index';
}public async ws() {
const { websocket } = this.ctx;
if (!websocket) {
throw new Error('this function can only be use in websocket router');
}// 加入到房间 foo
websocket.room.join('foo');
}
}
```浏览器连接 WebSocket
```javascript
const ws = new WebSocket('ws://127.0.0.1:7001/');
ws.addEventListener('message', data => {
console.log(data);
});
```这时候,访问 http://localhost:7001/ WebSocket 客户端将会收到一条 `hello from index` 的字符串
## 使用场景
- 使用 egg 开发标准 WebSocket 服务器
- 微信小程序 WebSocket 服务器## 提问交流
请到 [issues](https://github.com/flarestart/egg-websocket-plugin/issues) 异步交流。
## License
[MIT](LICENSE)