转载请注明出处:

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 实现客户端与服务端的更多相关文章

  1. TCP学习之五:客户端、服务端异步传输字符串

    参考学习张子阳大神的博客:http://www.cnblogs.com/JimmyZhang/category/101698.html 消息发送接口: 消息接收接口: 客户端: 服务端: 消息发送类: ...

  2. TCP学习之三:客户端、服务端同步传输字符串

    参考学习张子阳大神的博客:http://www.cnblogs.com/JimmyZhang/category/101698.html 一个客户端.发送一条消息 客户端: 服务端: 注意:Networ ...

  3. 客户端向服务端传送特殊字符解决方法(检测到有潜在危险的 Request.Form 值)

    当客户端向服务端传输特殊字符时报错,错误信息如下图:

  4. [Java]Hessian客户端和服务端代码例子

    简要说明:这是一个比较简单的hessian客户端和服务端,主要实现从客户端发送指定的数据量到服务端,然后服务端在将接收到的数据原封不动返回到客户端.设计该hessian客户端和服务端的初衷是为了做一个 ...

  5. SignalR 实现web浏览器客户端与服务端的推送功能

    SignalR 是一个集成的客户端与服务器库,基于浏览器的客户端和基于 ASP.NET 的服务器组件可以借助它来进行双向多步对话. 换句话说,该对话可不受限制地进行单个无状态请求/响应数据交换:它将继 ...

  6. Fresco 源码分析(二) Fresco客户端与服务端交互(3) 前后台打通

    4.2.1.2.4 PipelineDraweeControllerBuilder.obtainController()源码分析 续 上节中我们提到两个核心的步骤 obtainDataSourceSu ...

  7. Fresco 源码分析(二) Fresco客户端与服务端交互(1) 解决遗留的Q1问题

    4.2 Fresco客户端与服务端的交互(一) 解决Q1问题 从这篇博客开始,我们开始讨论客户端与服务端是如何交互的,这个交互的入口,我们从Q1问题入手(博客按照这样的问题入手,是因为当时我也是从这里 ...

  8. Asp.Net MVC 模型验证详解-实现客户端、服务端双重验证

    概要 在asp.net webform开发中经常会对用户提交输入的信息进行校验,一般为了安全起见大家都会在客户端进行Javascript(利于交互).服务端双重校验(安全).书写校验代码是一个繁琐的过 ...

  9. 用PHP的socket实现客户端到服务端的通信

    服务端 <?php error_reporting(E_ALL); set_time_limit(0); ob_implicit_flush(); //本地IP $address = 'loca ...

  10. C# TCP实现多个客户端与服务端 数据 与 文件的传输

    C#菜鸟做这个东东竟然花了快三天的时间了,真是菜,菜,菜--- 下面是我用C#写的 一个简单的TCP通信,主要的功能有: (1) 多个客户端与服务器间的数据交流 (2)可以实现群发的功能 (3)客户端 ...

随机推荐

  1. CF916E 解题报告

    被这道题搞了一个晚上,还好搞出来了qwq 令人耳目一新的阅读体验 题目简述 翻译已经很简单了. 前置知识 DFS序,LCA,线段树,不需要标签中的树剖! DFS序更新信息及判断祖先 如果你还不知道DF ...

  2. 数据库相关知识点整理,助力拿到心仪的offer

    1. 数据库的事务 1.1 什么是数据库事务? 事务是指一组逻辑上相关的操作,这些操作要么全部完成,要么全部不完成. 事务是数据库管理系统执行过程中的一个逻辑工作单位,是用户定义的一个操作序列,这些操 ...

  3. ACM-NEFU-2020大一寒假培训三(暴力)

    A.二倍的问题 Description 给定2到15个不同的正整数,你的任务是计算这些数里面有多少个数对满足:数对中一个数是另一个数的两倍.比如给定1 4 3 2 9 7 18 22,得到的答案是3, ...

  4. day02-搭建微服务基础环境01

    搭建微服务基础环境01 1.创建父工程,用于聚合其他微服务模块 1.1创建父项目 说明:我们先创建一个父项目,该父项目会去管理多个微服务模块(module),如下: (1)File-New-Proje ...

  5. [Linux]CPU架构/指令集:RISC / CISC | arm | amd | X86/i386 | aarch64

    1 前言 本文是解决在软件开发.软件交付过程中,常常需要找寻与服务器硬件的CPU架构适配的软件包时,开发者和交付者又时常摸不着头脑.[迷迷糊糊]地就下载了某个所谓"适配".&quo ...

  6. 四月十一号Java基础知识

    1.下列格式调用JAVA语言定义的方法:字符串变量名.方法名():2.由键盘输入多个数据普通格式一:Scanner reader= new Scanner(System.in): int number ...

  7. 五月二十七日jdbc,算法以及数据库

    1.ResultSetMetaData接口主要获得结果集.例如:结果集字段数量和名字通过ResultSet的getMetaData()方法获得对应对象 public class app17_20 { ...

  8. day128:MySQL进阶:MySQL安装&用户/权限/连接/配置管理&MySQL的体系结构&SQL&MySQL索引和执行计划

    目录 1.介绍和安装 2.基础管理 2.1 用户管理 2.2 权限管理 2.3 连接管理 2.4 配置管理 3.MySQL的体系结构 4.SQL 5.索引和执行计划 1.介绍和安装 1.1 数据库分类 ...

  9. sql 开窗函数排序遇到空值的处理办法

    sql sever默认null最小 升序排序 null值在最前面,若要放在后面,则: order by case when col is null then 1 else 0 end, col 降序排 ...

  10. Arch Linux配置Java学习环境

    1. JDK JDK8:主流版本 $ sudo pacman -S jdk8-openjdk JDK11:将会是下一个主流版本 $ sudo pacman -S jdk11-openjdk JDK19 ...