构建你的第一个gRPC服务(part 2)
在前一篇文章中,我介绍了如何使用skemaloop来创建协议(schema contract),在本文中,我将继续介绍如何使用skemaloop来创建服务框架代码(boilerplate)和桩代码(stub)来完成你的第一个gRPC服务的创建和运行。
Publish Schema
在创建完成协议之后,你首先需要将你的协议发布至github仓库,在本文中,我使用我自己的github账户来进行发布。在我自己的github账户下,我创建了一个sandbox的仓库用来保存我已经发布的协议和对应的代码。
在点击创建协议按钮后,你的协议就会被推送到你的github仓库中。如下图所示。
其中协议的地址会根据我们在创建协议时指定的仓库名称、模块名称(module)和包名称(package)来保存。在完成协议的发布后,就需要开始创建我们的桩代码(stub)和服务器端代码框架。
Publish Stub
点击下一步,来生成我们的桩代码(stub)。
默认情况下,skemaloop支持java和golang语言。
桩代码(stub)可以被客户端和服务器端代码用来实现通信,完成消息体的序列化和反序列化,实现主调和被调的业务封装。
Create Server Code
点击下一步,系统会帮你自动生成服务器端代码,支持golang和java的代码框架。 你可以通过点击下载,将服务器端代码框架下载到你的开发机上开始你的开发工作了。
在本文中,我将以java为例来完成说明。下载服务器端代码后,你可以看到代码结构如下。
代码语言:javascript复制 ~/Downloads/ cd sample_package_grpc-java_draft
~/Downloads/sample_package_grpc-java_draft/ ls
pom.xml sample_package sample_package-client
~/Downloads/sample_package_grpc-java_draft/ tree
.
├── pom.xml
├── sample_package
│ ├── pom.xml
│ ├── src
│ │ ├── main
│ │ │ ├── java
│ │ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── server
│ │ │ │ ├── SayHelloService.java
│ │ │ │ ├── SayHiService.java
│ │ │ │ └── ServiceApplication.java
│ │ │ └── resources
│ │ │ └── application.yaml
│ │ └── test
│ │ └── java
│ │ └── README.md
│ └── target
│ └── README.md
└── sample_package-client
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── example
│ │ │ └── client
│ │ │ ├── ClientApplication.java
│ │ │ ├── controller
│ │ │ │ └── ClientController.java
│ │ │ └── service
│ │ │ ├── ClientService.java
│ │ │ └── impl
│ │ │ └── ClientServiceImpl.java
│ │ └── resources
│ │ └── application.yaml
│ └── test
│ └── java
│ └── README.md
└── target
└── README.md
25 directories, 16 files
让我们来编辑SayHiService.java 来完成你的业务逻辑。
代码语言:javascript复制package com.example.server;
import com.skemaloop.test.SayHiGrpc;
import com.skemaloop.test.SayHiOuterClass;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
@GrpcService
public class SayHiService extends SayHiGrpc.SayHiImplBase {
@Override
// SayHello
public void sayHello(SayHiOuterClass.HelloRequest request,
StreamObserver<SayHiOuterClass.HelloReply> responseObserver) {
// PbServiceOuterClass.HelloReply reply = PbServiceOuterClass.HelloReply.newBuilder().setMsg("Msg: Hello," request.getMsg() "n").build();
SayHiOuterClass.HelloReply reply =SayHiOuterClass.HelloReply.newBuilder().build();
// add a business logic here
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
我们假设你已经完成你的业务逻辑的编写,让我们来通过maven命令完成服务的构建。
代码语言:javascript复制mvn package
并且启动你的服务。
代码语言:javascript复制java -jar sample_package-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\ / ___'_ __ _ _(_)_ __ __ _
( ( )___ | '_ | '_| | '_ / _` |
\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |___, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.4.0)
2022-04-02 12:48:24.162 INFO 80519 --- [ main] com.example.server.ServiceApplication : Starting ServiceApplication using Java 11.0.12 on JIMMYHZHAO-MB3 with PID 80519 (/Users/huizhao/Downloads/sample_package_grpc-java_v1.0.1/sample_package/target/sample_package-0.0.1-SNAPSHOT.jar started by huizhao in /Users/huizhao/Downloads/sample_package_grpc-java_v1.0.1/sample_package/target)
2022-04-02 12:48:24.164 INFO 80519 --- [ main] com.example.server.ServiceApplication : No active profile set, falling back to default profiles: default
2022-04-02 12:48:24.702 INFO 80519 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2022-04-02 12:48:24.708 INFO 80519 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-04-02 12:48:24.708 INFO 80519 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.39]
2022-04-02 12:48:24.739 INFO 80519 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-04-02 12:48:24.739 INFO 80519 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 538 ms
2022-04-02 12:48:24.831 INFO 80519 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2022-04-02 12:48:24.940 INFO 80519 --- [ main] g.s.a.GrpcServerFactoryAutoConfiguration : Detected grpc-netty-shaded: Creating ShadedNettyGrpcServerFactory
2022-04-02 12:48:25.018 INFO 80519 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2022-04-02 12:48:25.075 INFO 80519 --- [ main] n.d.b.g.s.s.AbstractGrpcServerFactory : Registered gRPC service: sample_module.sample_package.SayHi, bean: sayHiService, class: com.example.server.SayHiService
2022-04-02 12:48:25.076 INFO 80519 --- [ main] n.d.b.g.s.s.AbstractGrpcServerFactory : Registered gRPC service: grpc.health.v1.Health, bean: grpcHealthService, class: io.grpc.protobuf.services.HealthServiceImpl
2022-04-02 12:48:25.076 INFO 80519 --- [ main] n.d.b.g.s.s.AbstractGrpcServerFactory : Registered gRPC service: grpc.reflection.v1alpha.ServerReflection, bean: protoReflectionService, class: io.grpc.protobuf.services.ProtoReflectionService
2022-04-02 12:48:25.159 INFO 80519 --- [ main] n.d.b.g.s.s.GrpcServerLifecycle : gRPC Server started, listening on address: *, port: 9999
2022-04-02 12:48:25.166 INFO 80519 --- [ main] com.example.server.ServiceApplication : Started ServiceApplication in 1.963 seconds (JVM running for 2.272)
至此,你已经通过skemaloop完成了一个gRPC-java的服务。