protoBuf 实现客户端与服务端
转载请注明出处:
1.定义消息格式
在 src/main/proto 目录下创建 person.proto 文件,并定义消息格式,例如:
syntax = "proto3";
package example; message Person {
string name = 1;
int32 age = 2;
repeated string interests = 3;
}
这个文件定义了一个名为 Person 的消息类型,包括三个字段:name、age 和 interests
2.生成代码
使用 protoc 工具来生成 Java 代码,需要安装相应的插件和工具,可以通过 Maven 或 Gradle 等构建工具自动下载和配置。这里演示手动下载和安装的方式。
首先下载 protoc 工具及其插件,例如从官方网站下载对应版本的 protoc-3.x.x-linux-x86_64.zip,以及 protoc-gen-grpc-java 插件,例如从 Maven 中央仓库下载最新版的 protoc-gen-grpc-java-1.42.0-linux-x86_64.exe。
然后解压 protoc 工具,将 protoc 命令所在的路径添加到环境变量 PATH 中,例如:
export PATH="/path/to/protoc/bin:$PATH"
接下来安装 protobuf-java 和 grpc-java 两个依赖,例如通过 Maven 引入以下依赖:
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.17.3</version>
</dependency> <dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.42.0</version>
</dependency> <dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.42.0</version>
</dependency> <dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.42.0</version>
</dependency> <dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-testing</artifactId>
<version>1.42.0</version>
<scope>test</scope>
</dependency>
接着使用 protoc 生成 Java 代码,例如:
protoc --java_out=src/main/java --grpc-java_out=src/main/java src/main/proto/person.proto
这个命令会在 src/main/java/example 目录下生成 Person.java、PersonGrpc.java 和 PersonGrpc$PersonStub.java 等文件。
3.实现服务端
package example; import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver; import java.io.IOException; public class PersonServer {
private final int port;
private final Server server; public PersonServer(int port) throws IOException {
this.port = port;
this.server = ServerBuilder.forPort(port)
.addService(new PersonServiceImpl())
.build();
} public void start() throws IOException {
server.start();
System.out.println("Server started, listening on " + port);
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.err.println("*** shutting down gRPC server since JVM is shutting down");
PersonServer.this.stop();
System.err.println("*** server shut down");
}));
} public void stop() {
if (server != null) {
server.shutdown();
}
} private static class PersonServiceImpl extends PersonGrpc.PersonImplBase {
@Override
public void getMessage(PersonRequest request, StreamObserver<PersonResponse> responseObserver) {
String name = request.getName();
int age = request.getAge();
String interests = String.join(", ", request.getInterestsList()); // 将请求的内容响应回去
PersonResponse response = PersonResponse.newBuilder()
.setMessage("Received person info: name=" + name + ", age=" + age + ", interests=[" + interests + "]")
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
} public static void main(String[] args) throws IOException, InterruptedException {
PersonServer server = new PersonServer(8989);
server.start();
server.blockUntilShutdown();
}
}
4.实现客户端
package example; import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.stub.StreamObserver; import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; public class PersonClient {
private final ManagedChannel channel;
private final PersonGrpc.PersonStub stub; public PersonClient(String host, int port) {
this.channel = ManagedChannelBuilder.forAddress(host, port)
.usePlaintext()
.build();
this.stub = PersonGrpc.newStub(channel);
} public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
} public void sendMessage(String name, int age, String... interests) throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1); StreamObserver<PersonResponse> responseObserver = new StreamObserver<PersonResponse>() {
@Override
public void onNext(PersonResponse response) {
System.out.println("Received response: " + response.getMessage());
} @Override
public void onError(Throwable t) {
System.err.println("Received error: " + t.getMessage());
latch.countDown();
} @Override
public void onCompleted() {
System.out.println("Request completed");
latch.countDown();
}
}; List<String> interestList = Arrays.asList(interests);
PersonRequest request = PersonRequest.newBuilder()
.setName(name)
.setAge(age)
.addAllInterests(interestList)
.build(); stub.getMessage(request, responseObserver); latch.await();
} public static void main(String[] args) throws InterruptedException {
PersonClient client = new PersonClient("localhost", 8989); // 向服务器发送请求
client.sendMessage("Alice", 20, "reading", "swimming"); // 关闭连接
client.shutdown();
}
}
这个客户端会向服务器发送一个包含 name、age 和 interests 字段的 PersonRequest 消息,并等待接收服务器的响应信息。
protoBuf 实现客户端与服务端的更多相关文章
- TCP学习之五:客户端、服务端异步传输字符串
参考学习张子阳大神的博客:http://www.cnblogs.com/JimmyZhang/category/101698.html 消息发送接口: 消息接收接口: 客户端: 服务端: 消息发送类: ...
- TCP学习之三:客户端、服务端同步传输字符串
参考学习张子阳大神的博客:http://www.cnblogs.com/JimmyZhang/category/101698.html 一个客户端.发送一条消息 客户端: 服务端: 注意:Networ ...
- 客户端向服务端传送特殊字符解决方法(检测到有潜在危险的 Request.Form 值)
当客户端向服务端传输特殊字符时报错,错误信息如下图:
- [Java]Hessian客户端和服务端代码例子
简要说明:这是一个比较简单的hessian客户端和服务端,主要实现从客户端发送指定的数据量到服务端,然后服务端在将接收到的数据原封不动返回到客户端.设计该hessian客户端和服务端的初衷是为了做一个 ...
- SignalR 实现web浏览器客户端与服务端的推送功能
SignalR 是一个集成的客户端与服务器库,基于浏览器的客户端和基于 ASP.NET 的服务器组件可以借助它来进行双向多步对话. 换句话说,该对话可不受限制地进行单个无状态请求/响应数据交换:它将继 ...
- Fresco 源码分析(二) Fresco客户端与服务端交互(3) 前后台打通
4.2.1.2.4 PipelineDraweeControllerBuilder.obtainController()源码分析 续 上节中我们提到两个核心的步骤 obtainDataSourceSu ...
- Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题
4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...
- Asp.Net MVC 模型验证详解-实现客户端、服务端双重验证
概要 在asp.net webform开发中经常会对用户提交输入的信息进行校验,一般为了安全起见大家都会在客户端进行Javascript(利于交互).服务端双重校验(安全).书写校验代码是一个繁琐的过 ...
- 用PHP的socket实现客户端到服务端的通信
服务端 <?php error_reporting(E_ALL); set_time_limit(0); ob_implicit_flush(); //本地IP $address = 'loca ...
- C# TCP实现多个客户端与服务端 数据 与 文件的传输
C#菜鸟做这个东东竟然花了快三天的时间了,真是菜,菜,菜--- 下面是我用C#写的 一个简单的TCP通信,主要的功能有: (1) 多个客户端与服务器间的数据交流 (2)可以实现群发的功能 (3)客户端 ...
随机推荐
- 明解STM32—GPIO理论基础知识篇之八种工作模式
一.引言 在之前围绕STM32的GPIO的基本结构进行了介绍,图1为STM32的5V容忍的GPIO口内部基本结构图,图2为GPIO的基本结构中各个模块部分的概述. 阅读GPIO基本结构的内容能够对GP ...
- day01-2-依赖管理和自动配置
依赖管理和自动配置 1.依赖管理 1.1什么是依赖管理 spring-boot-starter-parent 中还有父项目,声明了开发中常用的依赖的版本号 并且进行自动版本仲裁,即如果程序员没有指定某 ...
- 全网最详细中英文ChatGPT接口文档(三)30分钟快速入门ChatGPT——资源库
目录 Python library(Python库) Node.js library(Node.js库) Community libraries 社区图书馆 C# / .NET Crystal Go ...
- Linux & 标准C语言学习 <DAY8_1>
一.进制转换 1.为什么要使用二进制.八进制.十六进制 因为目前的CPU只能识别高低两种电平,只能对二进制数据进行计算 二进制虽然能够直接被计算机识别,但是不方 ...
- 万字血书Vue—Vue语法
模板语法 插值语法 Mustache插值采用{{ }},用于解析标签体内容,将Vue实例中的数据插入DOM中 <h1>Hello {{name}}</h1> 指令语法 指令用于 ...
- java循环结构中局部变量和成员变量
前言 在前两篇文章中,壹哥给大家讲解了Java里的条件分支,包括if和switch两种情况.我们知道,除了条件分支结构,还有循环结构,所以接下来的一个学习重点就是Java里的循环.但在学习循环之前,我 ...
- CF1801B题解
CF1801B题解 传送门 更好的阅读体验 简化题意:有 n 个商店,每个商店卖 a,b 两种商品,价格分别为 \(a_i,b_i\),你需要在每个商店买一个商品,并且不能在所有商店都买同一种商品,最 ...
- SpringBoot——模板引擎及原理
更多内容,前往IT-BLOG 一.模板引擎的思想 模板是为了将显示与数据分离,模板技术多种多样,但其本质都是将模板文件和数据通过模板引擎生成最终的 HTML代码. 二.SpringBoot模板引擎 S ...
- 2.Web开发基础
Web开发基础 目录 Web开发基础 1.网络基础 2.OSI模型 应用层: 表示层: 会话: 传输层: 网络层: 数据链路层: 物理层: 3.通信子网:(数据通信) 4.资源子网:(数据处理) 5. ...
- 传输层和网络层的checksum区别,TCP cksum为何包含伪首部
一直搞不清传输层和网络层的校验和为什么校验内容不一样,最近问了一些前辈,找寻了一些答案,总结一下自己的思考. 先说一下传输层(TCP)和网络层(IP)的校验和: TCP校验和有伪首部.TCP herd ...