Node.js 使用grpc 静态编译后与动态用方法不一致问题

427 阅读2分钟

Node.js 使用grpc静态编码的坑

先介绍一下场景:

最近公司要移植一个 web 端的功能到 pc 端作为单机版的小应用。

web 端使用的是vue开发,为了效率也就定下了用 electron + vue 直接套用原来 web 端的代码改吧改吧。

由于这个功能 web 端的后端使用的是 python 调用的 C++ 的服务做了个中转,转向桌面端就没必要再➕一层,况且 electron 自带 node 这个调用的功能自然也就落到自己头上(终于做上了全干工程师)。 C++ 将它带服务打包成 window 平台的可执行程序,通过 grpc (对grpc不了解的同学可以点进去看下)交换数据。

简单介绍一下grpc调用方式

官网提供了常用的语言支持 C#/ .NET,C++,Dart,Go,Java,Kotlin,Node等。

  1. 动态加载协议使用:直接引入proto协议文件
  2. 静态编码为对应平台使用:编译为对应语言平台的文件作为包使用

动态导入的方式调用方法与定义在协议内定义的在 service 内的方法一致,主要说一下静态编码后使用。

下面是官方提供的一个协议

在协议 helloworld.proto 基础上添加了一个方法以及方法的参数和响应

syntax = "proto3";
​
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";
​
package helloworld;
​
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
  rpc SayHelloAgain(HelloRequestAgain) returns (HelloReplyAgain) {} // 这里是新增的
}
​
message HelloReplyAgain { 
  string nameAgain = 1;  // 待会这里的设置方法就与动态导入的有区别
}
​
message HelloRequestAgain {
  string messageAgain = 1;
}
​
message HelloRequest {
  string name = 1;
}
​
message HelloReply {
  string message = 1;
}
​

通过grpc-tools 包将协议编译为 js 文件后会得到两个文件

  • helloworld_grpc_pb.js
  • helloworld_pb.js

这张截图为 helloworld_pb.js 中编译后的内容,该方法就是就是设置协议中HelloReplyAgain 中设置nameAgain 的方法,这个方法只是一个案例,所有的小驼峰命名都会变的很奇怪。调用的时候最好在编译后的文件查看后调用。否则很容易出错。因为他不按套路出牌。

截屏2023-02-22 23.29.11.png

可以看到这个驼峰命名已经变成了setNameagain,而动态导入协议的设置方法为setNameAgain

我在开发中开始使用的动态导入,使用编译后的文件后设置参数的方法就报错了,最后找到了是这个原因导致的。

本文只是记录一下自己工作中遇到的一个坑,希望给后续大家遇到这种情况的提个醒。

结束语:主要就是记录node使用grpc的动态导入和编译为node版本后设置参数的方法名的坑。欢迎大家补充