egg-sofa-rpc
v3.0.0
Published
SOFARPC Plugin for egg
Downloads
37
Readme
egg-sofa-rpc
SOFARPC plugin for egg framework
Install
$ npm i egg-sofa-rpc --save
Usage
Enable the plugin
Change ${app_root}/config/plugin.js
to enable SOFARPC plugin:
exports.sofaRpc = {
enable: true,
package: 'egg-sofa-rpc',
};
RPC Service Discovery
By default, We use zookeeper for service discovery. Therefore you need to configure the zk address:
// ${app_root}/config/config.${env}.js
config.rpc = {
registry: {
address: '127.0.0.1:2181', // configure your real zk address
},
};
We plan to provide more implementations of service discovery. And also you can implement it by yourself, you can follow this article
RPC Client
By using the plugin, you can call rpc services provided by other system.
1. Get the RPC Interface Definition
We use protobuf interface definition lanaguge to describe the RPC service. So you need to get the *.proto files and put them into ${app_root}/proto
folder
2. Global RPC Client Configuration
Configure RPC Client information in ${app_root}/config/config.{env}.js:
// ${app_root}config/config.${env}.js
exports.rpc = {
client: {
responseTimeout: 3000,
},
};
responseTimeout
(optional): RPC timeout in milliseconds, default value is 3000
3. Configure the Interface in proxy.js
${app_root}/config/proxy.js
is a very important config file for rpc client, you should configure the services you needed, then executing the egg-rpc-generator
tool to generate the proxy files.
Let's see a simple example of proxy.js. It declare a interface named: com.alipay.sofa.rpc.test.ProtoService
provided by sofarpc
application
'use strict';
module.exports = {
services: [{
appName: 'sofarpc',
api: {
ProtoService: 'com.alipay.sofa.rpc.test.ProtoService',
},
}],
};
Refer this acticle for more details
4. Generate the Proxy
Run egg-rpc-generator
to generate the proxy files. After running success, it will generate a file: ProtoService.js
under ${app_root}/app/proxy
$ egg-rpc-generator
[EggRpcGenerator] framework: /egg-rpc-demo/node_modules/egg, baseDir: /egg-rpc-demo
[ProtoRPCPlugin] found "com.alipay.sofa.rpc.test.ProtoService" in proto file
[ProtoRPCPlugin] save all proto info into "/egg-rpc-demo/run/proto.json"
5. Call the Service
You can call the RPC service by using ctx.proxy.proxyName
. The proxyName is key
value of api object you configure in proxy.js. In our example, it's ProtoService, and proxyName using lower camelcase, so it's ctx.proxy.protoService
'use strict';
const Controller = require('egg').Controller;
class HomeController extends Controller {
async index() {
const { ctx } = this;
const res = await ctx.proxy.protoService.echoObj({
name: 'gxcsoccer',
group: 'A',
});
ctx.body = res;
}
}
module.exports = HomeController;
As above, you can call remote service as a local method.
RPC Server
By using the plugin, you also can publish your own RPC service to other system.
1. Define the RPC Interface
Writing the *.proto files, and put them into ${app_root}/proto
folder
# ProtoService.proto
syntax = "proto3";
package com.alipay.sofa.rpc.protobuf;
option java_multiple_files = true; // 可选
option java_outer_classname = "ProtoServiceModels"; // 可选
service ProtoService {
rpc echoObj (EchoRequest) returns (EchoResponse) {}
}
message EchoRequest {
string name = 1;
Group group = 2;
}
message EchoResponse {
int32 code = 1;
string message = 2;
}
enum Group {
A = 0;
B = 1;
}
2. Global RPC Server Configuration
Configure RPC Server information in ${app_root}/config/config.{env}.js:
module.exports = {
rpc: {
server: {
namespace: 'com.nodejs.rpc',
},
},
},
namespace
(required): the default namespace of all rpc serviceselfPublish
(optional): whether every node process publish service independent, default is trueport
(optional): the TCP port will be listen onmaxIdleTime
(optional): server will disconnect the socket if idle for long timeresponseTimeout
(optional): Number of milliseconds to wait for a response to begin arriving back from the remote system after sending a requestcodecType
(optional): recommended serialization method,default is protobuf
3. Implemenation the RPC Interface
Put your implementation code under ${app_root}/app/rpc
folder
// ${app_root}/app/rpc/ProtoService.js
exports.echoObj = async function(req) {
return {
code: 200,
message: 'hello ' + req.name + ', you are in ' + req.group,
};
};
4. RPC Unittest in Eggjs
'use strict';
const mm = require('egg-mock');
describe('test/index.test.js', () => {
let app;
before(async function() {
app = mm.app({
baseDir: 'apps/rpcserver',
});
await app.ready();
});
after(async function() {
await app.close();
});
it('should invoke HelloService', done => {
app.rpcRequest('com.alipay.nodejs.HelloService')
.invoke('hello')
.send([ 'gxcsoccer' ])
.expect('hello gxcsoccer', done);
});
});
For more details of app.rpcRequest
, you can refer to this acticle
Docs
- RPC in Nodejs Part One
- Cross-Language Interoperability between Eggjs & SOFA
- Custom Service Discovery in Eggjs
- RPC Proxy Configuration in Eggjs
- RPC Unittest in Eggjs
How to Contribute
Please let us know how can we help. Do check out issues for bug reports or suggestions first.
To become a contributor, please follow our contributing guide.