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.hqwc.cn/news/228508.html

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

相关文章

谷歌浏览器(chrome)114版本之前的驱动和119、120、121版本驱动下载

114版本驱动下载在这个链接 119以后版本驱动在这个链接&#xff0c;其中http状态码是200的才可以下载&#xff0c;驱动大版本一致就可以使用&#xff0c;不需一模一样

[MySQL--基础]函数、约束

hello! 这里是欧_aita的频道。 今日语录:不管你觉得自己能做什么&#xff0c;或者你觉得你不能做什么&#xff0c;你都是对的。 祝福语&#xff1a;愿你的程序像太阳一样明亮&#xff0c;给世界带来温暖和光明。 大家可以在评论区畅所欲言&#xff0c;可以指出我的错误&#xf…

什么是路由抖动?该如何控制

路由器在实现不间断的网络通信和连接方面发挥着重要作用&#xff0c;具有所需功能的持续可用的路由器可确保其相关子网的良好性能&#xff0c;由于网络严重依赖路由器的性能&#xff0c;因此确保您的路由器不会遇到任何问题非常重要。路由器遇到的一个严重的网络问题是路由抖动…

工具及方法 - 如何阅读epub文件:使用Adobe Digital Editions

EPUB&#xff08;Electronic Publication的缩写&#xff0c;电子出版&#xff09;是一种电子图书标准&#xff0c;由国际数字出版论坛&#xff08;IDPF&#xff09;提出&#xff1b;其中包括3种文件格式标准&#xff08;文件的扩展名为.epub&#xff09;&#xff0c;这个格式已…

“PredictingChildrenHeight“ app Tech Support(URL)

Using our app, we can predict a childs height through formulas. Because there are many factors that affect a childs height, it is for reference only. ​​​​​​​ If you have any questions, you can either leave a message or send the questions to our em…

MySql的InnoDB的三层B+树可以存储两千万左右条数据的计算逻辑

原创/朱季谦 B树是一种在非叶子节点存放排序好的索引而在叶子节点存放数据的数据结构&#xff0c;值得注意的是&#xff0c;在叶子节点中&#xff0c;存储的并非只是一行表数据&#xff0c;而是以页为单位存储&#xff0c;一个页可以包含多行表记录。非叶子节点存放的是索引键…

Xilinx Zynq-7000系列FPGA多路视频处理:图像缩放+视频拼接显示,提供工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐FPGA图像处理方案FPGA图像缩放方案FPGA视频拼接叠加融合方案推荐 3、设计思路详解HLS 图像缩放介绍Video Mixer介绍 4、vivado工程介绍PL 端 FPGA 逻辑设计PS 端 SDK 软件设计 5、工程移植说明vivado版本不一致处理FPGA型号不一致处理其他…

WebGL技术框架及功能

WebGL&#xff08;Web Graphics Library&#xff09;是一种用于在Web浏览器中渲染交互式3D和2D图形的JavaScript API。它允许在不需要插件的情况下&#xff0c;在支持WebGL的浏览器中直接运行高性能的图形渲染。WebGL没有一个固定的技术框架&#xff0c;而是基于JavaScript API…

Git分支管理--Bug分支

愿所有美好如期而遇 我们现在正在dev4分支上进行开发&#xff0c;但是在我们开发过程中&#xff0c;并且我们还未提交&#xff0c;master分支上出现了bug&#xff0c;需要我们修复&#xff0c;我们先来看情景 我们添加一行代码并且不提交充作开发&#xff0c;模拟正在进行开发时…

【Linux下基本指令——(1)】

Linux下基本指令——&#xff08;1&#xff09; 一. ls 指令1.1.语法&#xff1a;1.2.功能&#xff1a;1.3.常用选项&#xff1a;1.4.举例&#xff1a;1.5.Xshell7展示 二. pwd 命令2.1.语法: 2.2.功能&#xff1a;2.3.常用选项&#xff1a;2.4.Xshell7展示 三. cd 指令3.1.语法…

上海亚商投顾:沪指震荡反弹 汽车产业链掀涨停潮

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日震荡反弹&#xff0c;北证50指数跌超4%&#xff0c;近50只北交所个股跌超10%。 新能源车产业链掀…

AtCoder ABC163

D - Sum of Large Numbers 不考虑 1 0 100 10^{100} 10100的情况下&#xff0c;检查能取到的最大和与最小和&#xff0c;此时中间的所有数都能取到 给出 1 0 100 10^{100} 10100的用意在于&#xff0c;确保取2个数与取3个数下面取到的和是不相同的。因此遍历取数的个数&#x…