ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

typescript grpc server client 一问一答 简单工具类(亲测可用,带注释、测试类)

2021-07-05 18:08:31  阅读:192  来源: 互联网

标签:typescript const proto grpc param server Consts


  • 工具类结构
    在这里插入图片描述

  • 目录结构
    在这里插入图片描述

  • package.json 依赖

主要是proto-loader grpc 缺了啥补上啥把

"dependencies": {
    "@grpc/proto-loader": "^0.6.1",
    "@nestjs/common": "^7.6.15",
    "@nestjs/config": "^0.6.3",
    "@nestjs/core": "^7.6.15",
    "@nestjs/microservices": "^7.6.15",
    "@nestjs/mongoose": "^7.2.4",
    "@nestjs/platform-express": "^7.6.15",
    "@nestjs/schedule": "^0.4.3",
    "@nestjs/swagger": "^4.8.0",
    "@types/cron": "^1.7.2",
    "class-transformer": "^0.4.0",
    "class-validator": "^0.13.1",
    "cron": "^1.8.2",
    "dayjs": "^1.10.4",
    "grpc": "^1.24.6",
    "md5": "^2.3.0",
    "mongoose": "^5.12.3",
    "nest-winston": "^1.4.0",
    "nuid": "^1.1.4",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^6.6.6",
    "schedule": "^0.5.0",
    "swagger-ui-express": "^4.1.6",
    "winston": "^3.3.3",
    "winston-daily-rotate-file": "^4.5.1"
  },
  "devDependencies": {
    "@nestjs/cli": "^7.6.0",
    "@nestjs/schematics": "^7.3.0",
    "@nestjs/testing": "^7.6.15",
    "@types/express": "^4.17.11",
    "@types/jest": "^26.0.22",
    "@types/logform": "^1.10.1",
    "@types/node": "^14.14.36",
    "@types/supertest": "^2.0.10",
    "@types/winston": "^2.4.4",
    "@typescript-eslint/eslint-plugin": "^4.19.0",
    "@typescript-eslint/parser": "^4.19.0",
    "eslint": "^7.22.0",
    "eslint-config-prettier": "^8.1.0",
    "eslint-plugin-prettier": "^3.3.1",
    "jest": "^26.6.3",
    "prettier": "^2.2.1",
    "supertest": "^6.1.3",
    "ts-jest": "^26.5.4",
    "ts-loader": "^8.0.18",
    "ts-node": "^9.1.1",
    "tsconfig-paths": "^3.9.0",
    "typescript": "^4.2.3"
  }
  • 工具类代码:GrpcUtil
const path = require('path');
const grpc = require('grpc');


export class GrpcUtil {

  /**
   * 返回的client直接调用方法传入参数例如,client.hello(requestObj,function(err,res){})
   * @param protoPath proto文件的相对路径地址(当前路径为GrpcUtil类所在的路径)
   * @param ip grpc服务器IP地址
   * @param port  grpc服务器端口
   * @param packageName  proto文件里的package
   * @param serviceName proto文件里的service
   */
  static getClient(protoPath:string, ip:string, port:number, packageName:string, serviceName:string){
    const PROTO_PATH = path.join(__dirname,protoPath);
    const protoLoader = require('@grpc/proto-loader');
    const packageDefinition = protoLoader.loadSync(
      PROTO_PATH,
      {
        keepCase: true,
        longs: String,
        enums: String,
        defaults: true,
        oneofs: true
      }
    );
    const protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
    const packageObj = protoDescriptor[packageName];
    // 客户端
    const client = new packageObj[serviceName](
      ip+':'+port,
      grpc.credentials.createInsecure()
    );
    return client
  }

  /**
   * 关闭客户端
   * @param client
   */
  static closeClient(client){
    if (client){
      try {
        client.close()
      }catch (e) {

      }
    }
  }
  /**
   * 启动grpc服务端
   * @param protoPath proto文件的相对路径地址(当前路径为GrpcUtil类所在的路径)
   * @param ip grpc服务器IP地址
   * @param port  grpc服务器端口
   * @param packageName  proto文件里的package
   * @param serviceName proto文件里的service
   * @param serviceImpl proto里定义的rpc函数的实现,例如hello函数的实现  {hello:(requestObj,callback)=>{console.log(requestObj.request);callback(null,'hi')}}
   */
  static startServer(protoPath:string, ip:string, port:number, packageName:string, serviceName:string,serviceImpl:object){
    const PROTO_PATH = path.join(__dirname,protoPath);
    const protoLoader = require('@grpc/proto-loader');
    const packageDefinition = protoLoader.loadSync(
      PROTO_PATH,
      {
        keepCase: true,
        longs: String,
        enums: String,
        defaults: true,
        oneofs: true
      }
    );
    const protoDescriptor = grpc.loadPackageDefinition(packageDefinition);
    const packageObj = protoDescriptor[packageName];
    // 服务端
    const server = new grpc.Server();
    server.addService(
      packageObj[serviceName].service,
      serviceImpl
    );
    server.bind(ip+':'+port, grpc.ServerCredentials.createInsecure());
    server.start();
    return server
  }

  /**
   * 关闭服务器
   * @param server
   */
  static closeServer(server){
    if (server){
      try {
        server.close()
      }catch (e) {

      }
    }
  }
}
  • 测试类
import {GrpcUtil} from "./GrpcUtil";

enum CodeType {
  CodeType_ZERO,
    SUCCESS,
    FAILED
}
export class GrpcUtilTest {
  static test(){
    const Consts = {
       serviceName : 'strategy.instances',
       protoPath : './MarketData.proto',
       ip:'192.168.0.140',
       port:5000,
       packageName : 'market_data_collector',
       grpcServiceName : 'MarketDataService'
    }
    /**
     * 注意  localhost 和 自己IP192.168.0.140是不同的,不要服务器和客户端地址不一样!!!会连不上
     */
    let server = GrpcUtil.startServer(Consts.protoPath,Consts.ip,Consts.port,Consts.packageName,Consts.grpcServiceName,{
      loadStrategyInstance:(request,callback)=>{
        console.log('服务器收到请求');
        console.log(request.request);
        callback(null,{code:CodeType.SUCCESS,msg:'我是服务端,我收到了你的消息'})
      }
    })
    let client = GrpcUtil.getClient(Consts.protoPath,Consts.ip,Consts.port,Consts.packageName,Consts.grpcServiceName)
    client.loadStrategyInstance({id:'hhhhh'},(err,res)=>{
      if (err){
        console.log(err);
      }
      console.log('客户端收到结果');
      console.log(res);
    })
  }
}
  • 测试使用到的proto文件

我这边src->grpc下的proto文件是不会自动复制到dist目录去的,所以我是手动复制过去的,复制一次就行了,修改的时候都再手动覆盖过去
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 运行测试
    在这里插入图片描述
    以开发模式运行项目
    在这里插入图片描述

  • 测试结果
    在这里插入图片描述

 

标签:typescript,const,proto,grpc,param,server,Consts
来源: https://blog.51cto.com/humorchen/2984212

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有