I would like to use several services on one transport (Thrift)

I would like to create several services, and I want to use them with different identifiers. Therefore, I mean:

I have a Users and Projects service. I want to use them at the same time.

I mean, I can add more "services" to the "handlermap" on xmlrpc.

http://ws.apache.org/xmlrpc/server.html

phm.addHandler("Users", Users.class); phm.addHandler("Projects", Projects.class); 

I would like to do the same in charity.

Here is a simple example: test.thrift

 typedef i64 UserId struct Bonk { 1: string message, 2: i32 type } struct Insanity { 1: map<Bonk, UserId> userMap, 2: list<Bonk> xtructs } service ThriftTest { void testVoid(), string testString(1: string test), byte testByte(1: byte test), i32 testI32(1: i32 test), i64 testI64(1: i64 test), double testDouble(1: double test), list<map<i32,i32>> testMap(1: map<i32,i32> test), map<string,string> testStringMap(1: map<string,string> test), set<i32> testSet(1: set<i32> test), map<i32,map<i32,i32>> testMapMap(1: i32 test), map<UserId, map<i32,Insanity>> testInsanity(1: Insanity argument) } 

Then I create an implementation and then add it to the server instance.

 Users.Processor users_proccesor = new Users.Processor(New UsersImpl()); Projects.Processor project_processor = new Projects.Processors(new ProjectsImp()); // I would like to add Users and Projects ThriftTest.Processor prc = new ThriftTest.Processor(new ThiftTestImp()); TServerTransport serverTransport = new TServerSocket(9090); TServer server = new TSimpleServer(new Args(serverTransport).processor( prc )); 

And here is my big problem, I cannot add multiple server instances.

Thank you for your help.

+6
source share
2 answers

Multiplexed services (essentially what you want to do here) are being integrated right now. Corrections are already available for a number of available languages ​​that are already adopted or under consideration.

https://issues.apache.org/jira/browse/THRIFT-563 is a good place to start.

PS: reviewers and contributions are welcome; -)

+7
source

An RPC call is sent over the wire in a TMessage structure that does not have a targetService field. Thus, there is no easy way to bind multiple services to one port without adding this field to TMessage and recompiling lean.

Hacking is possible by implementing a custom TServer similar to TSimpleSever (or any other server).

The server should read the target service in a loop and get the appropriate processor:

  ... inputProtocol = inputProtocolFactory_.getProtocol(inputTransport); outputProtocol = outputProtocolFactory_.getProtocol(outputTransport); do { String target = inputProtocol.readString(); processor = processorFactoryMap.get(target).getProcessor(client); while (processor.process(inputProtocol, outputProtocol)); ... 

The client must prefix each message with the target service line. This can be done by wrapping TBinaryProtocol in a user protocol:

 public void writeMessageBegin(TMessage message) throws TException { wrapped.writeString(target); wrapped.writeMessageBegin(message); } 

The main disadvantage of this approach is the loss of compatibility with other customers. Thus, it might be better to either run two different TServers on different ports, or define all the methods in the same binding service, and then delegate calls to the appropriate handlers.

+4
source

Source: https://habr.com/ru/post/894073/


All Articles