SpringBoot+Kotlin中使用GRPC實(shí)現(xiàn)服務(wù)通信的示例代碼
示例項(xiàng)目見:kotlin-grpc
一、導(dǎo)入依賴:
import com.google.protobuf.gradle.* plugins { id("org.springframework.boot") version "2.3.1.RELEASE" id("io.spring.dependency-management") version "1.0.9.RELEASE" id("org.asciidoctor.convert") version "1.5.9.2" kotlin("jvm") version "1.6.0" kotlin("plugin.spring") version "1.6.0" id("com.google.protobuf") version "0.9.2" } repositories { mavenCentral() } group = "com.whrss.kotlin-grpc" version = "0.0.1-SNAPSHOT" java.sourceCompatibility = JavaVersion.VERSION_1_8 java.targetCompatibility = JavaVersion.VERSION_1_8 sourceSets.main { java.srcDirs("src/main/kotlin") } extra["spring-restdocs.version"] = "2.0.5.BUILD-SNAPSHOT" val snippetsDir by extra { file("build/generated-snippets") } dependencies { implementation("com.google.protobuf:protobuf-java:3.22.2") implementation("io.grpc:grpc-protobuf:1.53.0") implementation("com.google.protobuf:protobuf-kotlin:3.22.2") implementation("io.grpc:grpc-kotlin-stub:1.3.0") implementation("io.grpc:grpc-netty:1.56.1") implementation("io.grpc:grpc-all:1.56.1") } protobuf { protoc { artifact = "com.google.protobuf:protoc:3.19.4" } plugins { id("grpc") { artifact = "io.grpc:protoc-gen-grpc-java:1.40.1" } id("grpckt") { artifact = "io.grpc:protoc-gen-grpc-kotlin:1.3.0:jdk8@jar" } } // Enable Kotlin generation generateProtoTasks { all().forEach { it.plugins { id("grpc") id("grpckt") } } }}
二、設(shè)置Proto
將 proto
文件放在 src/mian/proto
目錄下
syntax = "proto3"; import "google/api/annotations.proto"; option java_multiple_files = true; package hello_world.v1; service HelloWorldService{ rpc GetUserInfo (GetUserRequest) returns (GetUserReply) { option (google.api.http) = { get: "/api/v1/users" }; } } message GetUserRequest{ // 用戶showId string userId = 1; } message GetUserReply{ // 用戶showId string userId = 1; }
執(zhí)行 ./gradlew clean build
build成功則會(huì)在 build/generated/source/proto/main
下生成對(duì)應(yīng)的 grpc
、 grpckt
、 java
文件在程序中可以直接導(dǎo)包引入
三、Server端
寫一個(gè) service
import hello_world.v1.GetUserReply import hello_world.v1.GetUserRequest import hello_world.v1.HelloWorldServiceGrpcKt class Service : HelloWorldServiceGrpcKt.HelloWorldServiceCoroutineImplBase() { override suspend fun getUserInfo(request: GetUserRequest) : GetUserReply { println("getItemStatistics exec") return GetUserReply.newBuilder() .setUserId(request.userId) .build() } }
在 main
入口引入啟動(dòng)
import io.grpc.ServerBuilder fun main() { helloServer() } fun helloServer() { val helloService = Service() val server = ServerBuilder .forPort(15001) .addService(helloService) .build() Runtime.getRuntime().addShutdownHook(Thread { server.shutdown() server.awaitTermination() }) server.start() println("server start") server.awaitTermination() println("server restart") }
四、Client 端
import hello_world.v1.GetUserRequest import hello_world.v1.HelloWorldServiceGrpc import io.grpc.ManagedChannelBuilder fun main() { val channel = ManagedChannelBuilder.forAddress("localhost", 15001).usePlaintext() val stub = HelloWorldServiceGrpc.newBlockingStub(channel.build()) val response = stub.getUserInfo(GetUserRequest.newBuilder().setUserId("0").build()) println(response) }
五、一些坑
io.grpc 和 com.google的一些依賴是有關(guān)聯(lián)的,如果依賴版本之間有巨大差異,是會(huì)導(dǎo)致運(yùn)行錯(cuò)誤的。比如我之前使用到了一個(gè)google的一個(gè)特別老的依賴:com.google.code.google-collections:google-collect:snapshot-20080530,導(dǎo)致了我程序運(yùn)行時(shí)提示:
Exception in thread "main" java.lang.NoSuchMethodError: 'void com.google.common.base.Preconditions.checkArgument(boolean, java.lang.String, char, java.lang.Object)'
at io.grpc.Metadata$Key.validateName(Metadata.java:754)
at io.grpc.Metadata$Key.<init>(Metadata.java:762)
at io.grpc.Metadata$Key.<init>(Metadata.java:671)
at io.grpc.Metadata$AsciiKey.<init>(Metadata.java:971)
at io.grpc.Metadata$AsciiKey.<init>(Metadata.java:966)
at io.grpc.Metadata$Key.of(Metadata.java:708)
at io.grpc.Metadata$Key.of(Metadata.java:704)
at io.grpc.internal.GrpcUtil.<clinit>(GrpcUtil.java:99)
at io.grpc.netty.Utils.<clinit>(Utils.java:83)
at io.grpc.netty.UdsNettyChannelProvider.isAvailable(UdsNettyChannelProvider.java:34)
at io.grpc.ManagedChannelRegistry$ManagedChannelPriorityAccessor.isAvailable(ManagedChannelRegistry.java:211)
at io.grpc.ManagedChannelRegistry$ManagedChannelPriorityAccessor.isAvailable(ManagedChannelRegistry.java:207)
at io.grpc.ServiceProviders.loadAll(ServiceProviders.java:68)
at io.grpc.ManagedChannelRegistry.getDefaultRegistry(ManagedChannelRegistry.java:101)
at io.grpc.ManagedChannelProvider.provider(ManagedChannelProvider.java:43)
at io.grpc.ManagedChannelBuilder.forAddress(ManagedChannelBuilder.java:39)
at com.ck567.kotlingrpc.ClientKt.main(Client.kt:9)
at com.ck567.kotlingrpc.ClientKt.main(Client.kt)
在google是發(fā)現(xiàn)不了具體的問題的,可以注意一下。
上面的依賴版本都是基于對(duì)應(yīng)spring boot和 kotlin 版本的,如果你的版本不適配,可能也需要折騰一下,但問題應(yīng)該不是很大。
到此這篇關(guān)于SpringBoot+Kotlin中使用GRPC實(shí)現(xiàn)服務(wù)通信的示例代碼的文章就介紹到這了,更多相關(guān)SpringBoot Kotlin GRPC服務(wù)通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java通過httpclient比較重定向和請(qǐng)求轉(zhuǎn)發(fā)
這篇文章主要介紹了Java通過httpclient比較重定向和請(qǐng)求轉(zhuǎn)發(fā),HttpClient?4.x?版本,get請(qǐng)求方法會(huì)自動(dòng)進(jìn)行重定向,而post請(qǐng)求方法不會(huì)自動(dòng)進(jìn)行重定向,需要的朋友可以參考下2023-04-04Java處理時(shí)間格式CST和GMT轉(zhuǎn)換方法示例
這篇文章主要給大家介紹了關(guān)于Java處理時(shí)間格式CST和GMT轉(zhuǎn)換方法的相關(guān)資料,相信很多小伙伴在時(shí)間格式轉(zhuǎn)換的時(shí)候非常頭疼,文中通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2023-09-09springboot+thymeleaf國(guó)際化之LocaleResolver接口的示例
本篇文章主要介紹了springboot+thymeleaf國(guó)際化之LocaleResolver的示例 ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11Springboot實(shí)現(xiàn)Activemq死信隊(duì)列詳解
這篇文章主要介紹了Springboot實(shí)現(xiàn)Activemq死信隊(duì)列詳解,Activemq服務(wù)端配置重新投遞次數(shù)超過?MaximumRedeliveries?,則會(huì)進(jìn)入死信隊(duì)列,默認(rèn)情況,有一個(gè)死信隊(duì)列:AcitveMQ.DLQ,所有的消息都投遞到此隊(duì)列,包括過期消息,重投遞失敗消息,需要的朋友可以參考下2023-12-12使用Fastjson進(jìn)行JSON生成與解析的新手指南
Fastjson是阿里巴巴開源的高性能 JSON 庫(kù),適用于 Java 對(duì)象的序列化和反序列化,本文將詳細(xì)介紹一下如何使用Fastjson進(jìn)行json的生成與解析吧2025-04-04java.lang.OutOfMemoryError: Metaspace異常解決的方法
這篇文章主要介紹了java.lang.OutOfMemoryError: Metaspace異常解決的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Java虛擬機(jī)之對(duì)象創(chuàng)建過程與類加載機(jī)制及雙親委派模型
這篇文章主要給大家介紹了關(guān)于Java虛擬機(jī)之對(duì)象創(chuàng)建過程與類加載機(jī)制及雙親委派模型的相關(guān)資料,本文通過示例代碼以及圖文介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2021-11-11