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

TA貢獻1796條經驗 獲得超4個贊
RPC是一項(遠程)服務。每當某些計算機請求遠程服務時,它就充當客戶端,要求服務器提供該服務。在此“定義”中,服務器調用客戶端RPC的概念沒有明確定義的含義。
- 3 回答
- 0 關注
- 227 瀏覽
添加回答
舉報