亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Go中來自客戶端和服務器的RPC

Go中來自客戶端和服務器的RPC

Go
一只斗牛犬 2021-04-26 17:43:17
使用net/rpcGo中的軟件包,實際上是否可以從服務器向客戶端進行RPC調用?如果沒有,是否有更好的解決方案?
查看完整描述

3 回答

?
滄海一幻覺

TA貢獻1824條經驗 獲得超5個贊

我目前正在使用thrift(thrift4go)來實現服務器->客戶端和客戶端->服務器RPC功能。默認情況下,thrift僅像net / rpc一樣執行客戶端->服務器調用。由于還需要服務器與客戶機之間的通信,因此我進行了一些研究,發現bidi-thrift。Bidi-thrift解釋了如何連接Java服務器+ Java客戶端進行雙向節儉通信。


比迪蒂節儉是做什么的,它的局限性。

TCP連接具有傳入和傳出的通信線路(RC和TX)。bidi-thrift的想法是將RS和TX分開,并將它們提供給客戶端應用程序和服務器應用程序上的服務器(處理器)和客戶端(遠程)。我發現在Go中很難做到這一點。同樣,這種方式沒有“響應”的可能(正在使用響應線)。因此,服務中的所有方法都必須“單向無效”。(開火忘了,打電話沒有結果)。


解決方案

我改變了“比迪節約”的概念,使客戶端打開了到服務器的兩個連接,即A和B。第一個連接(A)用于執行客戶端->服務器通信(客戶端照常進行呼叫)。第二個連接(B)被“劫持”,并且連接到客戶端上的服務器(處理器),而第二個連接(B)連接到服務器上的客戶端(遠程)。我已經將其與Go服務器和Java客戶端一起使用了。效果很好。它既快速又可靠(就像普通的節儉一樣)。


一些來源。B連接(服務器->客戶端)的設置如下:


轉到服務器

// 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();

}


查看完整回答
反對 回復 2021-05-17
?
SMILET

TA貢獻1796條經驗 獲得超4個贊

RPC是一項(遠程)服務。每當某些計算機請求遠程服務時,它就充當客戶端,要求服務器提供該服務。在此“定義”中,服務器調用客戶端RPC的概念沒有明確定義的含義。


查看完整回答
反對 回復 2021-05-17
  • 3 回答
  • 0 關注
  • 227 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號