0.0.6 • Published 5 years ago
egg-grpc-service v0.0.6
egg-grpc-server
Install
npm install egg-grpc-service --save
Usage
// {app_root}/config/plugin.js
exports.grpcServer = {
enable: true,
package: 'egg-grpc-service',
};
Configuration
// {app_root}/config/config.default.js
exports.grpcServer = {
port: 50051, // grpc监听端口
host: '127.0.0.1', // 监听地址
timeOut: 5000, // 超时时间
protoDir: 'app/proto', // proto文件所在文件夹
grpcDir: 'app/grpc', // 接口实现所在文件夹
startAfterInit: false, // 默认启动 grpc server
errorHandle(error) { // 全局统一错误处理
// TODO
// this 为ctx,接受error参数
}
};
see config/config.default.js for more detail.
Example
实现
- 插件在app上挂载了GrpcServer的class,在项目启动时实例化并调用start方法
- 在cluster模式下,会通过项目根目录下"pid"临时文件确定是哪一个worker进程启动grpc server
启动
- grpc server 可通过配置项
startAfterInit
控制是否自启动,默认false
不自启动 - 启动方式一:直接在app.js实例化并启动【不推荐】
// ${app_root}/app.js
module.exports = app => {
const grpcServer = new app.GrpcServer(app);
grpcServer.start();
Reflect.defineProperty(app, 'grpcServer', { value: grpcServer });
};
启动方式二:配置项
startAfterInit
设置为true自启动【推荐】proto/xxx.proto service中的的接口名 grpc/xxx.js 中的接口名 二者应当同名(grpc/xxx.js文件名可不大写)
proto 文件,可通过config.dir
配置目录,默认app/proto
// {app_root}/app/protos/hello.proto
syntax = "proto3";
package egg.node;
service Hello {
rpc sayHello (HelloReq) returns (HelloResp) {};
rpc buf (stream BufRequest) returns (stream BufResp) {};
}
message HelloReq {
string name = 1;
int32 group = 2;
}
message HelloResp {
int32 code = 1;
string message = 2;
}
message BufRequest {
string name = 1;
}
message BufResp {
string message = 1;
int32 code = 2;
}
接口实现,this
为egg
的Context
,接受一个参数为请求的call
(grpc中的call,call.request
为请求参数)
// {app_root}/app/grpc/hello.js
'use strict';
exports.sayHello = async function(call) {
const { request } = call;
function sleep(time) {
return new Promise(reslove => {
setTimeout(() => {
reslove();
}, time);
});
}
await sleep(1000);
return {
code: 200,
message: 'hello ' + request.name + ', you are in ' + request.group,
};
};
exports.buf = function(call) {
call.on('data', data => {
console.log('service recive data' + JSON.stringify(data));
call.write('hello' + data.name);
});
call.on('end', () => {
call.end();
});
};
单元测试
- 在
unittest
环境中app挂载了grpcServerTest
方法用于测试
const { assert, app } = require('egg-mock/bootstrap');
const path = require('path');
const PROTO_PATH_HELLO = path.join(__dirname, '../app/proto/hello.proto');
const grpc = require('grpc');
describe('test/grpc-server.test.js', () => {
let test;
before(async () => {
await app.ready();
test = app.grpcServerTest
});
it('should visit hello by grpcServer.hello', async () => {
const res = await test.call(app, {
proto: PROTO_PATH_HELLO,
implement: 'sayHello',
service: 'Hello', // 默认第一个service
data: { name: 'leo', group: 1 },
});
assert(res.code === 200);
});
it('should visit by stream test', () => {
const call = test.call(app, {
proto: PROTO_PATH_HELLO,
implement: 'buf',
});
call.write({ name: 'leo' });
call.end();
call.on('data', function(data) {
console.log('buf-resp-data', data);
});
call.on('end', function() {
// TODO
});
});
Questions & Suggestions
Please open an issue here.