文章目录
Declare Plugin and Repository
pluginManagement {
plugins {
id("org.jetbrains.kotlin.jvm") version "2.0.0" apply false
id("com.google.protobuf") version "0.9.2" apply false
}
}
dependencyResolutionManagement {
repositoriesMode = RepositoriesMode.PREFER_SETTINGS
repositories {
mavenLocal()
google()
mavenCentral()
gradlePluginPortal()
}
}
Apply Plugin and Dependency
plugins {
id("org.jetbrains.kotlin.jvm")
id("com.google.protobuf")
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(8)
}
}
dependencies {
api("io.github.hellogoogle2000:kotlin-commons:+")
api("com.google.protobuf:protobuf-kotlin:3.22.2")
api("io.grpc:grpc-protobuf:1.54.0")
api("io.grpc:grpc-netty-shaded:1.54.0")
api("io.grpc:grpc-kotlin-stub:1.3.0")
api("org.apache.tomcat:annotations-api:6.0.53")
}
Configure Code Generation Dir and Tools
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.22.2"
}
plugins {
create("rpc-java") {
artifact = "io.grpc:protoc-gen-grpc-java:1.54.0"
}
create("rpc-kotlin") {
artifact = "io.grpc:protoc-gen-grpc-kotlin:1.3.0:jdk8@jar"
}
}
generateProtoTasks {
all().forEach {
it.plugins {
create("rpc-java")
}
it.plugins {
create("rpc-kotlin")
}
it.builtins {
create("kotlin")
}
}
}
}
Compile Proto File
syntax = "proto3";
package com.kotlin.sample;
option java_multiple_files = true;
option java_package = "com.kotlin.sample.proto";
option java_outer_classname = "UserProto";
message UserListWrapper {
repeated User list = 1;
}
message User {
int32 id = 1;
string name = 2;
repeated Course courses = 3;
}
message Course {
int32 id = 1;
string name = 2;
}
message GetUserRequest {
int32 pageSize = 1;
int32 pageIndex = 2;
}
message GetUserResponse {
repeated User users = 1;
}
service UserService {
rpc GetUserList (GetUserRequest) returns (GetUserResponse) {}
}
Auto Generate Class Files
rebuild project, plugin will auto-generate all required files
Write and Read Data Directly Through PB File
import com.kotlin.sample.proto.User
import com.kotlin.sample.proto.UserListWrapper
import com.kotlin.sample.proto.user
import com.kotlin.sample.proto.userListWrapper
import x.kotlin.commons.string.UUID
import kotlin.io.path.Path
import kotlin.io.path.inputStream
import kotlin.io.path.outputStream
fun main() {
// create user objects
val users = mutableListOf<User>()
repeat(2) {
val user = user {
id = UUID.hashCode()
name = UUID.short()
}
users.add(user)
}
// create pb file
val path = Path("/home/easing/temp/users.pb")
// write to pb file
val userListWrapper1 = userListWrapper { list.addAll(users) }
path.outputStream().use { userListWrapper1.writeTo(it) }
// read from pb file
val userListWrapper2 = path.inputStream().use { UserListWrapper.parser().parseFrom(it) }
println(userListWrapper1 == userListWrapper2)
}
Create a Google RPC Server Transmitting with ProtoBuffer
import com.kotlin.sample.proto.*
import io.grpc.ServerBuilder
import x.kotlin.commons.string.UUID
private class UserService : UserServiceGrpcKt.UserServiceCoroutineImplBase() {
override suspend fun getUserList(request: GetUserRequest): GetUserResponse {
val users = mutableListOf<User>()
repeat(2) {
val user = user {
id = UUID.hashCode()
name = UUID.short()
}
users.add(user)
}
return getUserResponse { this.users.addAll(users) }
}
}
fun main() {
val server = ServerBuilder
.forPort(10001)
.addService(UserService())
.build()
server.start()
server.awaitTermination()
}
Create a Google RPC Client
import com.kotlin.sample.proto.UserServiceGrpcKt
import com.kotlin.sample.proto.getUserRequest
import io.grpc.ManagedChannelBuilder
suspend fun main() {
val channel = ManagedChannelBuilder
.forTarget("localhost:10001")
.usePlaintext()
.build()
val service = UserServiceGrpcKt.UserServiceCoroutineStub(channel)
val request = getUserRequest {
pageSize = 10
pageIndex = 0
}
val getUserResponse = service.getUserList(request)
println(getUserResponse.usersList)
}