Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go中客户端和服务器的RPC_Go_Rpc - Fatal编程技术网

Go中客户端和服务器的RPC

Go中客户端和服务器的RPC,go,rpc,Go,Rpc,使用Go中的net/RPC包从服务器到客户机进行RPC调用是否确实可行?如果没有,还有更好的解决方案吗?RPC是一种(远程)服务。每当某台计算机请求远程服务时,它就充当客户端,请求服务器提供服务。在这个“定义”中,服务器调用客户端RPC的概念没有明确定义的含义 我目前正在使用thrift()实现服务器->客户端和客户端->服务器RPC功能。默认情况下,thrift只执行客户端->服务器调用,就像net/rpc一样。由于我还需要服务器->客户机通信,所以我做了一些研究并发现。Bidi thrift

使用Go中的
net/RPC
包从服务器到客户机进行RPC调用是否确实可行?如果没有,还有更好的解决方案吗?

RPC是一种(远程)服务。每当某台计算机请求远程服务时,它就充当客户端,请求服务器提供服务。在这个“定义”中,服务器调用客户端RPC的概念没有明确定义的含义

我目前正在使用thrift()实现服务器->客户端和客户端->服务器RPC功能。默认情况下,thrift只执行客户端->服务器调用,就像net/rpc一样。由于我还需要服务器->客户机通信,所以我做了一些研究并发现。Bidi thrift解释了如何连接java服务器+java客户端以进行双向thrift通信

比迪节俭的作用及其局限性。 TCP连接具有输入和输出通信线路(RC和TX)。bidi thrift的想法是拆分RS和TX,并将其提供给客户端应用程序和服务器应用程序上的服务器(处理器)和客户端(远程)。我发现这在围棋中很难做到。而且,这样就不可能有“响应”(响应行正在使用)。因此,服务中的所有方法都必须是“单向无效”。(开火然后忘记,呼叫没有结果)

解决方案 我改变了bidi thrift的想法,让客户机打开到服务器的两个连接,A和B。第一个连接(A)用于执行客户机->服务器通信(客户机照常进行调用)。第二个连接(B)被“劫持”,并连接到客户端上的服务器(处理器),同时连接到服务器上的客户端(远程)。我已经用一个Go服务器和一个Java客户机实现了这一点。它工作得很好。它快速可靠(就像普通的节俭一样)

一些消息来源。。B连接(服务器->客户端)的设置如下:

Go服务器 Java客户端
//B连接的准备工作
ttTransportFactory transportFactory=新的ttTransportFactory();
TProtocolFactory protocolFactory=new TBinaryProtocol.Factory();
YourServiceProcessor=newyourservice.processor(newyourserviceprocessor(this));
/*为B呼叫创建thrift连接(服务器->客户端)*/
试一试{
//创建传输
最终t运输=新t轨道(“127.0.0.1”,9091);
//开放交通工具
transport.open();
//将框架添加到传输层
最终TTTransport framedTransport=新的TFramedTransport(transportFactory.getTransport(transport));
//将帧传输连接到协议
最终TProtocol协议=protocolFactory.getProtocol(framedTransport);
//让处理器在新线程中处理请求
新线程(){
公开募捐{
试一试{
while(processor.process(protocol,protocol)){}
}捕获(特克斯){
e、 printStackTrace();
}捕获(NullPointerException e){
e、 printStackTrace();
}
}
}.start();
}捕获(例外e){
e、 printStackTrace();
}
我遇到了实现它的方法。例如:

Server.go

// server.go
package main

import (
 "net"
 "github.com/cenkalti/rpc2"
 "fmt"
)

type Args struct{ A, B int }
type Reply int


func main(){
     srv := rpc2.NewServer()
     srv.Handle("add", func(client *rpc2.Client, args *Args, reply *Reply) error{
    // Reversed call (server to client)
    var rep Reply
    client.Call("mult", Args{2, 3}, &rep)
    fmt.Println("mult result:", rep)

    *reply = Reply(args.A + args.B)
    return nil
 })

 lis, _ := net.Listen("tcp", "127.0.0.1:5000")
 srv.Accept(lis)
}
客户机,开始

// client.go
package main

import (
 "fmt"
 "github.com/cenkalti/rpc2"
 "net"
)

type Args struct{ A, B int }
type Reply int

func main(){
     conn, _ := net.Dial("tcp", "127.0.0.1:5000")

     clt := rpc2.NewClient(conn)
     clt.Handle("mult", func(client *rpc2.Client, args *Args, reply *Reply) error {
    *reply = Reply(args.A * args.B)
    return nil
   })
   go clt.Run()

    var rep Reply
    clt.Call("add", Args{5, 2}, &rep)
    fmt.Println("add result:", rep)
   }

我想知道的是,当客户机连接到服务器时,服务器能否使用从客户机连接到服务器的流向客户机发送请求?“远程过程调用”并不意味着客户机发出请求,它只意味着主机打算调用远程主机上的过程。不确定客户机/服务器与它有什么关系。@Pierre LucBertrand:From:“RPC由客户机启动,它向已知的远程服务器发送请求消息,以使用提供的参数执行指定的过程。”\u“这是关于语义的。为请求提供服务的计算机始终是服务器。
// server.go
package main

import (
 "net"
 "github.com/cenkalti/rpc2"
 "fmt"
)

type Args struct{ A, B int }
type Reply int


func main(){
     srv := rpc2.NewServer()
     srv.Handle("add", func(client *rpc2.Client, args *Args, reply *Reply) error{
    // Reversed call (server to client)
    var rep Reply
    client.Call("mult", Args{2, 3}, &rep)
    fmt.Println("mult result:", rep)

    *reply = Reply(args.A + args.B)
    return nil
 })

 lis, _ := net.Listen("tcp", "127.0.0.1:5000")
 srv.Accept(lis)
}
// client.go
package main

import (
 "fmt"
 "github.com/cenkalti/rpc2"
 "net"
)

type Args struct{ A, B int }
type Reply int

func main(){
     conn, _ := net.Dial("tcp", "127.0.0.1:5000")

     clt := rpc2.NewClient(conn)
     clt.Handle("mult", func(client *rpc2.Client, args *Args, reply *Reply) error {
    *reply = Reply(args.A * args.B)
    return nil
   })
   go clt.Run()

    var rep Reply
    clt.Call("add", Args{5, 2}, &rep)
    fmt.Println("add result:", rep)
   }