当前位置:网站首页>玩转gRPC—不同编程语言间通信
玩转gRPC—不同编程语言间通信
2022-07-01 13:37:00 【Barry Yan】
1 简介gRPC在不同语言间是如何连接的

2 安装Protoc buffer
下载链接:https://github.com/protocolbuffers/protobuf/releases
Windows下建议直接下载可执行文件:
下载完成后放到指定目录,配置环境变量:
验证:
如果出现如下异常:
解决方式:
把protoc.exe拷贝到C:\Windows\System32
3 Go使用gRPC进行Go程序之间的通信
项目结构:
下载依赖:
go get google.golang.org/protobuf/runtime/[email protected]
go get google.golang.org/grpc
go get google.golang.org/protobuf
go.mod文件:
module grpc_go
go 1.16
require (
google.golang.org/grpc v1.43.0 // indirect
google.golang.org/protobuf v1.26.0 // indirect
)
protoc文件:
syntax = "proto3"; //指定语法格式
package proto; //指定生成的包名字
option java_package = "org.ymx.proto";
option go_package = "/";
// 定义gRPC服务接口
service HelloService {
// 接口的具体方法
rpc SayHello(HelloRequest) returns (HelloReply) {}
}
// 接口的请求参数类型
message HelloRequest {
string name = 1;
}
// 接口的响应参数类型
message HelloReply {
string message = 1;
}
到proto目录下进行编译,编译完成后会出现指定的go文件:
C:\Users\17122\Desktop\grpc_demo\grpc_go\protoc> protoc -I . --go_out=plugins=grpc:. hello.proto
如果出现异常:
'protoc-gen-go' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
--go_out: protoc-gen-go: Plugin failed with status code 1.
解决方式:
下载这个项目,到protoc-gen-go目录下,go build -o protoc-gen-go.exe main.go ,生成protoc-gen-go.exe文件
再将protoc-gen-go.exe拷贝到C:\Windows\System32
grpc客户端,main.go
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
_ "grpc_go/proto"
__ "grpc_go/proto"
"log"
)
func main() {
//1 配置grpc服务端的端口作为客户端的监听
conn, err := grpc.Dial(":6666", grpc.WithInsecure())
if err != nil {
log.Fatalf("正在监听服务端 : %v\n", err)
}
defer conn.Close()
//2 实例化 UserInfoService 服务的客户端
client := __.NewHelloServiceClient(conn)
//3 调用grpc服务
req := new (__.HelloRequest)
req.Name = "YMX"
resp, err := client.SayHello(context.Background(), req)
if err != nil {
log.Fatalf("请求错误 : %v\n", err)
}
fmt.Printf("响应内容 : %v\n", resp)
}
grpc服务端,main.go
import (
"context"
"fmt"
"google.golang.org/grpc"
__ "grpc_go/proto"
"log"
"net"
)
//定义服务端 实现 约定的接口
type HelloServiceServer struct{
}
var u = HelloServiceServer{
}
//实现 interface
func (s *HelloServiceServer) SayHello(ctx context.Context, req *__.HelloRequest) (resp *__.HelloReply, err error) {
name := req.Name
if name == "YMX" {
resp = &__.HelloReply{
Message: "Hello YMX"}
} else {
resp = &__.HelloReply{
Message: "Hi NoYMX"}
}
err = nil
return resp, nil
}
//启动服务
func main() {
//1 添加监听的端口
port := ":6666"
l, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("端口监听错误 : %v\n", err)
}
fmt.Printf("正在监听: %s 端口\n", port)
//2 启动grpc服务
s := grpc.NewServer()
//3 将UserInfoService服务注册到gRPC中,注意第二个参数是接口类型的变量,需要取地址传参
__.RegisterHelloServiceServer(s, &u)
s.Serve(l)
}
启动服务端和客户端,进行测试:
4 Java使用gRPC进行Java程序之间的通信
项目结构:
pom依赖
<?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>org.ymx</groupId>
<artifactId>grpc_java</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-all</artifactId>
<version>1.43.0</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.4.1.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.0.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.0.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
protoc文件内容:
syntax = "proto3"; //指定语法格式
package proto; //指定生成的包名字;
option java_multiple_files = true;
option java_package = "org.ymx.proto";
option go_package = "/";
option java_outer_classname = "Hello";
option objc_class_prefix = "YMX";
service HelloService {
rpc SayHello(HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
进行编译,首先利用protobuf进行编译:
然后再利用maven进行编译:
grpc服务端代码:
package org.ymx;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import org.ymx.proto.HelloReply;
import org.ymx.proto.HelloRequest;
import org.ymx.proto.HelloServiceGrpc;
import java.io.IOException;
/** * @desc: grpc服务端 * @author: YanMingXin * @create: 2021/12/18-14:52 **/
public class Server {
private final static int port = 5555;
private io.grpc.Server server;
private void start() throws IOException {
server = ServerBuilder.forPort(port)
.addService(new HelloServiceImpl())
.build()
.start();
System.out.println("service start...");
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.err.println("*** shutting down gRPC server since JVM is shutting down");
Server.this.stop();
System.err.println("*** server shut down");
}
});
}
private void stop() {
if (server != null) {
server.shutdown();
}
}
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
final Server server = new Server();
server.start();
server.blockUntilShutdown();
}
/** * 实现 定义一个实现服务接口的类 */
private class HelloServiceImpl extends HelloServiceGrpc.HelloServiceImplBase {
@Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
System.out.println("service:" + req.getName());
HelloReply reply = HelloReply.newBuilder().setMessage(("Hello: " + req.getName())).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
}
grpc客户端代码:
package org.ymx;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import org.ymx.proto.HelloReply;
import org.ymx.proto.HelloRequest;
import org.ymx.proto.HelloServiceGrpc;
import java.util.concurrent.TimeUnit;
/** * @desc: grpc客户端 * @author: YanMingXin * @create: 2021/12/18-14:52 **/
public class Client {
private final ManagedChannel channel;
private final HelloServiceGrpc.HelloServiceBlockingStub blockingStub;
public Client(String host, int port) {
channel = ManagedChannelBuilder.forAddress(host, port)
.usePlaintext()
.build();
blockingStub = HelloServiceGrpc.newBlockingStub(channel);
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
public void hello(String name) {
HelloRequest request = HelloRequest.newBuilder().setName(name).build();
HelloReply response = blockingStub.sayHello(request);
System.out.println(response.getMessage());
}
public static void main(String[] args) {
Client client = new Client("127.0.0.1", 5555);
for (int i = 0; i < 5; i++) {
if (i < 3) {
client.hello("ZS");
} else {
client.hello("YMX");
}
}
}
}
启动测试:
5 使用gRPC进行Go和Java程序间的通信
5.1 使用Java作为服务端,Go作为客户端
修改客户端端口:
Java服务端代码,其他代码不变:
/** * @desc: grpc服务端 * @author: YanMingXin * @create: 2021/12/18-14:52 **/
public class Server {
private final static int port = 5555;
private io.grpc.Server server;
private void start() throws IOException {
server = ServerBuilder.forPort(port)
.addService(new HelloServiceImpl())
.build()
.start();
System.out.println("service start...");
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.err.println("*** shutting down gRPC server since JVM is shutting down");
Server.this.stop();
System.err.println("*** server shut down");
}
});
}
private void stop() {
if (server != null) {
server.shutdown();
}
}
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
final Server server = new Server();
server.start();
server.blockUntilShutdown();
}
/** * 实现 定义一个实现服务接口的类 */
private class HelloServiceImpl extends HelloServiceGrpc.HelloServiceImplBase {
@Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
System.out.println("service:" + req.getName());
HelloReply reply = HelloReply.newBuilder().setMessage(("Hello: " + req.getName())).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
}
Go客户端代码,其他代码不变:
import (
"context"
"fmt"
"google.golang.org/grpc"
_ "grpc_go/proto"
__ "grpc_go/proto"
"log"
)
func main() {
//1 配置grpc服务端的端口作为客户端的监听
conn, err := grpc.Dial(":5555", grpc.WithInsecure())
if err != nil {
log.Fatalf("正在监听服务端 : %v\n", err)
}
defer conn.Close()
//2 实例化 UserInfoService 服务的客户端
client := __.NewHelloServiceClient(conn)
//3 调用grpc服务
req := new (__.HelloRequest)
req.Name = "YMX"
resp, err := client.SayHello(context.Background(), req)
if err != nil {
log.Fatalf("请求错误 : %v\n", err)
}
fmt.Printf("响应内容 : %v\n", resp)
}
测试:
5.2 使用Go作为服务端,Java作为客户端
修改客户端端口:
Go服务端代码,其他代码不变:
import (
"context"
"fmt"
"google.golang.org/grpc"
__ "grpc_go/proto"
"log"
"net"
)
//定义服务端 实现 约定的接口
type HelloServiceServer struct{
}
var u = HelloServiceServer{
}
//实现 interface
func (s *HelloServiceServer) SayHello(ctx context.Context, req *__.HelloRequest) (resp *__.HelloReply, err error) {
name := req.Name
if name == "YMX" {
resp = &__.HelloReply{
Message: "Hello YMX"}
} else {
resp = &__.HelloReply{
Message: "Hi NoYMX"}
}
err = nil
return resp, nil
}
//启动服务
func main() {
//1 添加监听的端口
port := ":6666"
l, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("端口监听错误 : %v\n", err)
}
fmt.Printf("正在监听: %s 端口\n", port)
//2 启动grpc服务
s := grpc.NewServer()
//3 将UserInfoService服务注册到gRPC中,注意第二个参数是接口类型的变量,需要取地址传参
__.RegisterHelloServiceServer(s, &u)
s.Serve(l)
}
Java客户端代码,其他代码不变:
/** * @desc: grpc客户端 * @author: YanMingXin * @create: 2021/12/18-14:52 **/
public class Client {
private final ManagedChannel channel;
private final HelloServiceGrpc.HelloServiceBlockingStub blockingStub;
public Client(String host, int port) {
channel = ManagedChannelBuilder.forAddress(host, port)
.usePlaintext()
.build();
blockingStub = HelloServiceGrpc.newBlockingStub(channel);
}
public void shutdown() throws InterruptedException {
channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
}
public void hello(String name) {
HelloRequest request = HelloRequest.newBuilder().setName(name).build();
HelloReply response = blockingStub.sayHello(request);
System.out.println(response.getMessage());
}
public static void main(String[] args) {
Client client = new Client("127.0.0.1", 6666);
for (int i = 0; i < 5; i++) {
if (i < 3) {
client.hello("ZS");
} else {
client.hello("YMX");
}
}
}
}
测试:
6 总结
- 存放protoc的文件目录尽量用proto命名
源码获取方式:关注下方公众号,回复【0701】
边栏推荐
- Report on the 14th five year plan and future development trend of China's integrated circuit packaging industry Ⓓ 2022 ~ 2028
- A new book by teacher Zhang Yujin of Tsinghua University: 2D vision system and image technology (five copies will be sent at the end of the article)
- Jenkins+webhooks- multi branch parametric construction-
- Beidou communication module Beidou GPS module Beidou communication terminal DTU
- Analysis report on the development trend and prospect scale of silicon intermediary industry in the world and China Ⓩ 2022 ~ 2027
- How much money do novices prepare to play futures? Is agricultural products OK?
- Analysis report on production and marketing demand and investment forecast of global and Chinese diamond powder industry Ⓤ 2022 ~ 2027
- In the next stage of digital transformation, digital twin manufacturer Youyi technology announced that it had completed a financing of more than 300 million yuan
- 介绍一种对 SAP GUI 里的收藏夹事务码管理工具增强的实现方案
- Google Earth engine (GEE) - Global Human Settlements grid data 1975-1990-2000-2014 (p2016)
猜你喜欢

5. Use of ly tab plug-in of header component
![[241. Design priority for operation expression]](/img/72/29d27204d5213a8efdb2c5be925dec.png)
[241. Design priority for operation expression]

8 popular recommended style layout

龙蜥社区开源 coolbpf,BPF 程序开发效率提升百倍

minimum spanning tree

Explain IO multiplexing, select, poll, epoll in detail

SAP intelligent robot process automation (IRPA) solution sharing

French Data Protection Agency: using Google Analytics or violating gdpr

Station B was scolded on the hot search..

AnimeSR:可学习的降质算子与新的真实世界动漫VSR数据集
随机推荐
1. Sum of two numbers: given an integer array num and an integer target value, please find the two integers whose sum is the target value target in the array and return their array subscripts
Word2vec training Chinese word vector
Detailed explanation of leetcode reconstruction binary tree [easy to understand]
Leetcode第一题:两数之和(3种语言)
小程序- view中多个text换行
Chen Yu (Aqua) - Safety - & gt; Cloud Security - & gt; Multicloud security
小程序-小程序图表库(F2图表库)
Etcd 概要 机制 和使用场景
[241. Design priority for operation expression]
About fossage 2.0 "meta force meta universe system development logic scheme (details)
Analysis report on the development trend and prospect scale of silicon intermediary industry in the world and China Ⓩ 2022 ~ 2027
Global and Chinese n-butanol acetic acid market development trend and prospect forecast report Ⓧ 2022 ~ 2028
2022 · 让我带你Jetpack架构组件从入门到精通 — Lifecycle
C语言课程设计题目
一文读懂TDengine的窗口查询功能
9. Use of better scroll and ref
Uni app realizes advertisement scroll bar
Flow management technology
Blind box NFT digital collection platform system development (build source code)
学会使用LiveData和ViewModel,我相信会让你在写业务时变得轻松