I'd like to create several services, and I want to use them with different identifiers. So I mean :
I've got a Users and Projects service . I want to use these 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 the thrift.
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 implementatino, then add it to the instance of TServer .
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's my big problem, I can't add multiple instances of the server.
Thank you for your help in advance.
Multiplexed Services (in essence that's what you want to do here) are being integrated right now. There are already patches for a number of languages available, either already accepted or in the process of being reviewed.
https://issues.apache.org/jira/browse/THRIFT-563 is a good place to start.
PS: Reviewers and contributions are welcome ;-)
RPC invocation is transmitted over the wire in TMessage structure that doesn't have 'targetService' field. So there's no straightforward way to bind several services to a single port without adding this field to TMessage and recompiling thrift.
It's possible to do a hack by implementing custom TServer similar to TSimpleSever (or any other TServer).
Server should read target service in the loop and get corresponding 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));
...
Client should prefix each message with target service string. This can be done by wrapping TBinaryProtocol in a custom protocol:
public void writeMessageBegin(TMessage message) throws TException {
wrapped.writeString(target);
wrapped.writeMessageBegin(message);
}
The main disadvantage of this approach is losing interoperability with other clients. So, probably it's better either to start two different TServers on different ports, or define all methods in a single thrift service, and then delegate invocations to appropriate handlers.
精彩评论