【复杂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.hqwc.cn/news/256861.html

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

相关文章

【Git】error:failed to push some refs to ‘git@gitee.com:name/project.git‘

错误展示 今天在版本回退的时候&#xff0c;推送到gitee显示如下错误 先执行了git pull origin master&#xff0c;然后再执行push操作&#xff0c;也没有用 解决办法 执行git push -f origin master ,-f 表示强制推送。 结果 问题解决啦&#xff01;

iOS(swiftui)——系统悬浮窗( 可在其他应用上显示,可实时更新内容)

因为ios系统对权限的限制是比较严格的,ios系统本身是不支持全局悬浮窗(可在其他app上显示)。在iphone14及之后的iPhone机型中提供了一个叫 灵动岛的功能,可以在手机上方可以添加一个悬浮窗显示内容并实时更新,但这个功能有很多局限性 如:需要iPhone14及之后的机型且系统…

Linux下c开发

编程环境 Linux 下的 C 语言程序设计与在其他环境中的 C 程序设计一样&#xff0c; 主要涉及到编辑器、编译链接器、调试器及项目管理工具。编译流程 编辑器 Linux 中最常用的编辑器有 Vi。编译连接器 编译是指源代码转化生成可执行代码的过程。在 Linux 中&#xff0c;最常用…

异常检测 | MATLAB实现基于支持向量机和孤立森林的数据异常检测(结合t-SNE降维和DBSCAN聚类)

异常检测 | MATLAB实现基于支持向量机和孤立森林的数据异常检测(结合t-SNE降维和DBSCAN聚类) 目录 异常检测 | MATLAB实现基于支持向量机和孤立森林的数据异常检测(结合t-SNE降维和DBSCAN聚类)效果一览基本介绍模型准备模型设计参考资料 效果一览 基本介绍 提取有用的特征&…

【Mac】brew提示arch -arm64 brew以及uname返回x86_64的问题

背景 使用MacBook 14 M1 Pro两年了&#xff0c;自从使用了第三方Shell工具WindTerm后&#xff0c;使用brew时会提示我使用arch -arm64 brew安装&#xff0c;一开始没太在意&#xff0c;直到今天朋友问我uname -a返回的是什么架构&#xff0c;我才惊讶的发现竟然返回的是x86_64…

vue3-vite前端快速入门教程 vue-element-admin

Vue3快速入门学习 初始化项目 # 创建项目 npm create vitelatest my-vue-app -- --template vue # 安装依赖 npm i # 运行 npm run dev 模板语法 文本插值​ 最基本的数据绑定形式是文本插值&#xff0c;它使用的是“Mustache”语法 (即双大括号)&#xff1a; <span&g…

AI助力智慧农业,基于YOLOv8全系列模型【n/s/m/l/x】开发构建不同参数量级的识别系统

智慧农业随着数字化信息化浪潮的演变有了新的定义&#xff0c;在前面的系列博文中&#xff0c;我们从一些现实世界里面的所见所想所感进行了很多对应的实践&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《自建数据集&#xff0c;基于YOLOv7开发构建农田场景下杂草…

玩转大数据10:深度学习与神经网络在大数据中的应用

目录 1. 引言&#xff1a;深度学习和神经网络在大数据中的重要性和应用场景 2. 深度学习的基本概念和架构 3. Java中的深度学习框架 3.1. Deeplearning4j框架介绍及Java编程模型 3.2. DL4J、Keras和TensorFlow的集成 4. 大数据与深度学习的结合 4.1. 大数据与深度学…

HarmonyOS4.0从零开始的开发教程09页签切换

HarmonyOS&#xff08;七&#xff09;页签切换 List组件和Grid组件的使用 Tabs组件的使用 概述 在我们常用的应用中&#xff0c;经常会有视图内容切换的场景&#xff0c;来展示更加丰富的内容。比如下面这个页面&#xff0c;点击底部的页签的选项&#xff0c;可以实现“首页…

Uniapp - 环境搭建 vscode开发

uni-app 基础 创建 uni-app 项目方式 uni-app 支持两种方式创建项目&#xff1a; 通过 HBuilderX 创建&#xff08;需安装 HBuilderX 编辑器&#xff09; 通过命令行创建&#xff08;需安装 NodeJS 环境&#xff09; HBuilderX 创建 uni-app 项目 创建步骤 1.下载安装 H…

[论文阅读]BEVFusion

BEVFusion BEVFusion: A Simple and Robust LiDAR-Camera Fusion Framework BEVFusion&#xff1a;简单而强大的激光雷达相机融合框架 论文网址&#xff1a;BEVFusion 论文代码&#xff1a;BEVFusion 简读论文 论文背景&#xff1a;激光雷达和摄像头是自动驾驶系统中常用的两…

四、分代垃圾回收机制及垃圾回收算法

学习垃圾回收的意义 Java 与 C等语言最大的技术区别&#xff1a;自动化的垃圾回收机制&#xff08;GC&#xff09; 为什么要了解 GC 和内存分配策略 1、面试需要 2、GC 对应用的性能是有影响的&#xff1b; 3、写代码有好处 栈&#xff1a;栈中的生命周期是跟随线程&…