调用 Go RPC TCP 服务时 Ruby Socket 客户端挂起

我有一个用 Go 编写的工作 RPC TCP 服务,但是当使用 Ruby 连接到该服务时,它挂起,因为似乎没有数据通过打开的套接字连接发回。


远程RPC功能:


package remote


import "fmt"


// Compose is our RPC functions return type

type Compose string


// Details is our exposed RPC function

func (c *Compose) Details(arg string, reply *string) error {

    fmt.Printf("Arg received: %+v\n", arg)

    *c = "some value"

    *reply = "Blah!"

    return nil

}

远程 RPC 端点暴露:


package remote


import (

    "fmt"

    "net"

    "net/rpc"

)


// Endpoint exposes our RPC over TCP service

func Endpoint() {

    compose := new(Compose)

    rpc.Register(compose)


    listener, err := net.Listen("tcp", ":8080")

    // error handling omitted


    for {

        conn, err := listener.Accept()

        // error handling omitted


        go rpc.ServeConn(conn)

    }

}

客户端通过 TCP 连接到远程 RPC 函数(使用 Golang,所以我知道它至少在这方面有效):


package main


import (

    "fmt"

    "log"

    "net/rpc"

)


func main() {

    client, err := rpc.Dial("tcp", "localhost:8080")

    if err != nil {

        log.Fatal("dialing:", err)

    }


    var reply string


    e := client.Call("Compose.Details", "my string", &reply)

    if e != nil {

        log.Fatalf("Something went wrong: %v", e.Error())

    }


    fmt.Printf("The 'reply' pointer value has been changed to: %s", reply)

}

这是我尝试使用的 Ruby 代码:


require "socket"

require "json"


socket = TCPSocket.new "localhost", "8080"


b = {

  method: "Compose.Details",

  params: "foobar"

}


socket.write(JSON.dump(b))


resp = JSON.load(socket.readline)


p resp

我认为它不起作用的原因是因为 Go RPC 需要提供一个指针作为暴露的 RPC 函数的第二个参数,但我不确定它在不同的编程语言(如 Ruby)中是如何工作的?


我也尝试过使用诸如https://github.com/chriskite/jimson 之类的库


require "jimson"


client = Jimson::Client.new("localhost:8080")

result = client.Details("foobar")

但我得到的只是:


RestClient::ServerBrokeConnection: Server broke connection


繁花如伊
浏览 255回答 1
1回答

胡说叔叔

好的,所以我需要在我的代码中进行的实际修复如下:传入的参数需要是自定义类型,以便您可以导出它,并且需要导出该类型中的字段本身...type Args struct {&nbsp; &nbsp; Foo string&nbsp; &nbsp; Bar string}但更重要的是,在 Ruby 方面,您需要以满足此要求的格式发送 JSON -> https://golang.org/src/net/rpc/jsonrpc/client.go#L45 <-happy所以这样做...b = {&nbsp; :method => "Compose.Details",&nbsp; :params => [{ :Foo => "Foo!", :Bar => "Bar!" }],&nbsp; :id&nbsp; &nbsp; &nbsp;=> "0" # id is just echo'ed back to the client}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go