netty-grpc基础准备
基本配置
完整标准依据官网进行配置。
依赖
compile(
'org.slf4j:slf4j-nop:1.7.25',
'io.grpc:grpc-netty-shaded:1.18.0',
'io.grpc:grpc-protobuf:1.18.0',
'io.grpc:grpc-stub:1.18.0'
)
插件
apply plugin: 'com.google.protobuf'
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.5'
}
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.5.1-1"
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.18.0'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
把关键内容添加进去,原来的内容可以不变。
我的就是这样
apply plugin : "com.google.protobuf"
apply plugin: "java"
group 'godme'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
maven {
url 'http://maven.aliyun.com/nexus/content/groups/public/'
}
mavenCentral()
}
dependencies {
compile(
'org.slf4j:slf4j-nop:1.7.25',
'io.grpc:grpc-netty-shaded:1.18.0',
'io.grpc:grpc-protobuf:1.18.0',
'io.grpc:grpc-stub:1.18.0'
)
}
buildscript {
repositories {
maven {
url 'http://maven.aliyun.com/nexus/content/groups/public/'
}
mavenCentral()
}
dependencies {
classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.5'
}
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.5.1-1"
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.18.0'
}
}
generateProtoTasks {
all()*.plugins {
grpc {}
}
}
}
问题
官网上的例子,我用5.1
的gradle
跑有问题,可以切换4.9
的版本。
如果使用gradlew
的话就会自动构建,如果没有的话,就手动装一个4.9
的吧。
IDL
proto
文件推荐放在/src/main/proto
文件夹下面,这是默认的如果想放在其他地方,也可以手动配置
sourceSetts{ main{ proto{ srcDir : "/src/main/proto" } } }
syntax = "proto3";
package com.godme.proto;
option java_package = "com.godme.proto";
option java_outer_classname = "Message";
message Student{
int32 id = 1;
string name = 2;
string addr = 3;
}
message Request{
string param = 1;
}
message Response{
string value = 1;
}
service StudentService{
rpc searchStudent(Request) returns(Student){}
}
proto
文件没多大变化,主要集中在两点
syntax
syntax = "proto3"
service
service StudentService{
rpc searchStudent(Request) returns(Student){}
}
从我们的使用角度可以发现一些端倪:
proto2
:单纯的作为序列化的手段
proto3
:提供RPC
远程调用
一般来说,远程调用这块是手动实现的,但是模式基本一致,后来就自动代码生成了。
proto3
没有更多的东西,针对的都是service
进行的自动代码生成。
service
结构和
thrift
中的service
类似,其实就是个接口定义。service StudentService{ rpc searchStudent(Request) returns(Student){} }
service
:关键字
StudentService
:自定义接口名称
rpc
:关键字
searchStudent
:自定义方法名称然后传参只需要指定类型即可。
需要注意返回时
returns
,同时,可入参一样也需要()
且指定返回类型。最后是空方法体
{}
。PS : 入参和返回都必须是
message
类型,不支持string
等基本类型。四种组合
入参和返回都可标记为
stream
,比如rpc searchStudent(stream Request) returns (stream Student){}
所以总共有四种形式
param returns stream - stream stream - - - stream 具体差异后续分析
generateProto
之前是
protoc --java_out=./../src Message.proto
手动进行的代码生成,但是,这次我们不仅是生成 序列化代码,还有service
。
命令行的形式真的麻烦,所以当你安装好插件以后,它自动创建了generateProto
等一系列gradle
任务。
我们只需要执行这个任务就行了,不同场景下,各种任务。
手动命令
gradle generateProto
点击执行
觉得麻烦IDEA
也可以直接点击就行了。
更多的任务见名思义,就不多说了,主要代码生成就是generateProto
了。
代码位置
生成的代码位置在build
文件夹下,不是--java_out
了。
grpc
下的就是service
生成的代码,普通包下就是序列化文件,包名都是同一个。
挪动粘贴之后,怎么分包随意。
接口实现
public class StudentServiceHandler extends StudentServiceGrpc.StudentServiceImplBase{
@Override
public void searchStudent(Message.Request request, StreamObserver<Message.Student> responseObserver) {
String param = request.getParam();
Message.Student student = Message.Student.newBuilder().setAddr("localhost").setId(99).setName(param).build();
responseObserver.onNext(student);
responseObserver.onCompleted();
}
}
service
的名称,生成以后加上Grpc
就是生成的服务类了。
有一个简单实现ImplBase
,继承就好。
小结
基本工作就是这些。
代码在此