精华内容
下载资源
问答
  • 文章目录简介JAVA提供`provider`和`consumer``proto`文件介绍java grpc providerjava grpc consumergo提供`provider`和`consumer`生成grpc文件go grpc providergo grpc consumer测试java 提供grpc服务go 提供grpc...

    bc75677c6c12ddbc3e90f4ada0b6c071.png

    文章目录

    简介

    JAVA提供`provider`和`consumer`

    `proto`文件介绍

    java grpc provider

    java grpc consumer

    go提供`provider`和`consumer`

    生成grpc文件

    go grpc provider

    go grpc consumer

    测试

    java 提供grpc服务

    go 提供grpc服务

    参考

    简介

    语言中立,支持多种语言;

    基于 IDL 文件定义服务,通过 proto3 工具生成指定语言的数据结构、服务端接口以及客户端 Stub;

    通信协议基于标准的 HTTP/2 设计,支持双向流、消息头压缩、单 TCP 的多路复用、服务端推送等特性,这些特性使得 gRPC 在移动端设备上更加省电和节省网络流量;

    序列化支持 PB(Protocol Buffer)和 JSON,PB 是一种语言无关的高性能序列化框架,基于 HTTP/2 + PB, 保障了 RPC 调用的高性能。

    JAVA提供provider和consumer

    proto文件介绍

    syntax

    指定语言版本

    syntax

    指定语言版本

    option

    修改配置选项

    service

    声明一个服务

    rpc

    声明一个方法

    resturns

    方法的返回值

    message

    定义一个消息类型

    repeated

    数组

    stream

    用流来交互

    一个栗子,helloworld.proto:

    syntax = "proto3"; //语法声明

    // Greeter 微服务

    service Greeter {

    // Sends a greeting

    rpc SayHello (HelloRequest) returns (HelloReply) {}

    }

    // HelloRequest 请求数据格式

    message HelloRequest {

    string name = 1;

    }

    // HelloReply 响应数据格式

    message HelloReply {

    string message = 1;

    }

    java grpc provider

    创建fast-common-grpc-proto,用来生成grpc相关接口。依赖如下,这个还配置了build,可以通过编译生成相关接口。

    com.google.protobuf

    protobuf-java

    ${protobuf.version}

    io.grpc

    grpc-netty

    ${grpc.version}

    io.grpc

    grpc-protobuf

    ${grpc.version}

    io.grpc

    grpc-stub

    ${grpc.version}

    kr.motd.maven

    os-maven-plugin

    ${os-maven-plugin.version}

    org.xolstice.maven.plugins

    protobuf-maven-plugin

    ${protobuf-maven-plugin.version}

    com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}

    grpc-java

    io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}

    compile

    compile-custom

    把上面的helloworld.proto复制到 java/main/proto下,注意一定要是proto文件夹,点击compile会成生成grpc接口文件

    f32ead1275baab4ad1c4b78a6ee2bd7c.png

    将文件GreeterGrpc、Helloworld复制到grpc包下面,创建GreeterServer文件

    5c7cd0b097ad0762683e77e38417133b.png

    GreeterServer的代码如下,继承 GreeterGrpc.GreeterImplBase 重写里面的sayHello方法

    @Component

    public class GreeterServer extends GreeterGrpc.GreeterImplBase implements InitializingBean {

    @Value("${gRPC.port}")

    private int port;

    @Override

    public void afterPropertiesSet() throws Exception {

    ServerBuilder.forPort(port)

    .addService(new GreeterServer())

    .build()

    .start();

    }

    @Override

    public void sayHello(Helloworld.HelloRequest request,

    io.grpc.stub.StreamObserver responseObserver) {

    Helloworld.HelloReply result = Helloworld.HelloReply.newBuilder().setMessage(request.getName()).build();

    responseObserver.onNext(result);

    responseObserver.onCompleted();

    }

    }

    java grpc consumer

    创建SimpleClient,调用你想要调用的接口。

    70e9d399072932bb1e378631681b55f3.png

    controller和service的代码这里就不给出了。需要的可以看github的代码,后面会给出地址。

    go提供provider和consumer

    生成grpc文件

    在根目录下运行命令

    protoc -I helloworld/ helloworld/helloworld.proto --go_out=plugins=grpc:helloworld

    1b3ca97a62d7a1bb38e3901be4c8236c.png

    go grpc provider

    创建service.go,代码如下

    package main

    import (

    "context"

    pb "go-grpc/helloworld"

    "log"

    "net"

    "google.golang.org/grpc"

    "google.golang.org/grpc/reflection"

    )

    const (

    port = ":50051"

    )

    type server struct{} //服务对象

    // SayHello 实现服务的接口 在proto中定义的所有服务都是接口

    func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {

    return &pb.HelloReply{Message: "Hello " + in.Name}, nil

    }

    func main() {

    lis, err := net.Listen("tcp", port)

    if err != nil {

    log.Fatalf("failed to listen: %v", err)

    }

    s := grpc.NewServer() //起一个服务

    pb.RegisterGreeterServer(s, &server{})

    // 注册反射服务 这个服务是CLI使用的 跟服务本身没有关系

    reflection.Register(s)

    if err := s.Serve(lis); err != nil {

    log.Fatalf("failed to serve: %v", err)

    }

    }

    go grpc consumer

    创建client.go,代码如下:

    package main

    import (

    "context"

    "log"

    "os"

    "time"

    pb "go-grpc/helloworld"

    "google.golang.org/grpc"

    )

    const (

    address = "localhost:50051"

    defaultName = "world"

    )

    func main() {

    //建立链接

    conn, err := grpc.Dial(address, grpc.WithInsecure())

    if err != nil {

    log.Fatalf("did not connect: %v", err)

    }

    defer conn.Close()

    c := pb.NewGreeterClient(conn)

    // Contact the server and print out its response.

    name := defaultName

    if len(os.Args) > 1 {

    name = os.Args[1]

    }

    // 1秒的上下文

    ctx, cancel := context.WithTimeout(context.Background(), time.Second)

    defer cancel()

    r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})

    if err != nil {

    log.Fatalf("could not greet: %v", err)

    }

    log.Printf("Greeting: %s", r.Message)

    }

    测试

    接下来测试服务之间的调用

    java 提供grpc服务

    java调用java,启动java服务,运行FastCommonGrpcExampleApplication这个类,访问http://localhost:8080/hello

    58fefc77d7cf09d2dbee5bfc583ede69.png

    go 调用java,运行client.go会看到输出

    435ec5a2d8468d65e56b927a5af4194e.png

    go 提供grpc服务

    java 调用go ,注释掉GreeterServer,启动FastCommonGrpcExampleApplication,启动service.go,访问http://localhost:8080/hello

    8a8f0f4e795eeb0412a834e5672c1e52.png

    go调用go,运行client.go会看到输出

    6a2a98d0dedf49dedb2f48c6be1178fe.png

    go地址:https://github.com/fafeidou/go-grpc

    java地址:https://github.com/fafeidou/fast-cloud-nacos

    参考

    java grpc: https://www.cnblogs.com/gutousu/p/9951956.html

    入门及服务端创建和调用原理: https://www.cnblogs.com/wxlevel/p/9154246.html#auto_id_24

    grpc(3):使用 golang 开发 grpc 服务端和客户端 : https://blog.csdn.net/freewebsys/article/details/59483427

    gRPC基于Golang和Java的简单实现: https://www.jianshu.com/p/21d5d7624951

    展开全文
  • Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。  想要运用androidstudio调用.go文件中的方法,具体操作如下:  1.安装go环境...

            Go语言专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速度,而且更加安全、支持并行进程。

            想要运用androidstudio调用.go文件中的方法,具体操作如下:

            1.安装go环境(mac系统)

            (1)安装Homebrew命令: ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

            (2)使用brew安装go命令:brew install go

            (3)使用go env查看当前go版本,以及路径配置相关属性,记住GOROOT的值下面会用到。

             (4)修改go路径环境:

                     主要是GOROOT和GOPATH

                        GOROOT:就是go的安装环境

                      GOPATH:作为编译后二进制的存放目的地和import包时的搜索路径。其实说通俗点就是你的go项目工作目录。通常情况下GOPATH包含三个目录:bin、pkg、src。(src目录下主要存放go的源文件;pkg目录存放编译好的库文件,主要是*.a文件;bin目录主要存放可执行文件)

                   那么重点操作来了,使用命令:vim ~/.bash_profile

                   现在已经进入了文件中,输入

    • GOROOT=上面记录的值

    • export GOROOT

    • export GOPATH=在你的目录中建立一个go环境目录,如mygopath

    • export GOBIN=$GOPATH/bin

    • export PATH=$PATH:$GOBIN:$GOROOT/bin

    编辑完之后退出保存文件,然后使用命令source ~/.bash_profile

    使之生效,然后再使用命令go env查看当前环境,可以发现已经是你配置文件中设置的路径环境了。

    2.安装gomobile环境

         (1)安装gomobile命令:go get golang.org/x/mobile/cmd/gomobile(可能需要翻墙)

        (2)go配置android sdk环境变量,输入命令:export ANDROID_HOME=你的sdk路径,可以在androidstudio中local.properties中查看

    (3)gomobile初始化ndk,执行命令:gomobile init -ndk  你的ndk路径,同上可以找到

    (4)如上所说,建立自己的gopath目录,gopath目录下面有src,bin,pkg三个文件夹,在src下建一个文件夹hello,名字随意,将你要使用的.go文件放到hello中。

    (5)见证奇迹的时刻到了,进入到gopath目录中的bin目录下执行命令:cd  你的gopath路径 + "/bin" ,然后输入命令:

    gomobile bind -target=android hello,只需等待几十秒就会在gopath的bin目录中生成.aar文件,这个文件android端就可以使用了。

     

    3.androidstudio调用生成的.aar文件。

          (1)androidstudio新建一个工程

          (2)将生成的.aar文件放到libs下面

          (3)在你的app下面的build.gradle中加入如下代码即可

                    

    repositories {
        flatDir {
            dirs 'libs' //this way we can find the .aar file in libs folder
        }
    }
    dependencies {
        compile (name:'tudun', ext:'aar')
    }

     

    大功告成,现在重新编译就可以调用go中的方法了,是不是很简单,只要一步一步按照命令操作即可!

    展开全文
  • 1、确保已经安装go语言 2、代码实现B.代码:packagepullwordimport("bufio""fmt""net""strings")typerequeststruct{sourcestringparam1float32param2uint}funcNewRequest(sourcestring,thresholdfloat32,debugbool)...

    1、确保已经安装go语言

    7f82af30b4bfe646e7329e99c0f3a52a.png

    2、代码实现

    B.代码:

    package pullword

    import (

    "bufio"

    "fmt"

    "net"

    "strings"

    )

    type request struct {

    source string

    param1 float32

    param2 uint

    }

    func NewRequest(source string, threshold float32, debug bool) request {

    var param2 uint

    if debug {

    param2 = 1

    } else {

    param2 = 0

    }

    return request{

    source: source,

    param1: threshold,

    param2: param2,

    }

    }

    func (req request) Do() ([]string, error) {

    conn, err := net.Dial("tcp", "api.pullword.com:2015")

    if err != nil {

    return nil, err

    }

    writer := bufio.NewWriter(conn)

    _, err = writer.WriteString(fmt.Sprintf("%s\t%1.2f\t%d]\r\n", req.source, req.param1, req.param2))

    if err != nil {

    return nil, err

    }

    writer.Flush()

    if err != nil {

    return nil, err

    }

    scanner := bufio.NewScanner(conn)

    list := make([]string, 0)

    for scanner.Scan() {

    if scanner.Text() != "\r\n" && scanner.Text() != "" {

    list = append(list, strings.Trim(scanner.Text(), "\r\n"))

    }

    }

    if err := scanner.Err(); err != nil {

    return nil, err

    }

    return list, nil

    }

    package main

    import (

    "fmt"

    "os"

    "pullword"

    "io/ioutil"

    )

    func main() {

    result_str := ""

    result_str = readFile("/home/tian/Desktop/test.txt")

    req := pullword.NewRequest(result_str, 1, true)

    result, err := req.Do()

    if err != nil {

    panic(err)

    }

    fmt.Printf("%q", result)

    }

    func readFile(path string) string {

    fi,err := os.Open(path)

    if err != nil{panic(err)}

    defer fi.Close()

    fd,err := ioutil.ReadAll(fi)

    return string(fd)

    }

    test.txt

    你的姿势水平还远远不够

    C.运行结果:

    ["姿势:1" "水平:1" "远远:1" "不够:1"]

    展开全文
  • java整个过程要解决的问题主要两个:数据类型在两种语言中如何转化何时清理无用的数据下面就围绕上述调用过程来阐述,本文涉及代码完整版可以下面链接找到:Go -> Cgo这是跨语言调用的第一步,主要是借助 cgo,...

    在 Java 中调用 Go 的大致过程如下go --> cgo --> jna --> java

    整个过程要解决的问题主要两个:数据类型在两种语言中如何转化

    何时清理无用的数据

    下面就围绕上述调用过程来阐述,本文涉及代码完整版可以下面链接找到:

    Go -> Cgo

    这是跨语言调用的第一步,主要是借助 cgo,把 Go 代码编译 C 共享库。

    cgo 是 Go 语言提供与 C 语言互调的一工具。提供一个名为 C 的伪 package,供 Go 访问 C 中的变量与函数,如 C.size_t C.stdout 等;同时提供 5 个特殊函数,用于两种语言间类型的转化:// Go string to C string

    // The C string is allocated in the C heap using malloc.

    // It is the caller's responsibility to arrange for it to be

    // freed, such as by calling C.free (be sure to include stdlib.h

    // if C.free is needed).

    func C.CString(string) *C.char

    // Go []byte slice to C array

    // The C array is allocated in the C heap using malloc.

    // It is the caller's responsibility to arrange for it to be

    // freed, such as by calling C.free (be sure to include stdlib.h

    // if C.free is needed).

    func C.CBytes([]byte) unsafe.Pointer

    // C string to Go string

    func C.GoString(*C.char) string

    // C data with explicit length to Go string

    func C.GoStringN(*C.char, C.int) string

    // C data with explicit length to Go []byte

    func C.GoBytes(unsafe.Pointer, C.int) []byte

    需要注意一点,cgo 中函数不能直接返回 slice/map 等具有 go pointer (区别与 C pointer,由 go runtime 管理生命周期)的数据类型,否则会报下面的 panic 信息:panic: runtime error: cgo result has Go pointer

    原因也很简单,go 是有 gc 的,假如允许返回具有 go pointer 的数据,那么 C 代码中得到的数据无法保证合法性,很有可能已经被 gc 了,即悬挂指针问题。解决的方式也很简单,就是采用 go 提供的特殊转化函数,将数据转为 unsafe.Pointer,在 C 中用 void * 的方式去使用。

    可以想象,这些特殊转化函数一定对数据进行了深拷贝,来保证数据的合法性,可参考 C.CBytes 的定义const cBytesDef = `

    func _Cfunc_CBytes(b []byte) unsafe.Pointer {

    p := _cgo_cmalloc(uint64(len(b)))

    pp := (*[1<<30]byte)(p)

    copy(pp[:], b)

    return p

    }

    `

    但这也意味着,Go/C 代码中需要负责 free 掉无用的数据(至于哪边 free,要看实际情况)。示例:func main() {

    cs := C.CString("Hello from stdio")

    C.myprint(cs)

    C.free(unsafe.Pointer(cs))

    }

    将 Go 函数导出供 C 调用,需要用 //export 标示相关函数,并且 Go 文件需要在 package main下。然后用类似下面的 build 命令,即可得到与 C 互调的动态库,同时会生产一个头文件,里面有 export 函数的相关签名。# linux 下可输出到 libawesome.so,这里以 Mac 下的动态库为例

    go build -v -o libawesome.dylib -buildmode=c-shared ./main.go//export Hello

    func Hello(msg string) *C.char {

    return C.CString("hello " + strings.ToUpper(msg))

    }

    // 头文件中 Hello 的定义

    // ptrdiff_t is the signed integer type of the result of subtracting two pointers.

    // n 这里表示字符串的长度

    typedef struct { const char *p; ptrdiff_t n; } _GoString_;

    extern char* Hello(GoString p0);

    Cgo -> JNA

    这一步主要是 Java 中如何调用 C 代码,目前主要有两种方式,JNA,优势是调用方便,只需要编写 Java 代码,JNA 框架负责在 C/Java 中进行数据类型转化

    JNI,优势是性能好,缺点是调用繁琐

    详细区别这里不展开叙述,感兴趣的读者可参考下面文章:

    JNA -> Java

    这一步主要是在 Java 代码中如何调用 JNA 框架提供的库进行跨语言调用,也是本文的重点。

    JNA 将 Java 基本类型直接映射为 C 中同等大小的类型,这里摘抄如下Native TypeSizeJava TypeCommon Windows Typeschar8-bit integerbyteBYTE, TCHAR

    short16-bit integershortWORD

    wchar_t16/32-bit charactercharTCHAR

    int32-bit integerintDWORD

    intboolean valuebooleanBOOL

    long32/64-bit integerNativeLongLONG

    long long64-bit integerlong__int64

    float32-bit FPfloat

    double64-bit FPdouble

    char*C stringStringLPCSTR

    void*pointerPointerLPVOID, HANDLE, LPXXX

    对于 C 中的 struct/pointer,JNA 中也提供了 Structure/Pointer 类来对应。JNA 的具体使用过程可参考:

    上述 GettingStarted 中第三种加载动态库的方式(即 resources 下的 {OS}-{ARCH}/{LIBRARY} 目录内)可以把动态库一起打包到 jar 中,这对于提供基础类库时比较方便,用户不需要再额外配置。resources/

    ├── darwin

    │   └── libawesome.dylib

    ├── linux-x86-64

    │   └── libawesome.so

    vladimirvivien/go-cshared-examples 这个仓库演示了四个函数 Add/Cosine/Sort/Log 的 JNA 调用,但这四个函数的返回类型都是基本类型(int/float64),没有 string/slice 等复杂类型,因此这里通过五个示例讲述复杂类型的返回问题:BadStringDemo.java 本示例演示了网络上一种常见,但有内存泄露问题的返回 string 的方式

    GoodStringDemo.java 这个示例演示了如何正确的返回 string

    ReturnByteSliceDemo.java 本示例演示如何返回 slice,以及如何在 Java 中处理 Go 中的多个返回值

    ReturnInterfaceDemo.java 本示例演示返回具有 Go Pointer 的结构时的报错行为

    上述示例均使用 direct mapping 的方式做 JNA,这种方式性能更好,但是支持的参数类型有限,读者可参考 vladimirvivien/go-cshared-examples 学习 interface mapping 的使用方式。

    总结

    C 语言作为连接不同高级语言的胶水语言,不具备垃圾回收功能,所以开发者在做 JNA 时要注意回收无用的内存结构。

    参考

    展开全文
  • Go语言写Android应用 (2) - 从Android的Java调用Go代码 上一篇我们讲到,Go在Android中的作用,就相当于NDK中的C/C++。上节我们学习了参照NDK的方式用纯Go语言来写应用。但是,也正如在Android中,C/C++主要是通过...
  • 最近有一个问题,是在golang作为底层,想获取apk的版本号和版本号代码(通俗一点就是versionName和versionCode),如果这时java代码,可以很容易地通过// please add try/catch ... ;-)PackageInfo info = context....
  • 学习Go语言时实现的集合操作工具库,类似于Java 8 中新增的Stream API。由于Go语言不支持泛型,所以基于反射实现。只用于学习目的,不要用于生产(PS:当然也不会有人用)。集合操作包括生成操作、中间操作和终止操作。...
  • 下面是Java调用百度API实现翻译的具体步骤:一、在写代码之前先在在百度翻译平台中,申请APP_ID申请地址申请的详见点击打开链接申请之后,会得到APP_ID和SECURITY_KEY二、java代码如下import IJFrame.IJFrame;...
  • 由于Java世界里有非常丰富的开源应用模型和轮子,而这些正是Go世界里面最缺乏的东西,所以我首先考虑的就是如何在Go里面调用现有的Java代码。早上写了个简单的Go调用Java的例子,在winxp环境下能够正常运行。这段...
  • 063666765/android/src/main/java/go/Universe.java write /tmp/gomobile-work-063666765/android/src/main/java/go/error.java write /tmp/gomobile-work-063666765/gomobile_bind/java_universe.c write /tmp/...
  • Java客户端调用Python服务端某些大型web服务一般是采用Spring框架编写的,然而深度学习计算框架TensorFlow是采用Python编写的,那么如何让客户端调用Python服务端的计算资源返回结果呢,一种可以采用传统的...
  • 'build/jar') #startJVM(r"D:worktoolsJavajdk1.5jrebinserverjvm.dll", "-ea") jpype.java.lang.System.out.println("Hello World") jpype.shutdownJVM() 直接在cmd命令行执行python test.py就可以了 二、调用jar...
  • 前端一般通过Ajax来调用,后端调用的方式还是挺多的,比如HttpURLConnection,HttpClient,Spring的RestTemplate服务端代码如下:package com.demo.restful.service.impl;import com.demo.restful.model.User;import...
  • java整个过程要解决的问题主要两个:数据类型在两种语言中如何转化何时清理无用的数据下面就围绕上述调用过程来阐述,本文涉及代码完整版可以下面链接找到:Go -> Cgo这是跨语言调用的第一步,主要是借助 cgo,...
  • 文章目录简介JAVA提供`provider`和`consumer``proto`文件介绍java grpc providerjava grpc consumergo提供`provider`和`consumer`生成grpc文件go grpc providergo grpc consumer测试java 提供grpc服务go 提供grpc...
  • 最近工作中常用到golang,学习了下golang的rpc框架,目前比较流行的有1.rpcx(http://rpcx.site/) 类似dubbo,不用定义protobuf文件 ...),服务拆分之后就会带来一个很基础的问题:调用链追踪,这个对于追踪问题和...
  • 一、rpcx中的网关在使用rpcx过程中可能会存在其他语言比如Java、Python、C#等来调用rpcx服务,这意味着需要提供不同的rpcx的协议来支撑,不过rpcx目前已提供了GateWay来为对应的rpcx服务提供了http网关服务,直接...
  • 二、Java代码,其中的MD5工具类请参照我的其他文章,或自己找一个MD5加密工具类。最终的MD5结果为32为大写。public class SendSMS {//短信接口地址private static String Url = "http://sdk.entinfo.cn:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 659
精华内容 263
关键字:

java调用go语言

java 订阅