vip解析网站如何做,软件工程属于什么专业类别,wordpress自定义字段不全站显示,可口可乐营销案例分析文章目录 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基础数据类型 thC/ththJava/Kotlin/ththPython/ththGo/ththRuby/ththC#/ththPHP/ththDart/th
/tr
trtddouble/tdtddouble/tdtddouble/tdtdfloat/tdtdfloat64/tdtdFloat/tdtddouble/tdtdfloat/tdtddouble/td
/tr
trtdfloat/tdtdfloat/tdtdfloat/tdtdfloat/tdtdfloat32/tdtdFloat/tdtdfloat/tdtdfloat/tdtddouble/td
/tr
trtdint32/tdtdint32/tdtdint/tdtdint/tdtdint32/tdtdFixnum or Bignum (as required)/tdtdint/tdtdinteger/tdtdint/td
/tr
trtdint64/tdtdint64/tdtdlong/tdtdint/longsup[4]/sup/tdtdint64/tdtdBignum/tdtdlong/tdtdinteger/stringsup[6]/sup/tdtdInt64/td
/tr
trtduint32/tdtduint32/tdtdintsup[2]/sup/tdtdint/longsup[4]/sup/tdtduint32/tdtdFixnum or Bignum (as required)/tdtduint/tdtdinteger/tdtdint/td
/tr
trtduint64/tdtduint64/tdtdlongsup[2]/sup/tdtdint/longsup[4]/sup/tdtduint64/tdtdBignum/tdtdulong/tdtdinteger/stringsup[6]/sup/tdtdInt64/td
/tr
trtdsint32/tdtdint32/tdtdint/tdtdint/tdtdint32/tdtdFixnum or Bignum (as required)/tdtdint/tdtdinteger/tdtdint/td
/tr
trtdsint64/tdtdint64/tdtdlong/tdtdint/longsup[4]/sup/tdtdint64/tdtdBignum/tdtdlong/tdtdinteger/stringsup[6]/sup/tdtdInt64/td
/tr
trtdfixed32/tdtduint32/tdtdintsup[2]/sup/tdtdint/longsup[4]/sup/tdtduint32/tdtdFixnum or Bignum (as required)/tdtduint/tdtdinteger/tdtdint/td
/tr
trtdfixed64/tdtduint64/tdtdlongsup[2]/sup/tdtdint/longsup[4]/sup/tdtduint64/tdtdBignum/tdtdulong/tdtdinteger/stringsup[6]/sup/tdtdInt64/td
/tr
trtdsfixed32/tdtdint32/tdtdint/tdtdint/tdtdint32/tdtdFixnum or Bignum (as required)/tdtdint/tdtdinteger/tdtdint/td
/tr
trtdsfixed64/tdtdint64/tdtdlong/tdtdint/longsup[4]/sup/tdtdint64/tdtdBignum/tdtdlong/tdtdinteger/stringsup[6]/sup/tdtdInt64/td
/tr
trtdbool/tdtdbool/tdtdboolean/tdtdbool/tdtdbool/tdtdTrueClass/FalseClass/tdtdbool/tdtdboolean/tdtdbool/td
/tr
trtdstring/tdtdstring/tdtdString/tdtdstr/unicodesup[5]/sup/tdtdstring/tdtdString (UTF-8)/tdtdstring/tdtdstring/tdtdString/td
/tr
trtdbytes/tdtdstring/tdtdByteString/tdtdstr (Python 2)brbytes (Python 3)/tdtd[]byte/tdtdString (ASCII-8BIT)/tdtdByteString/tdtdstring/tdtdListint/int/td
/tr
/tbody.proto
https://protobuf.dev/programming-guides/proto3/
2、服务器端实现
服务器端实例使用java编写
2.1、生成gRPC服务类
pom.xml
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.penngo/groupIdartifactIdgrpc-helloworld/artifactIdversion1.0/versionpropertiesmaven.compiler.source11/maven.compiler.sourcemaven.compiler.target11/maven.compiler.targetproject.build.sourceEncodingUTF-8/project.build.sourceEncoding/propertiesdependenciesdependencygroupIdio.grpc/groupIdartifactIdgrpc-netty-shaded/artifactIdversion1.59.0/versionscoperuntime/scope/dependencydependencygroupIdio.grpc/groupIdartifactIdgrpc-protobuf/artifactIdversion1.59.0/version/dependencydependencygroupIdio.grpc/groupIdartifactIdgrpc-stub/artifactIdversion1.59.0/version/dependencydependency !-- necessary for Java 9 --groupIdorg.apache.tomcat/groupIdartifactIdannotations-api/artifactIdversion6.0.53/versionscopeprovided/scope/dependency/dependenciesbuildextensionsextensiongroupIdkr.motd.maven/groupIdartifactIdos-maven-plugin/artifactIdversion1.7.1/version/extension/extensionsplugins!-- grpc代码生成插件 --plugingroupIdorg.xolstice.maven.plugins/groupIdartifactIdprotobuf-maven-plugin/artifactIdversion0.6.1/versionconfigurationprotocArtifactcom.google.protobuf:protoc:3.24.0:exe:${os.detected.classifier}/protocArtifactpluginIdgrpc-java/pluginIdpluginArtifactio.grpc:protoc-gen-grpc-java:1.59.0:exe:${os.detected.classifier}/pluginArtifact/configurationexecutionsexecutiongoalsgoalcompile/goalgoalcompile-custom/goal/goals/execution/executions/plugin/plugins/buildrepositoriesrepositoryidalimaven/idnameMaven Aliyun Mirror/nameurlhttps://maven.aliyun.com/repository/central/url/repository/repositoriespluginRepositoriespluginRepositoryidpublic/idnamealiyun nexus/nameurlhttps://maven.aliyun.com/nexus/content/groups/public//urlreleasesenabledtrue/enabled/releasessnapshotsenabledfalse/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, StreamObserverHelloReply 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, StreamObserverHelloReply 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-gov1.28
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpcv1.2执行下边命令生成Go的gRPC代码
protoc --go_out. --go_optpathssource_relative --go-grpc_out. --go-grpc_optpathssource_relative helloworld/helloworld.proto编写客户端实现代码
package mainimport (contextflaggoogle.golang.org/grpcgoogle.golang.org/grpc/credentials/insecurepb grpctest/helloworldlogtime
)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 clientlog.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 client2log.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这个文件加入
extensionphp_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. --pluginprotoc-gen-grpcgrpc_for_windows/x64/grpc_php_plugin.exe ./helloworld.protoclient.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、运行效果
服务器端