gRPC Java、Go、PHP使用例子

文章目录

    • 1、Protocol Buffers定义接口
      • 1.1、编写接口服务
      • 1.2、Protobuf基础数据类型
    • 2、服务器端实现
      • 2.1、生成gRPC服务类
      • 2.2、Java服务器端实现
    • 3、java、go、php客户端实现
      • 3.1、Java客户端实现
      • 3.2、Go客户端实现
      • 3.3、PHP客户端实现
    • 4、运行效果

本文例子是在Window平台测试,Java编写的gRPC服务器端,同时使用Java、Go、PHP编写客户端调用。

1、Protocol Buffers定义接口

1.1、编写接口服务

// 定义protocol buffers版本(proto3)
syntax = "proto3";// 定义包名,避免协议消息类型之间的命名冲突。
package helloworld;// 定义java格式
option java_multiple_files = true;
option java_package = "com.penngo.grpc";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";// 服务接口定义
service Greeter { // 方法1定义rpc SayHello (HelloRequest) returns (HelloReply) {}// 方法2定义rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}// HelloRequest消息类型格式定义,
message HelloRequest {// name为定义字段名,1为消息传输中的字段编号,使用后,不应该改编号。string name = 1;
}// HelloReply消息类型格式定义,
message HelloReply {// message为定义字段名,1为消息传输中的字段编号,使用后,不应该改编号。string message = 1;
}

1.2、Protobuf基础数据类型

    <th>C++</th><th>Java/Kotlin</th><th>Python</th><th>Go</th><th>Ruby</th><th>C#</th><th>PHP</th><th>Dart</th>
</tr>
<tr><td>double</td><td>double</td><td>double</td><td>float</td><td>float64</td><td>Float</td><td>double</td><td>float</td><td>double</td>
</tr>
<tr><td>float</td><td>float</td><td>float</td><td>float</td><td>float32</td><td>Float</td><td>float</td><td>float</td><td>double</td>
</tr>
<tr><td>int32</td><td>int32</td><td>int</td><td>int</td><td>int32</td><td>Fixnum or Bignum (as required)</td><td>int</td><td>integer</td><td>int</td>
</tr>
<tr><td>int64</td><td>int64</td><td>long</td><td>int/long<sup>[4]</sup></td><td>int64</td><td>Bignum</td><td>long</td><td>integer/string<sup>[6]</sup></td><td>Int64</td>
</tr>
<tr><td>uint32</td><td>uint32</td><td>int<sup>[2]</sup></td><td>int/long<sup>[4]</sup></td><td>uint32</td><td>Fixnum or Bignum (as required)</td><td>uint</td><td>integer</td><td>int</td>
</tr>
<tr><td>uint64</td><td>uint64</td><td>long<sup>[2]</sup></td><td>int/long<sup>[4]</sup></td><td>uint64</td><td>Bignum</td><td>ulong</td><td>integer/string<sup>[6]</sup></td><td>Int64</td>
</tr>
<tr><td>sint32</td><td>int32</td><td>int</td><td>int</td><td>int32</td><td>Fixnum or Bignum (as required)</td><td>int</td><td>integer</td><td>int</td>
</tr>
<tr><td>sint64</td><td>int64</td><td>long</td><td>int/long<sup>[4]</sup></td><td>int64</td><td>Bignum</td><td>long</td><td>integer/string<sup>[6]</sup></td><td>Int64</td>
</tr>
<tr><td>fixed32</td><td>uint32</td><td>int<sup>[2]</sup></td><td>int/long<sup>[4]</sup></td><td>uint32</td><td>Fixnum or Bignum (as required)</td><td>uint</td><td>integer</td><td>int</td>
</tr>
<tr><td>fixed64</td><td>uint64</td><td>long<sup>[2]</sup></td><td>int/long<sup>[4]</sup></td><td>uint64</td><td>Bignum</td><td>ulong</td><td>integer/string<sup>[6]</sup></td><td>Int64</td>
</tr>
<tr><td>sfixed32</td><td>int32</td><td>int</td><td>int</td><td>int32</td><td>Fixnum or Bignum (as required)</td><td>int</td><td>integer</td><td>int</td>
</tr>
<tr><td>sfixed64</td><td>int64</td><td>long</td><td>int/long<sup>[4]</sup></td><td>int64</td><td>Bignum</td><td>long</td><td>integer/string<sup>[6]</sup></td><td>Int64</td>
</tr>
<tr><td>bool</td><td>bool</td><td>boolean</td><td>bool</td><td>bool</td><td>TrueClass/FalseClass</td><td>bool</td><td>boolean</td><td>bool</td>
</tr>
<tr><td>string</td><td>string</td><td>String</td><td>str/unicode<sup>[5]</sup></td><td>string</td><td>String (UTF-8)</td><td>string</td><td>string</td><td>String</td>
</tr>
<tr><td>bytes</td><td>string</td><td>ByteString</td><td>str (Python 2)<br>bytes (Python 3)</td><td>[]byte</td><td>String (ASCII-8BIT)</td><td>ByteString</td><td>string</td><td>List<int></int></td>
</tr>
</tbody>
.proto

https://protobuf.dev/programming-guides/proto3/

2、服务器端实现

服务器端实例使用java编写

2.1、生成gRPC服务类

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.penngo</groupId><artifactId>grpc-helloworld</artifactId><version>1.0</version><properties><maven.compiler.source>11</maven.compiler.source><maven.compiler.target>11</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>io.grpc</groupId><artifactId>grpc-netty-shaded</artifactId><version>1.59.0</version><scope>runtime</scope></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-protobuf</artifactId><version>1.59.0</version></dependency><dependency><groupId>io.grpc</groupId><artifactId>grpc-stub</artifactId><version>1.59.0</version></dependency><dependency> <!-- necessary for Java 9+ --><groupId>org.apache.tomcat</groupId><artifactId>annotations-api</artifactId><version>6.0.53</version><scope>provided</scope></dependency></dependencies><build><extensions><extension><groupId>kr.motd.maven</groupId><artifactId>os-maven-plugin</artifactId><version>1.7.1</version></extension></extensions><plugins><!-- grpc代码生成插件 --><plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>0.6.1</version><configuration><protocArtifact>com.google.protobuf:protoc:3.24.0:exe:${os.detected.classifier}</protocArtifact><pluginId>grpc-java</pluginId><pluginArtifact>io.grpc:protoc-gen-grpc-java:1.59.0:exe:${os.detected.classifier}</pluginArtifact></configuration><executions><execution><goals><goal>compile</goal><goal>compile-custom</goal></goals></execution></executions></plugin></plugins></build><repositories><repository><id>alimaven</id><name>Maven Aliyun Mirror</name><url>https://maven.aliyun.com/repository/central</url></repository></repositories><pluginRepositories><pluginRepository><id>public</id><name>aliyun nexus</name><url>https://maven.aliyun.com/nexus/content/groups/public/</url><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories>
</project>

命令行下执行gRPC的java代码

mvn compile

自动扫描代码目中src/main/proto/helloworld.proto下的proto文件,自动生成gRPC相关代码到target/generated-sources/protobuf目录下。
在这里插入图片描述

2.2、Java服务器端实现

HelloServer.java

package com.penngo;import com.penngo.grpc.GreeterGrpc;
import com.penngo.grpc.HelloReply;
import com.penngo.grpc.HelloRequest;
import io.grpc.Grpc;
import io.grpc.InsecureServerCredentials;
import io.grpc.Server;
import io.grpc.stub.StreamObserver;
import java.io.IOException;public class HelloServer {public static void main(String[] args) throws IOException, InterruptedException {int port = 50051;Server server = Grpc.newServerBuilderForPort(port, InsecureServerCredentials.create()).addService(new GreeterImpl()).build().start();Runtime.getRuntime().addShutdownHook(new Thread(()->{System.err.println("*** shutting down gRPC server since JVM is shutting down");stopServer(server);System.err.println("*** server shut down");}));server.awaitTermination();}private static void stopServer(Server server) {if (server != null) {server.shutdown();}}static class GreeterImpl extends GreeterGrpc.GreeterImplBase {@Overridepublic void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {System.out.println("收到客户端消息:" + req.getName());String msg = "我是Java Server";System.out.println("回复客户端消息:" + msg);HelloReply reply = HelloReply.newBuilder().setMessage("你好!" + msg).build();responseObserver.onNext(reply);responseObserver.onCompleted();}@Overridepublic void sayHelloAgain(HelloRequest req, StreamObserver<HelloReply> responseObserver) {System.out.println("再次收到客户端消息:" + req.getName());String msg = "我是Java Server2";System.out.println("再次回复客户端消息:" + msg);HelloReply reply = HelloReply.newBuilder().setMessage(msg).build();responseObserver.onNext(reply);responseObserver.onCompleted();}}
}

https://github.com/protocolbuffers/protobuf/releases

3、java、go、php客户端实现

3.1、Java客户端实现

HelloClient.java

package com.penngo;import com.penngo.grpc.GreeterGrpc;
import com.penngo.grpc.HelloReply;
import com.penngo.grpc.HelloRequest;
import io.grpc.Grpc;
import io.grpc.InsecureChannelCredentials;
import io.grpc.ManagedChannel;import java.util.concurrent.TimeUnit;public class HelloClient {public static void main(String[] args) throws InterruptedException {String host = "localhost";int port = 50051;ManagedChannel managedChannel = Grpc.newChannelBuilderForAddress(host, port, InsecureChannelCredentials.create()).build();GreeterGrpc.GreeterBlockingStub blockingStub = GreeterGrpc.newBlockingStub(managedChannel);String msg1 = "我是java client";System.out.println("向服务器端发送消息:" + msg1);HelloRequest helloRequest1 = HelloRequest.newBuilder().setName(msg1).build();HelloReply reply1 = blockingStub.sayHello(helloRequest1);System.out.println("收到服务器端消息:" + reply1.getMessage());String msg2 = "我是java client2";System.out.println("再次向服务器端发送消息:" + msg2);HelloRequest helloRequest2 = HelloRequest.newBuilder().setName(msg2).build();HelloReply reply2 = blockingStub.sayHelloAgain(helloRequest2);System.out.println("再次收到服务器端消息:" + reply2.getMessage());managedChannel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS);}}

3.2、Go客户端实现

Go的代码生成需要使用protoc.exe来编译helloworld.proto服务文件,生成对应的服务调用代码
下载地址:https://github.com/protocolbuffers/protobuf/releases,当前最新版本为protoc-25.1-win64.zip
解压到目录D:\Program Files\protoc-25.1-win64\bin,需要把这个目录添加到环境变量PATH当中。

安装protocol编译器的Go插件

$ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2

执行下边命令生成Go的gRPC代码

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative helloworld/helloworld.proto

在这里插入图片描述

编写客户端实现代码

package mainimport ("context""flag""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure"pb "grpctest/helloworld""log""time"
)var (addr = flag.String("addr", "localhost:50051", "the address to connect to")
)func main() {flag.Parse()// Set up a connection to the server.conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))if err != nil {log.Fatalf("did not connect: %v", err)}defer conn.Close()c := pb.NewGreeterClient(conn)// Contact the server and print out its response.ctx, cancel := context.WithTimeout(context.Background(), time.Second)defer cancel()msg1 := "我是go client"log.Printf("向服务器端发送消息: %s", msg1)r1, err1 := c.SayHello(ctx, &pb.HelloRequest{Name: msg1})if err1 != nil {log.Fatalf("could not greet: %v", err1)}log.Printf("收到服务器端消息:%s", r1.GetMessage())msg2 := "我是go client2"log.Printf("再次向服务器端发送消息: %s", msg1)r2, err2 := c.SayHelloAgain(ctx, &pb.HelloRequest{Name: msg2})if err2 != nil {log.Fatalf("could not greet: %v", err2)}log.Printf("再次收到服务器端消息: %s", r2.GetMessage())
}

3.3、PHP客户端实现

安装gRPC的PHP扩展https://pecl.php.net/package/gRPC
当前测试php版本7.3,下载php_grpc-1.42.0-7.3-nts-vc15-x64.zip
php.ini这个文件加入

extension=php_grpc.dll

新建composer.json

{"name": "xxs/grpc","require": {"grpc/grpc": "^v1.4.0","google/protobuf": "^v3.3.0"},"autoload":{"psr-4":{"GPBMetadata\\":"GPBMetadata/","Helloworld\\":"Helloworld/"}}
}

在composer.json相同目录下执行命令下载依赖库

composer install

安装grpc的php插件,https://github.com/lifenglsf/grpc_for_windows
解压复制到项目下grpc_for_windows/x64/grpc_php_plugin.exe

执行命令生成gRPC代码

protoc --proto_path=. --php_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_for_windows/x64/grpc_php_plugin.exe ./helloworld.proto

在这里插入图片描述

client.php实现

<?php
require dirname(__FILE__) . '/vendor/autoload.php';
//echo dirname(__FILE__) . '/vendor/autoload.php';
function greet($hostname)
{$client = new Helloworld\GreeterClient($hostname, ['credentials' => Grpc\ChannelCredentials::createInsecure(),]);$request = new Helloworld\HelloRequest();$msg1 = "我是PHP client";$request->setName($msg1);echo "向服务器端发送消息: $msg1". PHP_EOL;list($response, $status) = $client->SayHello($request)->wait();if ($status->code !== Grpc\STATUS_OK) {echo "ERROR: " . $status->code . ", " . $status->details . PHP_EOL;exit(1);}echo "收到服务器端消息:".$response->getMessage() . PHP_EOL;$msg2 = "我是PHP client2";$request->setName($msg2);echo "再次向服务器端发送消息: $msg2". PHP_EOL;list($response, $status) = $client->SayHelloAgain($request)->wait();if ($status->code !== Grpc\STATUS_OK) {echo "ERROR: " . $status->code . ", " . $status->details . PHP_EOL;exit(1);}echo "再次收到服务器端发送消息:".$response->getMessage() . PHP_EOL;$client->close();
}$hostname = !empty($argv[2]) ? $argv[2] : 'localhost:50051';
greet($hostname);

4、运行效果

服务器端

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/180431.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity UGUI图片锯齿严重怎么解决

在开发的时候&#xff0c;发现图片锯齿严重&#xff0c;打包到移动端或者在编辑器都这样&#xff0c;如下图 原因&#xff1a; 查了一些资料&#xff0c;找到了原因如下&#xff1a;关于为什么会发生这种情况&#xff1a;看起来你的源资源比你在屏幕上显示的大小大得多。所以当…

深入浅出 Vue 中的插槽 slot

深入浅出 Vue 中的插槽 slot start 最近被问到好几次 Vue 中的插槽相关知识&#xff0c;掌握的还是有些不全面。抱着重新学习的心态&#xff0c;写这篇博客。首先对基础知识做一个回顾&#xff0c;然后再对源码实现做一个学习。作者&#xff1a;番茄编写时间&#xff1a;2023…

STM32_10(I2C)

I2C通信 I2C&#xff08;Inter IC Bus&#xff09;是由Philips公司开发的一种通用数据总线两根通信线&#xff1a;SCL&#xff08;Serial Clock&#xff09;、SDA&#xff08;Serial Data&#xff09;同步&#xff0c;半双工带数据应答支持总线挂载多设备&#xff08;一主多从…

QAC支持的静态度量属性

上面介绍了Coverity支持的12个度量属性&#xff0c;下面我们看看QAC这款工具支持的度量属性。下面分成3类&#xff0c;函数度量、文件度量和类度量。 函数度量指标不多&#xff0c;一共有8个。 文件度量度量指标一共10个&#xff0c;如下表。 类度量指标一个8个&#xff0c;如…

python实现C++简易自动压行

突发奇想&#xff0c;想要将自己的c压行之后交上去。但是苦于手动压行效率太低&#xff0c;在网上搜索压行网站没有找到&#xff0c;突然发现压行不就是检查检查去个换行符吗。于是心血来潮&#xff0c;用python实现了一个简易压行程序。 首先&#xff0c;宏定义等带#的文件不…

正则表达式及文本三剑客grep,awk,sed

目录 正则表达式 前瞻 代表字符 表示次数 位置锚定 分组或其他 grep 选项 范例 awk 前瞻 awk常见的内置变量 范例 sed 前瞻 sed格式 范例 搜索替代 格式 范例 分组后项引用 格式 范例 正则表达式 前瞻 通配符&#xff1a;匹配的是文件名 正则表达式&a…

Windows10免安装PostgreSQL

1. PostgreSQL简介2. 下载3. 安装环境4. 安装 4.1. 初始化数据库4.2. 启动数据库4.3. 注册服务4.3. 卸载服务 1. PostgreSQL简介 PostgreSQL 是一种特性非常齐全的自由软件的对象-关系型数据库管理系统&#xff0c;是以加州大学计算机系开发的 POSTGRES 4.2版本为基础的对象关…

java开发需要掌握的maven相关知识和Junit单元测试

maven简介 什么是maven&#xff1a; maven是一款管理和构建java项目的工具&#xff0c;是apache旗下的一个开源项目。 maven的作用&#xff1a; 依赖管理&#xff1a; 方便快捷的管理项目依赖的资源&#xff08;jar包&#xff09;。 项目构建&#xff1a; 标准化的跨平台&#…

开发知识点-CSS样式

CSS样式 fontCSS 外边距 —— 围绕在元素边框的空白区域# linear-gradient() ——创建一个线性渐变的 "图像"# transform ——旋转 元素![在这里插入图片描述](https://img-blog.csdnimg.cn/20191204100321698.png)# rotate() [旋转] # 边框 (border) —— 围绕元素内…

计算机毕业设计php+bootstrap小区物业管理系统

意义&#xff1a;随着我国经济的发展和人们生活水平的提高&#xff0c;住宅小区已经成为人们居住的主流&#xff0c;人们生活质量提高的同时&#xff0c;对小区物业管理的要求也越来越高&#xff0c;诸如对小区的维修维护&#xff0c;甚至对各项投诉都要求小区管理者做得好&…

人工智能-优化算法之梯度下降

梯度下降 尽管梯度下降&#xff08;gradient descent&#xff09;很少直接用于深度学习&#xff0c; 但了解它是理解下一节随机梯度下降算法的关键。 例如&#xff0c;由于学习率过大&#xff0c;优化问题可能会发散&#xff0c;这种现象早已在梯度下降中出现。 同样地&#x…

《微信小程序开发从入门到实战》学习三十四

4.2 云开发JSON数据库 MySQL、Oracle之类的“关系型数据库”。JSON数据库是“非关系型数据库”&#xff0c;没有行表列的概念。 4.2.1 JSON数据库基本概念 集合:一个数据库有多个集合&#xff0c;一个集合存储通常是同一类数据&#xff0c;可看作为JSON数组&#xff0c;数组…

P25 C++ const关键字

前言 本期我们要讲的是 C 中的 const 关键字。 const 在改变生成代码方面做不了什么&#xff0c;它有点像类和结构体的可见性&#xff0c;这是一个机制&#xff0c;可以让我们的代码更加干净&#xff0c;并对开发人员写代码强制特定的规则。 const 就像你做出的承诺&#xf…

王者小游戏

游戏里的经验动物 Bear package beast; import sxt.GameFrame; public class Bear extends Beast {public Bear(int x, int y, GameFrame gameFrame) {super(x, y, gameFrame);setImg("C:\\Users\\辛欣\\OneDrive\\桌面\\王者荣耀图片(1)\\王者荣耀图片\\beast\\bear.jp…

MacBook如何远程控制华为手机?

将手机屏幕投影到电脑上可以提供更大的屏幕空间&#xff0c;方便观看电影、浏览照片、阅读文档等。然而&#xff0c;除了想将手机投屏到电脑&#xff0c;还想要在电脑上直接操作手机&#xff0c;有方法可以实现吗&#xff1f; 现在使用AirDroid Cast的远程控制手机功能就可以实…

【CVE-2023-49103】ownCloud graphapi信息泄露漏洞(2023年11月发布)

漏洞简介 ownCloud owncloud/graphapi 0.2.x在0.2.1之前和0.3.x在0.3.1之前存在漏洞。graphapi应用程序依赖于提供URL的第三方GetPhpInfo.php库。当访问此URL时&#xff0c;会显示PHP环境的配置详细信息&#xff08;phpinfo&#xff09;。此信息包括Web服务器的所有环境变量&a…

ArkTS-WebView内嵌H5页面

鸿蒙开发使用WebView内嵌H5页面 访问在线网页时需添加网络权限&#xff1a;ohos.permission.INTERNET module.json5文件配置 {"module" : {"requestPermissions":[{"name": "ohos.permission.INTERNET"}]} }踩坑日记 加载网页效果无法…

C# datagridview控件 绑定数据库中表中数据的方式-3

1.如下图所示&#xff0c;为数据库中的一张表结构&#xff0c;注意该表中共有11个字段 2.首先在窗体后台代码中拖入一个datagridview控件&#xff0c;并在窗体加载时&#xff0c;给datagridview控件添加列&#xff0c;添加的方式如下所示&#xff1a;请注意&#xff0c;每个列…

[操作系统] 面试宝典之~死锁连环系列

文章目录 2.22 什么是死锁2.24 解决死锁的方法死锁的预防死锁的避免死锁的检测死锁的解除 2.22 什么是死锁 在多道程序环境下&#xff0c;多个进程可以竞争有限数量的资源。当一个进程申请资源时&#xff0c;如果这时没有可用资源&#xff0c;那么这个进程进入等待状态。有时&…

项目五 配置与管理磁盘

项目五 配置与管理磁盘 磁盘配额&#xff08;Quota&#xff09;&#xff0c;磁盘阵列&#xff08;RAID&#xff09;&#xff0c;逻辑滚动文件系统&#xff08;LVM&#xff09; #职业能力目标和要求 1&#xff0c;掌握Linux下的磁盘管理工具的使用方法 2&#xff0c;掌握Linux…