天天看點

Netty架構入門學習--gRPC整合gradle,實作通信demo

詳細說明請參考:https://github.com/grpc/grpc-java

build.gradle

build.gradle檔案中具體引用,建議看下 https://github.com/grpc/grpc-java

group 'com.hll'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'com.google.protobuf'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    compile (
            "io.netty:netty-all:4.1.9.Final",
            "com.google.protobuf:protobuf-java:3.3.1",
            "com.google.protobuf:protobuf-java-util:3.3.1",
            "org.apache.thrift:libthrift:0.12.0",
            "io.grpc:grpc-netty:1.4.0",
            "io.grpc:grpc-protobuf:1.4.0",
            "io.grpc:grpc-stub:1.4.0"
    )
}

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.4'
    }
}

protobuf {
    protoc {
        artifact = "com.google.protobuf:protoc:3.2.0"
    }
    plugins {
        grpc {
            artifact = 'io.grpc:protoc-gen-grpc-java:1.4.0'
        }
    }
    //自定義檔案生成路徑
    generateProtoTasks.generatedFilesBaseDir = "src"
    generateProtoTasks {
        all()*.plugins {
            grpc {
            	//自定義檔案生成路徑
				setOutputSubDir 'java'
			}
        }
    }
}
           

配置完成之後,在Gradle的Tasks裡面可以看到generateProto,說明已經引用成功

Netty架構入門學習--gRPC整合gradle,實作通信demo
建立

src/main/proto

檔案夾,并建立proto檔案
Netty架構入門學習--gRPC整合gradle,實作通信demo

注意:建立的proto檔案需要在

src/main/proto

路徑下。

syntax = "proto3";

package com.hll.proto;

option java_package = "com.hll.proto";
option java_outer_classname = "PersonProto";
option java_multiple_files = true;

//rpc方法
service PersonService {
    rpc GetRealNameByUsername(MyRequest) returns (MyResponse) {}
}

//請求
message MyRequest {
    string username = 1;
}

//響應
message MyResponse {
    string realname = 2;
}
           

proto檔案編寫完成之後,通過Tasks裡面的

generateProto

指令生成代碼檔案。

#執行指令
gradle generateProto
           

成功之後,在build目錄就會有生成的檔案

Netty架構入門學習--gRPC整合gradle,實作通信demo

然後把生成的檔案全部複制到新建立的

com.hll.proto

包中

Netty架構入門學習--gRPC整合gradle,實作通信demo

注意

通過gradle generateProto生成檔案預設在build檔案夾下生成,然後我們會把生成的所有檔案複制到自己建立的包中,當我們對項目執行build操作時就會報錯,提示類重複了,是以我們需要将gradle generateProto生成的檔案直接在我們定義的包中生成才可以。不然每次build工程時,build檔案夾下面就會重新生成新的proto相關檔案。

服務端和用戶端業務代碼

建立一個類,實作grpc生成的方法

PersonServiceImpl

package com.hll.grpc;

import com.hll.proto.MyRequest;
import com.hll.proto.MyResponse;
import com.hll.proto.PersonServiceGrpc;
import io.grpc.stub.StreamObserver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 繼承grpc生成的抽象類PersonServiceImplBase
 */
public class PersonServiceImpl extends PersonServiceGrpc.PersonServiceImplBase {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 用戶端向服務端發起一個rpc調用會進入到這個方法
     * @param request
     * @param responseObserver 該方法是void類型無傳回值, 通過responseObserver實作傳回結果
     */
    @Override
    public void getRealNameByUsername(MyRequest request, StreamObserver<MyResponse> responseObserver) {
       logger.info("接收到用戶端資訊:" + request.getUsername());

       //服務端把結果構造完并傳回給用戶端
       responseObserver.onNext(MyResponse.newBuilder()
               .setRealname("張三")
               .build());
       //通知用戶端方法執行完成,onCompleted隻能調用一次
       responseObserver.onCompleted();
    }
}

           

服務端:GrpcServer

package com.hll.grpc;

import io.grpc.Server;
import io.grpc.ServerBuilder;

import java.io.IOException;

/**
 * 服務端.可參考官方例子代碼
 */
public class GrpcServer {

    private Server server;

    public static void main(String[] args) throws IOException, InterruptedException {
        GrpcServer server = new GrpcServer();
        server.start();
        server.awaitTermination();
    }

    //啟動服務
    private void start() throws IOException {
        this.server = ServerBuilder.forPort(8899).addService(new PersonServiceImpl()).build().start();

        System.out.println("server started...");
    }

    //停止服務
    private void stop() {
        if (null != this.server) {
            this.server.shutdown();
        }
    }

    //服務啟動之後就會立刻停止,awaitTermination會保持服務一直運作
    private void awaitTermination() throws InterruptedException {
        if (null != this.server) {
            this.server.awaitTermination();
        }
    }
}

           

用戶端:GrpcClient

package com.hll.grpc;

import com.hll.proto.MyRequest;
import com.hll.proto.MyResponse;
import com.hll.proto.PersonServiceGrpc;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;

/**
 * 用戶端.可參考官方例子代碼
 */
public class GrpcClient {

    public static void main(String[] args) {
        ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 8899)
                .usePlaintext(true).build();

        PersonServiceGrpc.PersonServiceBlockingStub blockingStub = PersonServiceGrpc
                .newBlockingStub(managedChannel);
        MyResponse myResponse = blockingStub
                .getRealNameByUsername(MyRequest.newBuilder().setUsername("zhangsan").build());
        System.out.println(myResponse.getRealname());

    }
}

           
啟動服務端和用戶端

在控制台可以看到通信資訊

Netty架構入門學習--gRPC整合gradle,實作通信demo
Netty架構入門學習--gRPC整合gradle,實作通信demo