grpc 的 eggjs 插件
$ npm i egg-grpc --save// {app_root}/config/plugin.js
exports.grpc = {
enable: true,
package: 'egg-grpc',
};// {app_root}/config/config.default.js
exports.grpc = {
endpoint: 'localhost:50051',
// dir: 'app/proto', // proto 文件目录,相对路径
// property: 'grpc', // 默认挂载到 `ctx.grpc.**`
// loadOpts: { convertFieldsToCamelCase: true, }, // message field case: `string user_name` -> `userName`
};更多参数配置见 config/config.default.js。
示例代码:
app/proto
├── egg
│ └── test
│ ├── game.proto
│ └── message.proto
├── uc
│ └── test.proto
└── share.proto// app/proto/share.proto
syntax = "proto3";
package egg.share;
message Status {
string code = 1;
string err_msg = 2;
}
service ShowCase {
rpc Echo(Status) returns (Status) {}
}快速开始:
// 仅跟 `package` 定义有关,跟 proto 文件路径无关。
const client = ctx.grpc.egg.share.showCase;
const result = yield client.echo({ code: 200 });
console.log(result);- 默认从
app/proto目录加载 proto 文件。 - 目录仅用于文件管理,不影响到挂载到
ctx和app上的访问路径,后者仅跟package定义有关。 - 譬如上述的
app/proto/share.proto文件,定义为package egg;,所以对应的访问方式:yield ctx.grpc.egg.share.showCase.echo(data, meta, options)new app.grpcProto.egg.share.Status({ code: 200 })new app.grpcProto.egg.share.ShowCase(address)new ctx.grpcProto.egg.share.ShowCase(address)
| 术语 | 命名规范(proto 定义) | 加载后 |
|---|---|---|
| package | 小写,用 . 分隔 |
若存在 _,则驼峰 |
| service | 类名风格,首字母大写 | 初始化到 ctx 后为驼峰格式 |
| rpc | 类名风格,首字母大写 | 驼峰格式 |
| message | 类名风格,首字母大写 | 按原格式挂载在 app.grpcProto 上 |
| field | 下划线风格,全小写 | 驼峰格式 |
| enums | 下划线风格,全大写 | 不变 |
- {Number}
timeout- 语法糖,等价于{ deadline: Date.now() + timeout }
你可以通过 ctx.mypackage.myService.myRpc({ id: 1 }) 获取到 grpc service 的实例并执行 rpc 方法。
一般来说,message 是无需实例化的,只需传递普通的 object,grpc 会自动校验。当然你也可以使用 new app.grpcProto.mypackage.SomeMessage({ id: 1 })。
/**
* Unary RPC, such as `rpc Echo(Request) returns (Response) {}`
* @param {Object} data - data sent to sever
* @param {Object|grpc.Metadata} [metadata] - metadata, support plain object
* @param {Object} [options] - { timeout }
* @return {Promise} response promise chain
* @see http://www.grpc.io/docs/guides/concepts.html#unary-rpc
*/
// const client = ctx.grpc.<package>.<service>;
yield client.echo(data, metadata, options);
yield client.echo(data, options);/**
* Client Streaming RPC, such as `rpc EchoClientStream(stream Request) returns (Response) {}`
* @param {Object|grpc.Metadata} [metadata] - metadata, support plain object
* @param {Object} [options] - { timeout }
* @param {Function} [callback] - callback for response, `(err, response) => {}`
* @return {Stream} write stream
* @see http://www.grpc.io/docs/guides/concepts.html#client-streaming-rpc
*/
const stream = client.echoClientStream(meta, options, callback);
// const stream = client.echoClientStream(callback);
// const stream = client.echoClientStream(meta, callback);
// trigger order: metadata -> callback -> status
stream.once('metadata', meta => {});
stream.once('status', status => {});
stream.on('error', status => {});
// send data to server or end
stream.write(data1);
stream.write(data2);
stream.end(data4);/**
* Server Streaming RPC, such as `rpc EchoServerStream(Request) returns (stream Response) {}`
* @param {Object} data - data sent to sever
* @param {Object|grpc.Metadata} [metadata] - metadata, support plain object
* @param {Object} [options] - { timeout }
* @return {Stream} read stream
* @see http://www.grpc.io/docs/guides/concepts.html#server-streaming-rpc
*/
const stream = client.echoServerStream(data, meta, options);
// trigger order: metadata -> data -> status -> end
stream.on('data', response => {});
stream.on('end', response => {});
stream.once('metadata', meta => {});
stream.once('status', status => {});
stream.on('error', status => {});/**
* Bidirectional Streaming RPC, such as `rpc echoStreamStream(stream Request) returns (stream Response) {}`
* @param {Object|grpc.Metadata} [metadata] - metadata, support plain object
* @param {Object} [options] - { timeout }
* @return {Stream} duplex stream
* @see http://www.grpc.io/docs/guides/concepts.html#bidirectional-streaming-rpc
*/
const stream = client.echoStreamStream(meta, options);
// trigger order: metadata -> data -> status -> end
stream.on('data', response => {});
stream.on('end', () => {});
stream.once('metadata', meta => {});
stream.once('status', status => {});
stream.on('error', status => {});
// send data to server or end
stream.write(data1);
stream.write(data2);
stream.end(data3);参见 grpc.tests.js.
访问并发起 issue.