当前位置 : 主页 > 大数据 > 区块链 >

Go中来自客户端和服务器的RPC

来源:互联网 收集:自由互联 发布时间:2021-06-22
实际上是否可以使用Go中的net / rpc包从服务器到客户端进行RPC调用?如果不是,那里有更好的解决方案吗? 我目前正在使用thrift( thrift4go)进行server-客户端和客户端服务器RPC功能.默认情况
实际上是否可以使用Go中的net / rpc包从服务器到客户端进行RPC调用?如果不是,那里有更好的解决方案吗? 我目前正在使用thrift( thrift4go)进行server->客户端和客户端>服务器RPC功能.默认情况下,thrift只执行客户端>服务器调用,就像net / rpc一样.由于我还需要服务器 – >客户端通信,我做了一些研究并找到了 bidi-thrift.Bidi-thrift解释了如何连接java服务器java客户端以进行双向thrift通信.

比迪烟节俭有什么作用,它的局限性.

TCP连接具有接收和输出通信线路(RC和TX). bidi-thrift的想法是拆分RS和TX,并将它们提供给客户端应用程序和服务器应用程序上的服务器(处理器)和客户端(远程).我发现在Go中很难做到这一点.此外,这种方式不存在“响应”(响应线正在使用中).因此,服务中的所有方法都必须“单向无效”. (火灾和忘记,呼叫没有结果).

解决方案

我改变了bidi-thrift的想法,并让客户端打开两个连接到服务器A和B.第一个连接(A)用于执行客户端 – >服务器通信(客户端像往常一样进行呼叫).第二个连接(B)被’劫持’,并连接到客户端上的服务器(处理器),同时连接到服务器上的客户端(远程).我使用Go服务器和Java客户端.它工作得很好.它快速可靠(就像正常的节俭一样).

一些来源.. B连接(server->客户端)设置如下:

去服务器

// factories
framedTransportFactory := thrift.NewTFramedTransportFactory(thrift.NewTTransportFactory())
protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()

// create socket listener
addr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:9091")
if err != nil {
    log.Print("Error resolving address: ", err.Error(), "\n")
    return
}
serverTransport, err := thrift.NewTServerSocketAddr(addr)
if err != nil {
    log.Print("Error creating server socket: ", err.Error(), "\n")
    return
}

// Start the server to listen for connections
log.Print("Starting the server for B communication (server->client) on ", addr, "\n")
err = serverTransport.Listen()
if err != nil {
    log.Print("Error during B server: ", err.Error(), "\n")
    return //err
}

// Accept new connections and handle those
for {
    transport, err := serverTransport.Accept()
    if err != nil {
        return //err
    }
    if transport != nil {
        // Each transport is handled in a goroutine so the server is availiable again.
        go func() {
            useTransport := framedTransportFactory.GetTransport(transport)
            client := worldclient.NewWorldClientClientFactory(useTransport, protocolFactory)

            // Thats it!
            // Lets do something with the connction
            result, err := client.Hello()
            if err != nil {
                log.Printf("Errror when calling Hello on client: %s\n", err)
            }

            // client.CallSomething()
        }()
    }
}

Java客户端

// preparations for B connection
TTransportFactory transportFactory = new TTransportFactory();
TProtocolFactory protocolFactory = new TBinaryProtocol.Factory();
YourServiceProcessor processor = new YourService.Processor<YourServiceProcessor>(new YourServiceProcessor(this));


/* Create thrift connection for B calls (server -> client) */
try {
    // create the transport
    final TTransport transport = new TSocket("127.0.0.1", 9091);

    // open the transport
    transport.open();

    // add framing to the transport layer
    final TTransport framedTransport = new TFramedTransport(transportFactory.getTransport(transport));

    // connect framed transports to protocols
    final TProtocol protocol = protocolFactory.getProtocol(framedTransport);

    // let the processor handle the requests in new Thread
    new Thread() {
        public void run() {
            try {
                while (processor.process(protocol, protocol)) {}
            } catch (TException e) {
                e.printStackTrace();
            } catch (NullPointerException e) {
                e.printStackTrace();
            }
        }
    }.start();
} catch(Exception e) {
    e.printStackTrace();
}
网友评论