【复杂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 {@AutowiredRouteGuideClient routeGuideClient;@Overridepublic Feature GetFeature(Point point) {return routeGuideClient.getRPCMethods().getFeature(point);}@Overridepublic 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>() {@Overridepublic 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);}}@Overridepublic void onError(Throwable t) {//表示操作已经出错,进行通知finishFuture.setException(t);}@Overridepublic 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>() {@Overridepublic 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());}@Overridepublic void onError(Throwable t) {finishFuture.setException(t);}@Overridepublic 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 "";}

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

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

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

相关文章

实战章节:在Linux上部署各类软件

详细资料见文章的资源绑定 一、前言 1.1 为什么学习各类软件在Linux上的部署 在前面&#xff0c;我们学习了许多的Linux命令和高级技巧&#xff0c;这些知识点比较零散&#xff0c;同学们跟随着课程的内容进行练习虽然可以基础掌握这些命令和技巧的使用&#xff0c;但是并没…

事务隔离级别:保障数据库并发事务的一致性与性能

目录 引言 1. 事务隔离级别概述 2. 读未提交隔离级别 3. 读已提交隔离级别 4. 可重复读隔离级别 5. 串行化隔离级别 6. 保障事务隔离级别的机制 7. 如何选择合适的隔离级别 8. 结语 引言 在数据库管理系统&#xff08;DBMS&#xff09;中&#xff0c;事务隔离级别是一…

Redisson分布式锁原理分析

1.Redisson实现分布式锁 在分布式系统中&#xff0c;涉及到多个实例对同一资源加锁的情况&#xff0c;传统的synchronized、ReentrantLock等单进程加锁的API就不再适用&#xff0c;此时就需要使用分布式锁来保证多服务之间加锁的安全性。 常见的分布式锁的实现方式有&#xff…

PyTorch 模型训练性能大揭秘:从基础到高级技巧一网打尽!

PyTorch 是一个开源的 Python 机器学习库&#xff0c;基于Torch&#xff0c;用于自然语言处理等应用程序。 PyTorch既可以看作加入了GPU支持的numpy&#xff0c;也可以看成一个拥有自动求导功能的强大的深度神经网络&#xff0c;同时它也是大模型开发的首选工具。 《PyTorch模…

不用再找,这是大模型 LLM 微调经验最全总结

大家好&#xff0c;今天对大模型微调项目代码进行了重构&#xff0c;支持ChatGLM和ChatGLM2模型微调的切换&#xff0c;增加了代码的可读性&#xff0c;并且支持Freeze方法、Lora方法、P-Tuning方法、「全量参数方法」 微调。 PS&#xff1a;在对Chat类模型进行SFT时&#xff…

binkw32.dll丢失怎么办?这5个方法都可以解决binkw32.dll丢失问题

binkw32.dll文件是什么&#xff1f; binkw32.dll是一个动态链接库文件&#xff0c;它是Windows操作系统中的一个重要组件。它包含了许多用于处理多媒体文件的函数和资源&#xff0c;如视频、音频等。当我们在电脑上打开或播放某些多媒体文件时&#xff0c;系统会调用binkw32.d…

显示器件是什么

显示器件 电子元器件百科 文章目录 显示器件前言一、显示器件是什么二、显示器件的类别三、显示器件的应用实例四、显示器件的作用原理总结前言 显示器件根据不同的技术原理和应用领域,具有不同的特点和优势,可适用于电子产品、电视、计算机显示器、手持设备、汽车仪表盘等…

绿盟 SAS堡垒机 local_user.php 权限绕过漏洞复现

绿盟 SAS堡垒机 local_user.php 权限绕过漏洞复现 一、 产品简介二、漏洞概述三、 复现环境四、漏洞复现五、小龙检测 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&…

全维度构建核心竞争优势,极智嘉(Geek+)连获六项大奖

近日&#xff0c;全球仓储机器人引领者极智嘉(Geek)一举斩获国内外六大重磅奖项&#xff0c;在技术实力、出海成绩到人才战略等多个维度&#xff0c;再度向大众展示了行业标杆的强劲实力。 首先在技术实力上&#xff0c;此前极智嘉与罗马尼亚医药电商Dr.MAX达成合作&#xff0…

测试用例设计方法六脉神剑——第四剑:石破天惊,功能图法攻阵

1 引言 前面几篇文章为我们讲述了因果图、判定表、正交试验等几种方法&#xff0c;主要是针对于不同条件输入输出的组合进行测试&#xff0c;但在实际需求中&#xff0c;我们也常会遇到需要对被测对象的状态流转进行验证的情况&#xff0c;此时前面几种方法将不再适用&#xf…

美国访问学者陪读签证怎么申请?

美国访问学者陪读签证是许多前往美国深造的学者及其家属关注的重要问题。如何申请这一签证&#xff0c;一直以来都是备受关注的话题。下面知识人网小编将为您介绍一下美国访问学者陪读签证的申请流程。 首先&#xff0c;申请人需要了解访问学者陪读签证的基本要求。通常情况下&…

马尔科夫预测模型(超详细,案例代码)

概述 马尔科夫预测模型是一种基于马尔科夫过程的预测方法。马尔科夫过程是一类具有马尔科夫性质的随机过程&#xff0c;即未来的状态只依赖于当前状态&#xff0c;而与过去状态无关。这种过程通常用状态空间和状态转移概率矩阵来描述。 在马尔科夫预测模型中&#xff0c;系统被…

Disruptor详解,Java高性能内存队列最优解

文章目录 一、Disruptor介绍1、为什么要有Disruptor2、Disruptor介绍3、Disruptor的高性能设计4、RingBuffer数据结构5、等待策略6、Disruptor在日志框架中的应用7、术语 二、Disruptor实战1、引入依赖2、Disruptor构造器3、入门实例&#xff08;1&#xff09;Hello World&…

浮动的魅力与挑战:如何在前端设计中巧妙运用浮动(下)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

SpringBoot的Starter自动化配置,自己编写配置maven依赖且使用及短信发送案例

目录 一、Starter机制 1. 是什么 2. 有什么用 3. 应用场景 二、短信发送案例 1. 创建 2. 配置 3. 编写 4. 形成依赖 6. 其他项目的使用 每篇一获 一、Starter机制 1. 是什么 SpringBoot中的starter是一种非常重要的机制(自动化配置)&#xff0c;能够抛弃以前繁杂…

SD-WAN解决外贸企业网络问题

为了获取全球客户&#xff0c;占领更多的市场&#xff0c;越来越多的外贸企业出现。外贸企业在发展业务的过程中会遇到很多困难&#xff0c;海外网络访问问题就是其中之一。目前该问题主要有三种解决方案&#xff1a;VPN、MPLS专线以及SD-WAN专线。 VPN通过在公网上面建立专用网…

WPF-UI HandyControl 简单介绍

文章目录 前言我的网易云专栏和Gitee仓库HandyControlHandyControl示例相关资源地址 我的运行环境快速开始和Material Design功能对比手风琴右键菜单自动补充滚动条轮播图消息通知步骤条托盘按钮 结尾 前言 最近我在研究如何使用WPF做一个比较完整的项目&#xff0c;然后我就先…

SLAM学习——相机模型(针孔+鱼眼)

针孔相机模型 针孔相机模型是很常用&#xff0c;而且有效的模型&#xff0c;它描述了一束光线通过针孔之后&#xff0c;在针孔背面投影成像的关系&#xff0c;基于针孔的投影过程可以通过针孔和畸变两个模型来描述。 模型中有四个坐标系&#xff0c;分别为world&#xff0c;c…

初识GroovyShell

文章目录 前言一、GroovyShell二、maven三、解决方案四、关键代码4.1 数据库配置表(pg)4.2 入参4.3 分页查询 总结 前言 项目背景&#xff1a;查询多个表的数据列表和详情&#xff0c;但不想创建过多的po、dao、resp等项目文件。 一、GroovyShell Apache Groovy是一种强大的…

Windows下使用CMake编译lua

Lua 是一个功能强大、高效、轻量级、可嵌入的脚本语言。它支持程序编程、面向对象程序设计、函数式编程、数据驱动编程和数据描述。 Lua的官方网站上只提供了源码&#xff0c;需要使用Make进行编译&#xff0c;具体的编译方法为 curl -R -O http://www.lua.org/ftp/lua-5.4.6.…