快速上手

如果你有通过 NodeJs 调用 SOFARPC 的需求.可以按照如下的文档来开始.

安装

首先按照文档安装

https://github.com/alipay/sofa-rpc-node

使用命令.

  1. $ npm install sofa-rpc-node --save

代码示例

暴露一个 RPC 服务,并发布到注册中心

  1. 'use strict';
  2. const { RpcServer } = require('sofa-rpc-node').server;
  3. const { ZookeeperRegistry } = require('sofa-rpc-node').registry;
  4. const logger = console;
  5. // 1. 创建 zk 注册中心客户端
  6. const registry = new ZookeeperRegistry({
  7. logger,
  8. address: '127.0.0.1:2181', // 需要本地启动一个 zkServer
  9. });
  10. // 2. 创建 RPC Server 实例
  11. const server = new RpcServer({
  12. logger,
  13. registry, // 传入注册中心客户端
  14. port: 12200,
  15. });
  16. // 3. 添加服务
  17. server.addService({
  18. interfaceName: 'com.nodejs.test.TestService',
  19. }, {
  20. async plus(a, b) {
  21. return a + b;
  22. },
  23. });
  24. // 4. 启动 Server 并发布服务
  25. server.start()
  26. .then(() => {
  27. server.publish();
  28. });

调用 RPC 服务(从注册中心获取服务列表)

  1. 'use strict';
  2. const { RpcClient } = require('sofa-rpc-node').client;
  3. const { ZookeeperRegistry } = require('sofa-rpc-node').registry;
  4. const logger = console;
  5. // 1. 创建 zk 注册中心客户端
  6. const registry = new ZookeeperRegistry({
  7. logger,
  8. address: '127.0.0.1:2181',
  9. });
  10. async function invoke() {
  11. // 2. 创建 RPC Client 实例
  12. const client = new RpcClient({
  13. logger,
  14. registry,
  15. });
  16. // 3. 创建服务的 consumer
  17. const consumer = client.createConsumer({
  18. interfaceName: 'com.nodejs.test.TestService',
  19. });
  20. // 4. 等待 consumer ready(从注册中心订阅服务列表...)
  21. await consumer.ready();
  22. // 5. 执行泛化调用
  23. const result = await consumer.invoke('plus', [ 1, 2 ], { responseTimeout: 3000 });
  24. console.log('1 + 2 = ' + result);
  25. }
  26. invoke().catch(console.error);

调用 RPC 服务(直连模式)

  1. 'use strict';
  2. const { RpcClient } = require('sofa-rpc-node').client;
  3. const logger = console;
  4. async function invoke() {
  5. // 不需要传入 registry 实例了
  6. const client = new RpcClient({
  7. logger,
  8. });
  9. const consumer = client.createConsumer({
  10. interfaceName: 'com.nodejs.test.TestService',
  11. serverHost: '127.0.0.1:12200', // 直接指定服务地址
  12. });
  13. await consumer.ready();
  14. const result = await consumer.invoke('plus', [ 1, 2 ], { responseTimeout: 3000 });
  15. console.log('1 + 2 = ' + result);
  16. }
  17. invoke().catch(console.error);

暴露和调用 protobuf 接口

接口定义

通过 *.proto 来定义接口

  1. syntax = "proto3";
  2. package com.alipay.sofa.rpc.test;
  3. // 可选
  4. option java_multiple_files = false;
  5. service ProtoService {
  6. rpc echoObj (EchoRequest) returns (EchoResponse) {}
  7. }
  8. message EchoRequest {
  9. string name = 1;
  10. Group group = 2;
  11. }
  12. message EchoResponse {
  13. int32 code = 1;
  14. string message = 2;
  15. }
  16. enum Group {
  17. A = 0;
  18. B = 1;
  19. }

服务端代码

  1. 'use strict';
  2. const antpb = require('antpb');
  3. const protocol = require('sofa-bolt-node');
  4. const { RpcServer } = require('sofa-rpc-node').server;
  5. const { ZookeeperRegistry } = require('sofa-rpc-node').registry;
  6. const logger = console;
  7. // 传入 *.proto 文件存放的目录,加载接口定义
  8. const proto = antpb.loadAll('/path/proto');
  9. // 将 proto 设置到协议中
  10. protocol.setOptions({ proto });
  11. const registry = new ZookeeperRegistry({
  12. logger,
  13. address: '127.0.0.1:2181',
  14. });
  15. const server = new RpcServer({
  16. logger,
  17. protocol, // 覆盖协议
  18. registry,
  19. codecType: 'protobuf', // 设置默认的序列化方式为 protobuf
  20. port: 12200,
  21. });
  22. server.addService({
  23. interfaceName: 'com.alipay.sofa.rpc.test.ProtoService',
  24. }, {
  25. async echoObj(req) {
  26. req = req.toObject({ enums: String });
  27. return {
  28. code: 200,
  29. message: 'hello ' + req.name + ', you are in ' + req.group,
  30. };
  31. },
  32. });
  33. server.start()
  34. .then(() => {
  35. server.publish();
  36. });

客户端代码

  1. 'use strict';
  2. const antpb = require('antpb');
  3. const protocol = require('sofa-bolt-node');
  4. const { RpcClient } = require('sofa-rpc-node').client;
  5. const { ZookeeperRegistry } = require('sofa-rpc-node').registry;
  6. const logger = console;
  7. // 传入 *.proto 文件存放的目录,加载接口定义
  8. const proto = antpb.loadAll('/path/proto');
  9. // 将 proto 设置到协议中
  10. protocol.setOptions({ proto });
  11. const registry = new ZookeeperRegistry({
  12. logger,
  13. address: '127.0.0.1:2181',
  14. });
  15. async function invoke() {
  16. const client = new RpcClient({
  17. logger,
  18. protocol,
  19. registry,
  20. });
  21. const consumer = client.createConsumer({
  22. interfaceName: 'com.alipay.sofa.rpc.test.ProtoService',
  23. });
  24. await consumer.ready();
  25. const result = await consumer.invoke('echoObj', [{
  26. name: 'gxcsoccer',
  27. group: 'B',
  28. }], { responseTimeout: 3000 });
  29. console.log(result);
  30. }
  31. invoke().catch(console.error);