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)客户端 ...
随机推荐
- Less8-Less10 时间注入
Less-8和Less-5使用的是一样的布尔盲注,为了学习,这里我们使用时间盲注 Less-8 这里使用到了mysql中的if语句,格式为if(条件,正确执行,错误执行) 实例如图: sleep(秒速 ...
- Day05笔记
01.数组类(了解) 1.目的:设计一个类,该类有数组的功能,可以存储数据,可以删除修改数据 2.设计核心数据 1.属性:指针(指向堆区空间),数组实际存储的元素个数,数组容量 2.方法:构造(开辟堆 ...
- AI 影评家:用 Hugging Face 模型打造一个电影评分机器人
本文为社区成员 Jun Chen 为 百姓 AI 和 Hugging Face 联合举办的黑客松所撰写的教程文档,欢迎你阅读今天的第二条推送了解和参加本次黑客松活动.文内含有较多链接,我们不再一一贴出 ...
- 人脸关键点的应用场景及重难点解析丨Dev for Dev 专栏
本文为「Dev for Dev 专栏」系列内容,作者为声网视频组 AI 算法工程师 周世付. 人脸检测.人脸关键点检测,是计算机视觉的基础算法.许多酷炫应用背后,例如美颜.贴纸.人脸驱动 avatar ...
- Mathematica处理若干个点电荷的电位电场的一个程序包
来自 Mathematica for Theoretical Physics Electrodynamics, Quantum Mechanics, General Relativity and Fr ...
- 一文学会Flex布局
参考: <CSS权威指南>(第四版) flex布局教程-语法篇-阮一峰 1.Flex布局是什么 FlexBox,弹性盒布局,顾名思义,就是元素具有弹性,能根据可用空间大小增减尺寸. 2.基 ...
- img2pdf 报 img2pdf.AlphaChannelError: Refusing to work on images with alpha channel 的解决方案
问题描述: 在使用img2pdf转换png到pdf时候,报了如下错误 img2pdf.AlphaChannelError: Refusing to work on images with alph ...
- IPv4已正式用尽
网际协议版本4 (英语:Internet Protocol version 4,缩写:IPv4,又称互联网通信协议第四版)是网际协议开发过程中的第四个修订版本,也是此协议第一个被广泛部署和使用的版本. ...
- pysimplegui之常用元素介绍
1文本元素 | T == Txt == Text 2多行文本sg.Multiline('This is what a Multi-line Text Element looks like', size ...
- [MAUI 项目实战] 手势控制音乐播放器(一): 概述与架构
这是一篇系列博文.请关注我,学习更多.NET MAUI开发知识! [MAUI 项目实战] 手势控制音乐播放器(一): 概述与架构 [MAUI 项目实战] 手势控制音乐播放器(二): 手势交互 [MAU ...