【复杂gRPC之Java调用go】

1 注意点

一般上来说如果java调用java的话,我们可以使用springcloud来做,而面对这种跨语言的情况下,gRPC就展现出了他的优势。
代码放在这了,请结合前面的go服务器端一起使用
https://gitee.com/guo-zonghao/java-client-grpc

// 这些是在java端生成时候的配置
 option java_multiple_files = true;
 //生成文件所属的包
 option java_package = "com.iq50.client.routeguide";
 option java_outer_classname = "RouteGuideProto";

在运行插件的时候我们需要运行以下两个命令
在这里插入图片描述
之后我们会获得:
在这里插入图片描述

2 如何编写客户端代码

package com.iq50.client.routeguide;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.netty.NegotiationType;
import io.grpc.netty.NettyChannelBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class RouteGuideClient {
    //socket通道管理
    private final ManagedChannel channel;
    //负责普通调用和服务端到客户端的流调用
    private final RouteGuideGrpc.RouteGuideBlockingStub blockingStub;
    //负责双向流调用和客户端到服务端的流调用
    private final RouteGuideGrpc.RouteGuideStub asyncStub;
    
    public RouteGuideClient(){
        this(ManagedChannelBuilder.forAddress("127.0.0.1", 50051).usePlaintext());
    }
    private RouteGuideClient(ManagedChannelBuilder<?> channelBuilder) {
        this.channel = channelBuilder.build();
        this.blockingStub = RouteGuideGrpc.newBlockingStub(channel);
        this.asyncStub = RouteGuideGrpc.newStub(channel);
    }
    public RouteGuideGrpc.RouteGuideBlockingStub getRPCMethods(){
        return this.blockingStub;
    }
    public RouteGuideGrpc.RouteGuideStub getRPCAsyncMethods(){
        return this.asyncStub;
    }
}

3 如何调用具体的方法

3.1 普通调用和服务端流式调用

so easy!
通过获取stub之后直接调用即可。

package com.iq50.client.service.impl;

import com.iq50.client.routeguide.Feature;
import com.iq50.client.routeguide.Point;
import com.iq50.client.routeguide.Rectangle;
import com.iq50.client.routeguide.RouteGuideClient;
import com.iq50.client.service.RouteGuideService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Iterator;

@Service
public class RouteGuideServiceImpl implements RouteGuideService {
    @Autowired
    RouteGuideClient routeGuideClient;
    @Override
    public Feature GetFeature(Point point) {
        return routeGuideClient.getRPCMethods().getFeature(point);
    }
    @Override
    public Iterator<Feature>  ListFeatures(Rectangle rectangle) {
        return routeGuideClient.getRPCMethods().listFeatures(rectangle);
    }
}

3.2 客户端流式调用

在这个代码中我们需要使用SettableFuture来进行异步操作的通知,以及重写一个观察者的方法来方便进行异步的回调操作。

在这个方法体中,我们返回了一个匿名 StreamObserver 实例,其中我们:

  • 覆写了 onNext() 方法,每次客户端写入一个 Point 到消息流时,拿到特性和其它信息。 覆写了 onCompleted()
  • 方法(在 客户端 结束写入消息时调用),用来填充和构建我们的 RouteSummary。然后我们用 RouteSummary调用方法自己的的响应观察者的 onNext(),
  • 之后调用它的 onCompleted() 方法,结束服务器端的调用。
   		List<Feature> features = new ArrayList<Feature>();
        features.add(Feature.newBuilder().setLocation(Point.newBuilder().setLatitude(1200000).setLongitude(12000).build()).setName("asd").build());
        features.add(Feature.newBuilder().setLocation(Point.newBuilder().setLatitude(2200000).setLongitude(12000).build()).setName("asdf").build());
        features.add(Feature.newBuilder().setLocation(Point.newBuilder().setLatitude(3200000).setLongitude(12000).build()).setName("ewfew").build());
        features.add(Feature.newBuilder().setLocation(Point.newBuilder().setLatitude(4200000).setLongitude(12000).build()).setName("rtgr").build());
        features.add(Feature.newBuilder().setLocation(Point.newBuilder().setLatitude(5200000).setLongitude(12000).build()).setName("wer").build());
        int numPoints = features.size();
        //=========================
        //用来控制异步操作
        final SettableFuture<Void> finishFuture = SettableFuture.create();
        StreamObserver<RouteSummary> responseObserver = new StreamObserver<RouteSummary>() {
            @Override
            public void onNext(RouteSummary summary) {
                try {
                    System.out.printf("Finished trip with %d points. Passed %d features. Travelled %d meters. It took %d seconds.\n",
                            summary.getPointCount(), summary.getFeatureCount(), summary.getDistance(), summary.getElapsedTime());

                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }

            @Override
            public void onError(Throwable t) {
                //表示操作已经出错,进行通知
                finishFuture.setException(t);
            }

            @Override
            public void onCompleted() {
                //表示操作已经完成
                finishFuture.set(null);
            }
        };
        //获得一个请求的观察者对象
        StreamObserver<Point> requestObserver = routeGuideClient.getRPCAsyncMethods().recordRoute(responseObserver);

        try {
            // 随机挑选节点发送给服务器
            StringBuilder numMsg = new StringBuilder();
            Random rand = new Random();
            for (int i = 0; i < numPoints; ++i) {
                int index = rand.nextInt(features.size());
                Point point = features.get(index).getLocation();
                System.out.printf("Visiting point %d, %d\n", point.getLatitude(),point.getLongitude());
                //将点发送给服务器
                requestObserver.onNext(point);
                // Sleep for a bit before sending the next one.
                Thread.sleep(rand.nextInt(1000) + 500);
                if (finishFuture.isDone()) {
                    break;
                }
            }
            System.out.println(numMsg.toString());
            //告诉服务器端客户端以及发送完全部信息
            requestObserver.onCompleted();
            //等待服务器端完成处理
            finishFuture.get();
            System.out.println("Finished RecordRoute\n");
        } catch (Exception e) {
            requestObserver.onError(e);
            System.out.printf("RecordRoute Failed\n", e);
        }

        return "调用成功";

3.3 双向流式调用

    @GetMapping("/routeChat")
    public String routeChat() {
        final SettableFuture<Void> finishFuture = SettableFuture.create();
        StreamObserver<RouteNote> requestObserver = routeGuideClient.getRPCAsyncMethods().routeChat(new StreamObserver<RouteNote>() {
            @Override
            public void onNext(RouteNote note) {
                System.out.println("========");
                System.out.printf("Got2 message \"{%s}\" at {%d}, {%d}\n", note.getMessage(), note.getLocation().getLatitude(), note.getLocation().getLongitude());
            }

            @Override
            public void onError(Throwable t) {
                finishFuture.setException(t);
            }

            @Override
            public void onCompleted() {
                finishFuture.set(null);
            }
        });

        try {
            RouteNote[] requests =
                    {
                            RouteNote.newBuilder().setMessage("First message").setLocation(Point.newBuilder().setLongitude(0).setLatitude(0).build()).build(),
                            RouteNote.newBuilder().setMessage("Second message").setLocation(Point.newBuilder().setLongitude(0).setLatitude(1).build()).build(),
                            RouteNote.newBuilder().setMessage("Third message").setLocation(Point.newBuilder().setLongitude(1).setLatitude(0).build()).build(),
                            RouteNote.newBuilder().setMessage("Fourth message").setLocation(Point.newBuilder().setLongitude(1).setLatitude(1).build()).build(),
                            RouteNote.newBuilder().setMessage("Fifth message").setLocation(Point.newBuilder().setLongitude(1).setLatitude(1).build()).build(),
                    };

            for (RouteNote request : requests) {
                System.out.println("========");
                System.out.printf("Got message \"{%s}\" at {%d}, {%d}\n", request.getMessage(), request.getLocation().getLatitude(), request.getLocation().getLongitude());
                //发送请求
                requestObserver.onNext(request);
                //线程休眠0.5。这样从结果中才能体现出双向流的调用
                Thread.sleep(500);
            }
            //发送完成
            requestObserver.onCompleted();
            //等待服务器完成
            finishFuture.get();
            System.out.println("Finished RouteChat");
        } catch (Exception t) {
            requestObserver.onError(t);
            System.out.println("RouteChat Failed");
        }

        return "";
    }

结果如下:确实体现出了双向流
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

阿里云实时数据仓库HologresFlink

1. 实时数仓Hologres特点 专注实时场景&#xff1a;数据实时写入、实时更新&#xff0c;写入即可见&#xff0c;与Flink原生集成&#xff0c;支持高吞吐、低延时、有模型的实时数仓开发&#xff0c;满足业务洞察实时性需求。亚秒级交互式分析&#xff1a;支持海量数据亚秒级交…

量子算力引领未来!玻色量子出席第二届CCF量子计算大会

​8月19日至20日&#xff0c;中国计算机学会&#xff08;CCF&#xff09;主办的第二届CCF量子计算大会暨中国量子计算峰会&#xff08;CQCC 2023&#xff09;在中国合肥成功举办。本届大会以“量超融合&#xff0c;大国算力”为主题&#xff0c;设有量子计算软件、硬件、应用生…

机器学习应用 | 使用 MATLAB 进行异常检测(上)

异常检测任务&#xff0c;指的是检测偏离期望行为的事件或模式&#xff0c;可以是简单地检测数值型数据中&#xff0c;是否存在远超出正常取值范围的离群值&#xff0c;也可以是借助相对复杂的机器学习算法识别数据中隐藏的异常模式。 在不同行业中&#xff0c;异常检测的典型…

智能优化算法应用:基于材料生成算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于材料生成算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于材料生成算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.材料生成算法4.实验参数设定5.算法结果6.参考…

Tomcat头上有个叉叉

问题原因&#xff1a; 这是因为它就是个空的tomcat,并没有导入项目运行 解决方案&#xff1a; war模式&#xff1a;发布模式&#xff0c;正式发布时用&#xff0c;将WEB工程以war包的形式上传到服务器 war exploded模式&#xff1a;开发时用&#xff0c;将WEB工程的文件夹直接…

Navicat 连接 GaussDB分布式的快速入门

Navicat Premium&#xff08;16.3.3 Windows版或以上&#xff09;正式支持 GaussDB 分布式数据库。GaussDB分布式模式更适合对系统可用性和数据处理能力要求较高的场景。Navicat 工具不仅提供可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结构…

【2023年网络安全优秀创新成果大赛专刊】医疗机构临床数据合规共享解决方案(美创科技)

“2023年网络安全优秀创新成果大赛”由中央网信办网络安全协调局指导&#xff0c;中国网络安全产业联盟&#xff08;CCIA&#xff09;主办。本次大赛由3场分站赛、3场专题赛、1场大学生创新创业作品赛组成。 在杭州分站赛&#xff0c;美创科技—“医疗机构临床合规共享解决方案…

redis-学习笔记(list)

因为 list 可以头插头删, 尾插尾删, 所以其实更像 C 中的 deque (双端队列) ---- 知道就好, 别乱说, 具体底层编码是啥, 俺也不知道(没注意过) 可以通过组合, 把 list 当作队列 / 栈来用 list 的几种底层编码: ziplist(压缩列表) , linkedlist(链表) , quicklist ziplist 就是将…

docker镜像仓库hub.docker.com无法访问

docker镜像仓库hub.docker.com无法访问 文章主要内容&#xff1a; 介绍dockerhub为什么无法访问解决办法 1 介绍dockerhub为什么无法访问 最近许多群友都询问为什么无法访问Docker镜像仓库&#xff0c;于是我也尝试去访问&#xff0c;结果果然无法访问。 大家的第一反应就是…

如何优雅使用 vue-html2pdf 插件生成pdf报表

使用 vue-html2pdf 插件 业务背景&#xff0c;老板想要一份能征服客户的pdf报表&#xff0c;传统的pdf要手撕&#xff0c;企业中确实有点耗费时间&#xff0c;于是github上面看到开源的这个插件就…废话不多说&#xff0c;直接上教程 1.使用下面命令安装 vue-html2pdf npm i…

PHPstudy小皮的数据库打开失败问题解决

如果你的MYSQL服务启动后停止&#xff0c;多次重启依然无法解决的情况下&#xff0c;大概率是和本地mysql冲突了 但是&#xff0c;千万不要卸载掉本地mysql&#xff0c;只需要在服务中停止本地mysql即可 将此服务关闭&#xff0c;小皮的mysql即可使用

AtCoder ABC周赛2023 11/4 (Sat) D题题解

目录 原题截图&#xff1a; 题目大意&#xff1a; 主要思路&#xff1a; 注意事项&#xff08;很多人再这个地方掉坑&#xff09;&#xff1a; 代码&#xff1a; 原题截图&#xff1a; 题目大意&#xff1a; 给你两个数组&#xff08;A和B)长度都为n&#xff0c;然你求出一…

从零开发短视频电商 在AWS SageMaker已创建的模型列表中进行部署

1.导航到 SageMaker 控制台。 2.在 SageMaker 控制台的左侧导航栏中&#xff0c;选择 “模型” 选项。 3.在模型列表中&#xff0c;找到您要部署的模型。选择该模型。 4.点击 “创建端点” 选项或者点击 “创建端点配置” 选项都可以进行部署。 选择创建端点进去后还是会进行…

Axure原型组件库,数据可视化动态元件库(超详细Axure9可视化素材)

专门针对Axure制作的动态图表元件库&#xff0c;帮助产品经理更高效地制作高保真图表原型&#xff0c;是产品经理必备元件工具。现分享完整的组件库&#xff0c;大家一起学习。 每一个动态组件在原型文件中都配有详细介绍&#xff0c;文末可下载完整原型组件包~ 1. 本组件库的…

Appium获取toast方法封装

一、前置说明 toast消失的很快&#xff0c;并且通过uiautomatorviewer也不能获取到它的定位信息&#xff0c;如下图&#xff1a; 二、操作步骤 toast的class name值为android.widget.Toast&#xff0c;虽然toast消失的很快&#xff0c;但是它终究是在Dom结构中出现过&…

如何在Spring Boot中集成RabbitMQ

如何在Spring Boot中集成RabbitMQ 在现代微服务架构中&#xff0c;消息队列&#xff08;如RabbitMQ&#xff09;扮演了关键的角色&#xff0c;它不仅能够提供高效的消息传递机制&#xff0c;还能解耦服务间的通信。本文将介绍如何在Spring Boot项目中集成RabbitMQ&#xff0c;…

华为配置Smart Link负载分担示例

Smart Link基本概念 Smart Link通过两个端口相互配合工作来实现功能。这样的一对端口组成了一个Smart Link组。为了区别一个Smart Link组中的两个端口&#xff0c;我们将其中的一个叫做主端口&#xff0c;另一个叫做从端口。同时我们利用Flush报文、Smart Link实例和控制VLAN等…

Windows故障排除 – 连接WiFi却无法上网

Windows故障排除 – 连接WiFi却无法上网 Windows Troubleshooting - Connecting WiFi but PC Cannot Browse Internet By JacksonML 有个同学买了一台崭新的D品牌游戏本&#xff0c;i7处理器&#xff0c;英伟达RTX系列独立显卡及15寸液晶显示器&#xff0c;可谓功能强大。但是…

0011Java程序设计-ssm药店管理系统微信小程序

文章目录 摘 要目 录系统实现5.2服务端开发环境 编程技术交流、源码分享、模板分享、网课分享 企鹅&#x1f427;裙&#xff1a;776871563 摘 要 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机…

设备状态监测好帮手:无线温振传感器的应用

在现代工业生产中&#xff0c;设备状态监测对于确保设备的正常运行和预防故障至关重要。而无线温振传感器的出现为设备状态监测带来了全新的解决方案。本文将介绍无线温振传感器的工作原理和优势&#xff0c;并探讨其在设备状态监测中的广泛应用。 无线温振传感器是一种能够实时…