为Vert.x/kotlin添加gRPC
程序员文章站
2023-12-29 18:50:22
...
为Vert.x/kotlin添加gRPC
前些日子,因为项目需求,决定用grpc实现对新系统的调用,项目的架子用的是Vert.x/kotlin,在添加grpc时出现了一些问题,网上这部分的资料并不多,这几个官网也很久没有更新相关的文档内容,所以决定把整个流程记录下来。
添加依赖
我们是用gradle构建的项目,这部分功能涉及到的依赖如下:
plugins {
....
id 'com.google.protobuf' version '0.8.12'
}
ext {
vertxVersion = '3.9.1'
grpcKotlinVersion = "0.1.2"
}
dependencies{
....
//grpc
implementation "io.grpc:grpc-kotlin-stub:$grpcKotlinVersion"
implementation "io.vertx:vertx-grpc:$vertxVersion"
}
需要注意
- vertx-grpc,使用vert.x的版本
- grpckotlin,可以不依赖,使用这个会额外编译出kotlin的类,视觉上感觉更优雅,但是实际上还是再调用的java编译出的文件,本质上没有啥用
之后是protobuf的部分
protobuf {
protoc {
path
artifact = "com.google.protobuf:protoc:3.4.0"
}
plugins {
grpc {
artifact = "io.vertx:protoc-gen-grpc-java:$grpcVersion"
}
grpckt {
artifact = "io.grpc:protoc-gen-grpc-kotlin:$grpcKotlinVersion"
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
grpckt {}
}
}
}
- grpckt,这部分就是上面提到编译出kotlin相关类的部分
如果需要指定生成目录可以按照如下修改
protobuf {
generatedFilesBaseDir = "src"//指定base目录
....
generateProtoTasks {
all()*.plugins {
grpc { outputSubDir = "java" }//指定具体的目录
grpckt { outputSubDir = "kotlin" }//指定具体的目录
}
}
}
- 具体在哪个包下需要看proto文件里面的设置了
如果需要设置读取proto的路径
sourceSets {
main {
proto {
srcDir 'src/main/proto'
}
}
}
- 这样就会按照srcDir的路径去找proto文件
依赖部分这样就完成了
编译
按照上面的srcDir的路径把需要编译的proto文件扔进去,或者扔到默认的路径(src/main/proto)
proto文件这里就不展示了,放完之后执行build,或者点开右边的Grable工具栏,找到other,在里面双击generateProto,如下图
等待编译完成,之后可以看到在指定的,目录下会生成编译好的文件,如下图所示
使用
服务方
- 如果使用了grpckotlin,可以定义一个server继承编译出的
*GrpcKt.*ImplBase()
重写里面的定义的接口方法,具体方法的实现就不赘述了
最后在vert.x的项目中新建一个Verticle去承载这个server,或者直接在主Verticle中的start中添加
val gRPCServer = VertxServerBuilder
.forPort(vertx,"your port")
.addService("YourGrpcServer()")
.build()
gRPCServer.start { ar ->
if (ar.succeeded())
log { "gRPCServer started on port "+"your port") }
else
log { "gRPCServer started error" }
- 未使用grpckotlin,定义一个server继承编译出的
*Grpc.*ImplBase(),其他部分和上边相同
调用方
- 定义channel
val channel = VertxChannelBuilder
.forAddress("your server address", "your port")
.usePlaintext()
.build()
- 定义stub
- 如果使用了grpckotlin
val stub = *GrpcKt.*Stub(channel)
- 未使用
val stub = *Grpc.*Stub(channel)
- 具体用哪种stub根据自己的使用场景选择
- 调用接口
val response = stub.*(*.newBuilder().build())
最后
启动服务,调用方就可以调用了