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)客户端 ...
随机推荐
- FastCorrect:语音识别快速纠错模型丨RTC Dev Meetup
前言 「语音处理」是实时互动领域中非常重要的一个场景,在声网发起的「RTC Dev Meetup丨语音处理在实时互动领域的技术实践和应用」活动中,来自百度.寰宇科技和依图的技术专家,围绕该话题进行了相 ...
- springboot--配置格式文件
修改端口号的三种方法 1.server.port = 80 2.新建application.yml文件. 3.新建application.yaml文件. 配置文件加载顺序: 当三个文件都存在时prop ...
- monggodb项目操作
1.回顾 1.express + node 1.1 准备工作 前后端不分离开发 --- 前端负责写页面,后端负责渲染 --- admin-lte 1.2 创建express项目 express mya ...
- ACM-NEFU-2020大一寒假培训三(暴力)
A.二倍的问题 Description 给定2到15个不同的正整数,你的任务是计算这些数里面有多少个数对满足:数对中一个数是另一个数的两倍.比如给定1 4 3 2 9 7 18 22,得到的答案是3, ...
- C++/Qt网络通讯模块设计与实现(六)
前面章节主要讲述网络通讯客户端的实现,各位小伙伴需认真阅读以及理解,理会其中的思想,有疑问的地方可及时给我私信,我都会非常认真地解答大家的疑惑. C++/Qt网络通讯模块设计与实现(一) C++/Qt ...
- 镜像搬运工 skopeo
镜像搬运工 skopeo 介绍 skopeo 是一个命令行工具,可对容器镜像和容器存储进行操作. 在没有dockerd的环境下,使用 skopeo 操作镜像是非常方便的. 安装 # 安装 skopeo ...
- 在 k8s(kubernetes)中使用 Loki 进行日志监控
安装helm环境 [root@hello ~/yaml]# [root@hello ~/yaml]# curl https://baltocdn.com/helm/signing.asc | sudo ...
- [数据库]MySQL之SQL查询
一 关系表的介绍 * 课程表 * 学生表 * 选课表 二 SQL查询语句格式 /* SQL查询的一般格式 SELECT [ALL | DISTINCT] [* | coulmnNameA,coulmn ...
- mysql的查询--子查询,order by,group by,having
一. 1.多表查询 格式1: select 字段列表 from 表1 join 表2 on 表1.字段1=表2.字段1 where 查询条件 格式2: select 字段列表 from 表1 join ...
- Django笔记二十三之case、when操作条件表达式搜索、更新等操作
本文首发于公众号:Hunter后端 原文链接:Django笔记二十三之条件表达式搜索.更新等操作 这一篇笔记将介绍条件表达式,就是如何在 model 的使用中根据不同的条件筛选数据返回. 这个操作类似 ...