Welcome to my GitHub

https://github.com/zq2599/blog_demos

Content: All original articles and supporting source code, involving Java, Docker, Kubernetes, DevOPS, etc.

“Java version gRPC actual combat” full series of links

  1. Generate code with proto
  2. Service publishing and invocation
  3. The service side flow
  4. Client stream
  5. Two-way flow
  6. The client dynamically obtains the server ADDRESS
  7. Registration discovery based on EureKA

About the four types of gRPC definitions

This article is the “Java version of gRPC actual combat” series of the third, we actual combat experience of simple RPC request and response, the simple request and response mode is actually just one of the four types of gRPC definition, here give “gRPC Official Document Chinese” on the four gRPC types of description:

  1. Simple RPC: The client sends a request to the server using a stub and waits for the response to return, just like a normal function call;
  2. Server-side streaming RPC: The client sends a request to the server and gets a stream to read the returned message sequence. The client reads the returned stream until there are no messages in it. (That is, the content)
  3. Client-side streaming RPC: A client writes a sequence of messages and sends them to the server, also using a stream. Once the client finishes writing the message, it waits for the server to finish reading and return its response;
  4. Bidirectional STREAMING RPC: Two parties use a read/write stream to send a sequence of messages. The two streams operate independently, so the client and server can read and write in any order they like: for example, the server can wait to receive all client messages before writing the response, or it can read and write messages alternately, or some combination of reads and writes. The order of messages in each flow is reserved;

This paper gives an overview of

This is the server stream type gRPC service combat, including the following content:

  1. Develop a gRPC service of type server stream;
  2. Develop a client that invokes the previously published gRPC service;
  3. Validation;
  4. So let’s start coding;

Download the source code

  • This may be downloaded in making to combat the full source code, address and link information shown in the following table (https://github.com/zq2599/blo… :
The name of the link note
Project home page https://github.com/zq2599/blo… The project’s home page on GitHub
Git Repository address (HTTPS) https://github.com/zq2599/blo… The project source repository address, HTTPS protocol
Git Repository address (SSH) [email protected]:zq2599/blog_demos.git The project source warehouse address, SSH protocol
  • gRPC -tutorials on gRPC – Tutorials on

  • grpc-tutorials folder, the server code for this article is in the server-stream-server-side directory, server-stream-client-side

Develop a gRPC service of type Server Stream

  • The first step is to develop the gRPC server, which involves seven things as shown below:

  • SRC /main/proto stream
syntax = "proto3"; option java_multiple_files = true; / / to generate Java code package option java_package = "com. Bolingcavalry. Grpctutorials. Lib"; // Class name option java_outer_className = "MallProto"; // gRPC service, which is an online store OrderQuery service OrderQuery {// service stream: Order list interface, the input is the buyer information, RPC ListOrders (Buyer) returns (stream Order) {}} Message Buyer ID {int32 buyerId = 1; Message Order {// Order ID int32 orderId = 1; Int32 productId = 2; Int64 orderTime = 3; String buyerRemark = 4; }
  • Double-click generateProto in the red box below to generate Java code from proto:

  • The newly generated Java code is shown in the red box below:

  • Torials in parent project grpc-turtorials create new modules called server-stream-server-side to torials, The contents of build.gradle are as follows:
Plugins {id 'org.springframework.boot'} dependencies {implementation 'projectLombok :lombok' Implementation 'org. Springframework. The boot: spring - the boot - starter' / / as a gRPC service provider, Implementation 'net.devh:grpc-server-spring-boot-starter' // Implementation project(':grpc-lib')}
  • Create a configuration file application.yml:
Spring: application: name: server-stream-server-side gRPC: server: port: 9899 gRPC: server: port: 9899
  • Start the class:
package com.bolingcavalry.grpctutorials; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ServerStreamServerSideApplication { public static void main(String[] args) { SpringApplication.run(ServerStreamServerSideApplication.class, args); }}
  • Next is the most critical gRPC service, the code is as follows, visible responseObserver. OnNext method is called several times, to the client output data continuously,. Finally, responseObserver onCompleted end output:
package com.bolingcavalry.grpctutorials; import com.bolingcavalry.grpctutorials.lib.Buyer; import com.bolingcavalry.grpctutorials.lib.Order; import com.bolingcavalry.grpctutorials.lib.OrderQueryGrpc; import io.grpc.stub.StreamObserver; import net.devh.boot.grpc.server.service.GrpcService; import java.util.ArrayList; import java.util.List; @ GrpcService public class GrpcServerService extends OrderQueryGrpc. OrderQueryImplBase {/ * * * * @ return * / mock a batch of data private static List<Order> mockOrders(){ List<Order> list = new ArrayList<>(); Order.Builder builder = Order.newBuilder(); for (int i = 0; i < 10; i++) { list.add(builder .setOrderId(i) .setProductId(1000+i) .setOrderTime(System.currentTimeMillis()/1000) .setBuyerRemark(("remark-" + i)) .build()); } return list; } @Override public void listOrders(Buyer request, StreamObserver<Order> responseObserver) {// continue output to client for (Order Order: mockOrders()) { responseObserver.onNext(order); } / / end output responseObserver. OnCompleted (); }}
  • listOrders interface to get the responseobserver. onNext method output data;

Develop a client that invokes the PREVIOUSLY published gRPC service

  • The basic function of the client module is to provide a Web interface, which internally calls the server’s listOrders interface and returns the data to the front end, as shown below:

  • Torials in parent project grpc-turtorials create new modules called server-stream-client-side to torials, The contents of build.gradle are as follows:
plugins {
    id 'org.springframework.boot'
}

dependencies {
    implementation 'org.projectlombok:lombok'
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'net.devh:grpc-client-spring-boot-starter'
    implementation project(':grpc-lib')
}
  • Application configuration information application.yml contains the following contents, indicating the configuration of the port and the gRPC server address:
server: port: 8081 spring: application: name: server-stream-client-side grpc: client: Address: 'static://127.0.0.1:9899' enableKeepAlive: true keepAliveWithoutCalls: true negotiationType: plaintext
  • the listOrders interface returns an Order object that contains a lot of gRPC content and is not suitable as a return value for a Web interface, so define a DispOrder class as a return value for a Web interface:
package com.bolingcavalry.grpctutorials;

import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;

@Data
@AllArgsConstructor
public class DispOrder {
    private int orderId;
    private int productId;
    private String orderTime;
    private String buyerRemark;
}
  • The bland startup class:
package com.bolingcavalry.grpctutorials; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ServerStreamClientSideApplication { public static void main(String[] args) { SpringApplication.run(ServerStreamClientSideApplication.class, args); }}
  • Grpcclientservice. Java, which shows how to remotely invoke the listOrders interface of the gRPC service. Iterator < span style =” box-sizing: border-box; color: RGB (62, 62, 62); line-height: 22px; font-size: 12px; white-space: inherit;”
package com.bolingcavalry.grpctutorials; import com.bolingcavalry.grpctutorials.lib.Buyer; import com.bolingcavalry.grpctutorials.lib.Order; import com.bolingcavalry.grpctutorials.lib.OrderQueryGrpc; import io.grpc.StatusRuntimeException; import lombok.extern.slf4j.Slf4j; import net.devh.boot.grpc.client.inject.GrpcClient; import org.springframework.stereotype.Service; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @Service @Slf4j public class GrpcClientService { @GrpcClient("server-stream-server-side") private OrderQueryGrpc.OrderQueryBlockingStub orderQueryBlockingStub; Public List<DispOrder> listOrders(final String name) {// gRPC request parameter Buyer Buyer = Buyer.newBuilder().setBuyerId(101).build(); // gRPC response Iterator<Order> orderIterator; List<DispOrder> orders = new ArrayList<>(); / / request via stub remote gRPC try {orderIterator = orderQueryBlockingStub. ListOrders (buyer); } catch (final StatusRuntimeException e) { log.error("error grpc invoke", e); return new ArrayList<>(); } DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); log.info("start put order to list"); while (orderIterator.hasNext()) { Order order = orderIterator.next(); orders.add(new DispOrder(order.getOrderId(), order.getProductId(), / / use DateTimeFormatter DTF timestamp to a string. The format (LocalDateTime. OfEpochSecond (order. GetOrderTime (), 0, ZoneOffset. Of (" + 8 "))), order.getBuyerRemark())); log.info(""); } log.info("end put order to list"); return orders; }}
  • Finally, make a controller class that provides a web interface that calls the GrpcClientService method:
package com.bolingcavalry.grpctutorials; import com.bolingcavalry.grpctutorials.lib.Order; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class GrpcClientController { @Autowired private GrpcClientService grpcClientService; @RequestMapping("/") public List<DispOrder> printMessage(@RequestParam(defaultValue = "will") String name) { return grpcClientService.listOrders(name); }}
  • At this point, the coding is complete and the validation begins

validation

  1. < span style =” box-sizing: border-box; color: RGB (74, 74, 74); line-height: 22px; white-space: inherit;”

  1. server-stream-client-side Name =Tom, the result is as follows (Firefox automatically formats JSON data), it can be seen that gRPC remote data is successfully obtained:

At this point, the development and use of gRPC interface server stream type is complete, the next chapter will continue to learn the other two types;

You are not alone. Xin Chen is with you all the way

  1. Java series
  2. Spring series
  3. The Docker series
  4. Kubernetes series
  5. Database + middleware series
  6. The conversation series

Welcome to follow the public number: programmer Xin Chen

Wechat search “Programmer Chen”, I am Chen, looking forward to enjoying the Java world with you…


https://github.com/zq2599/blog_demos