【复杂gRPC之Java调用go】

news2024/10/2 22:20:27

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 "";
    }

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

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

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

相关文章

2-4、DEBUG和源程序区别

语雀原文链接 文章目录 1、DEBUG 和 汇编编译器MASM区别1&#xff1a;默认进制不同区别2&#xff1a;[地址]示例1&#xff1a;debug示例2&#xff1a;[0]示例3&#xff1a;[寄存器]示例4&#xff1a;ds:[0]小结 区别3&#xff1a;源程序数据不能以字母开头 1、DEBUG 和 汇编编…

labelme等标注工具/数据增强工具输出JSON文件格式检查脚本

标注的文件太多了&#xff0c;还有用数据增强工具生成了一票的新数据。在转换或使用训练时候会报错&#xff0c;错误原因是json中语法有问题&#xff0c;这样会中断程序运行&#xff0c;调试造成很大困扰。 检查确实最后有问题&#xff0c;多写了一次 写一个脚本&#xff0c;用…

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

在使用MATLAB 进行异常检测&#xff08;上&#xff09;中&#xff0c;我们探讨了什么是异常值&#xff0c;简单的一维数据异常检测问题&#xff0c;针对高维数据的有监督异常检测方法。 在&#xff08;下&#xff09;篇中&#xff0c;我们将和大家一起探讨无监督异常检测。 没…

Unity 状态系统

状态系统 原理食用方法Demo 原理 #mermaid-svg-lUbxJ8eMP3KqrEhY {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-lUbxJ8eMP3KqrEhY .error-icon{fill:#552222;}#mermaid-svg-lUbxJ8eMP3KqrEhY .error-text{fill:#55…

算法通关村第十八关-青铜挑战回溯是怎么回事

大家好我是苏麟 , 今天聊聊回溯是怎么个事 . 回溯是最重要的算法思想之一&#xff0c;主要解决一些暴力枚举也搞不定的问题&#xff0c;例如组合、分割、子集、排列&#xff0c;棋盘等。从性能角度来看回溯算法的效率并不高&#xff0c;但对于这些暴力都搞不定的算法能出结果就…

快速排序的非递归实现

上期我们实现了快速排序的递归实现&#xff0c;但是我们知道如果递归深度太深&#xff0c;栈就会溢出&#xff0c;所以我们本期将为大家讲述快速排序的非递归实现&#xff0c;我们需要用到栈的数据结构&#xff0c;我们知道栈中的数据全是在堆区开辟的空间&#xff0c;堆的空间…

【EXCEL】offset函数

语法&#xff1a; offset(reference,row,column,[height],[width]) 例子&#xff1a;

【日常总结】mybatis-plus WHERE BINARY 中文查不出来

目录 一、场景 二、问题 三、原因 四、解决方案 五、拓展&#xff08;全表全字段修改字符集一键更改&#xff09; 准备工作&#xff1a;做好整个库备份 1. 全表一键修改 Stage 1&#xff1a;运行如下查询 Stage 2&#xff1a;复制sql语句 Stage 3&#xff1a;执行即可…

Volumetric Lights 2 HDRP

高清晰度渲染管道,包括先进的新功能,如半透明阴影图和直接灯光投射加上许多改进。 插件是一个快速,灵活和伟大的前瞻性光散射解决方案的高清晰度渲染管道。只需点击几下,即可改善场景中的照明视觉效果。 兼容: 点光源 聚光灯 碟形灯 矩形灯 通过覆盖摄像机周围大面积区域的…

05 JQuery基础入门

文章目录 一、jQuery介绍1. 简介2. 版本介绍3. 相关网站4. HTML引入方式 二、基础语法1. 顶级对象$2. 与DOM对象转化3. 选择器4. 事件5. 动画6. 修改样式7. 修改属性 一、jQuery介绍 1. 简介 jQuery是JavaScript编程语言底层库&#xff0c;它是一个快速&#xff0c;简洁的Jav…

JavaScript <关于逆向RSA非对称加密算法的案例(附原代码)>--案例(五)

前言: 趁热打铁,标记一下RSA的算法逆向...第二篇会有详解(本篇重在过程) 正文: 废话不说,直接分析步骤图: 到了这里,可以看到在登录的时候,需要验证码(本篇不教反验证码) 下面是正题--->逆他的pwd(密码) 总结: 问题:怎么确定一个密文数据是基于什么算法做出来的呢? 答:…

python 涉及opencv mediapipe知识,眨眼计数 供初学者参考

基本思路 我们知道正面侦测到人脸时&#xff0c;任意一只眼睛水平方向上的两个特征点构成水平距离&#xff0c;上下两个特征点构成垂直距离 当头像靠近或者远离摄像头时&#xff0c;垂直距离与水平距离的比值基本恒定 根据这一思路 当闭眼时 垂直距离变小 比值固定小于某一个…

Abaqus基础教程--胶合失效仿真

胶合是电子行业中常见的连接方式&#xff0c;abaqus中常用cohesive单元或者cohesive接触两种方法进行胶合失效仿真&#xff0c;这两种方式操作方法有所差别&#xff0c;但结果一般大同小异。 本例模型比较简单&#xff0c;建模过程从略&#xff0c;使用静态分析&#xff0c;使…

python基于ModBusTCP服务端的业务实现特定的client

python实现ModBusTCP协议的client是一件简单的事情&#xff0c;只要通过pymodbus、pyModbusTCP等模块都可以实现&#xff0c;本文采用pymodbus。但要基于ModBusTCP服务端的业务实现特定的client&#xff0c;那得看看服务端是否复杂。前面系列文章&#xff0c;我们学习了对服务端…

【vtkWidgetRepresentation】第五期 vtkLineRepresentation

很高兴在雪易的CSDN遇见你 内容同步更新在公众号“VTK忠粉” 【vtkWidgetRepresentation】第五期 一条直线的交互 前言 本文分享vtkLineRepresentation&#xff0c;希望对各位小伙伴有所帮助&#xff01; 感谢各位小伙伴的点赞关注&#xff0c;小易会继续努力分享&#xf…

Python---继承

1、什么是继承 我们接下来来聊聊Python代码中的“继承”&#xff1a;类是用来描述现实世界中同一组事务的共有特性的抽象模型&#xff0c;但是类也有上下级和范围之分&#xff0c;比如&#xff1a;生物 > 动物 > 哺乳动物 > 灵长型动物 > 人类 > 黄种人 从哲学…

Go--协程

协程 协程是Go语言最大的特色之一。 1、协程的概念 协程并不是Go发明的概念&#xff0c;支持协程的变成语言有很多。Go在语言层面直接提供对协程的支持称为goroutine。 1.1 基本概念 进程 进程是应用程序启动的实例&#xff0c;每个进程都有独立的内存空间&#xff0c;不同…

DSP外部中断笔记

中断原理 三部分 注意 &#xff0c;外部中断使能&#xff0c;PIE使能&#xff0c;CPU中断使能 外部中断有7个&#xff0c;PIE有12组&#xff0c;一个组有8个中断复用。只有一个CPU中断可执行。 外部中断原理 1、外部中断概述 外部中断结构图 外部中断XINT1对应的是0到31GPI…

<IBM Websphere Portal>《关于IBM的Portal和WAS的说明和总结(自用笔记)》

《关于IBM的Portal和WAS的简单总结》 1 架构1.1 说明 2 常见问题2.1 LDAP链接问题2.2 启动脚本建议2.3 日志大小保留建议2.4 启动垃圾回收日志 3 日志位置 1 架构 应用服务部署架构如上&#xff1a; &#x1f449;192.168.66.1服务器运行的server进程有&#xff1a;dmgr、nodea…

360压缩安装一半不动了怎么办?

360压缩软件是我们常用的压缩软件&#xff0c;但是常常会遇到压缩安装到一半停止的情况&#xff0c;下面提供了一些可能的原因和解决办法&#xff0c;大家可以进行尝试~ 方法一&#xff1a;关闭防火墙和杀毒软件 有时候&#xff0c;防火墙和杀毒软件可能会阻止360压缩的安装过…