RPC from the client and server in Go

Is it actually possible to use the net/rpc package in Go to make RPC calls from the server to the client? If not, is there a better solution out there?
I am currently using thrift (thrift4go) for server->client and client>server RPC functions. By default Next, thrift only performs client>server calls, just like net/rpc. Since I also need server->client communication, I did some research and found bidi-thrift. Bidi-thrift explained how to connect to the java server java client for two-way thrift communication.

What is the role of bidi frugality and its limitations.

TCP connection has receiving and output communication lines (RC and TX). The idea of ​​bidi-thrift is to split RS and TX and provide them to the server (processor) and client (remote) on the client application and the server application. I find it difficult to do in Go Up to this point. In addition, there is no “response” in this way (the response line is in use). Therefore, all methods in the service must be “one-way invalid”. (Fire and forget, the call has no result).

Solution

I changed the idea of ​​bidi-thrift and let the client open two connections to server A and B. The first connection (A) is used to execute the client -> Server communication (the client makes the call as usual). The second connection (B) is’hijacked’ and connects to the server (processor) on the client and at the same time connects to the client (remote) on the server. I Use Go server and Java client. It works very well. It is fast and reliable (just like normal thrift).

Some sources.. B connection (server->client) is set up as follows:< /p>

Go to the 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(), " ")
return
}
serverTransport, err := thrift.NewTServerSocketAddr (addr)
if err != nil {
log.Print("Error creating server socket: ", err.Error(), " ")
return
}

// Start the server to listen for connections
log.Print("Starting the server for B communication (server->client) on ", addr, " ")
err = serverTransport.Listen()
if err != nil {
log.Print("Error during B server: ", err.Error(), " ")
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)
cl ient := 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 ", err)
}

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

Java client

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

/* 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() {< br /> 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();
}

Is it actually possible to use the net/rpc package in Go from the server to Does the client make an RPC call? If not, is there a better solution out there?

I am currently using thrift (thrift4go) for server->client and client>server RPC functions. By default, thrift only performs client>server calls, just Like net/rpc. Since I also need server->client communication, I did some research and found bidi-thrift. Bidi-thrift explained how to connect java server and java client for two-way thrift communication.

What is the effect of bidi frugality and its limitations.

TCP connection has receiving and output communication lines (RC and TX). The idea of ​​bidi-thrift is to split RS And TX, and provide them to the client application and the server (processor) and client (remote) on the server application. I find it difficult to do this in Go. Also, this way does not exist” “Response” (the response line is in use). Therefore, all methods in the service must be “one-way invalid”. (Fire and forget, the call has no result).

Solution

I changed the idea of ​​bidi-thrift and let the client open two connections to servers A and B. The first connection (A) is used to perform client->server communication (the client makes the call as usual). The second connection (B) is’hijacked’ and connects to the server (processor) on the client, and at the same time connects to the client (remote) on the server. I use a Go server and a Java client. It works very well Good. It is fast and reliable (just like normal thrift).

Some sources.. B connection (server->client) settings are as follows:

Go to the 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.Er ror(), " ")
return
}
serverTransport, err := thrift.NewTServerSocketAddr(addr)
if err != nil {
log. Print("Error creating server socket: ", err.Error(), " ")
return
}

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

// Accept new connections and handle those
for {
transport, err := serverTransport.Accept()
if err != nil {
return //err
}< br /> 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 ", err)
}

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

Java client

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

< br />/* 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 trans port 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();
}

Leave a Comment

Your email address will not be published.