THRIFT-3219 Provide a C++ tutorial on server-side IP logging and
per-connection state
Client: C++
Patch: Ben Craig <bencraig@apache.org>
This closes #538
diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/CppServer.cpp
index 6b22193..eafffa9 100644
--- a/tutorial/cpp/CppServer.cpp
+++ b/tutorial/cpp/CppServer.cpp
@@ -18,15 +18,18 @@
*/
#include <thrift/concurrency/ThreadManager.h>
-#include <thrift/concurrency/PosixThreadFactory.h>
+#include <thrift/concurrency/PlatformThreadFactory.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/server/TThreadPoolServer.h>
#include <thrift/server/TThreadedServer.h>
#include <thrift/transport/TServerSocket.h>
+#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/TToString.h>
+#include <boost/make_shared.hpp>
+
#include <iostream>
#include <stdexcept>
#include <sstream>
@@ -104,37 +107,71 @@
map<int32_t, SharedStruct> log;
};
-int main() {
- boost::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
- boost::shared_ptr<CalculatorHandler> handler(new CalculatorHandler());
- boost::shared_ptr<TProcessor> processor(new CalculatorProcessor(handler));
- boost::shared_ptr<TServerTransport> serverTransport(new TServerSocket(9090));
- boost::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
+/*
+ CalculatorIfFactory is code generated.
+ CalculatorCloneFactory is useful for getting access to the server side of the
+ transport. It is also useful for making per-connection state. Without this
+ CloneFactory, all connections will end up sharing the same handler instance.
+*/
+class CalculatorCloneFactory : virtual public CalculatorIfFactory {
+ public:
+ virtual ~CalculatorCloneFactory() {}
+ virtual CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo)
+ {
+ boost::shared_ptr<TSocket> sock = boost::dynamic_pointer_cast<TSocket>(connInfo.transport);
+ cout << "Incoming connection\n";
+ cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n";
+ cout << "\tPeerHost: " << sock->getPeerHost() << "\n";
+ cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n";
+ cout << "\tPeerPort: " << sock->getPeerPort() << "\n";
+ return new CalculatorHandler;
+ }
+ virtual void releaseHandler( ::shared::SharedServiceIf* handler) {
+ delete handler;
+ }
+};
- TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
+int main() {
+ TThreadedServer server(
+ boost::make_shared<CalculatorProcessorFactory>(boost::make_shared<CalculatorCloneFactory>()),
+ boost::make_shared<TServerSocket>(9090), //port
+ boost::make_shared<TBufferedTransportFactory>(),
+ boost::make_shared<TBinaryProtocolFactory>());
+
+ /*
+ // if you don't need per-connection state, do the following instead
+ TThreadedServer server(
+ boost::make_shared<CalculatorProcessor>(boost::make_shared<CalculatorHandler>()),
+ boost::make_shared<TServerSocket>(9090), //port
+ boost::make_shared<TBufferedTransportFactory>(),
+ boost::make_shared<TBinaryProtocolFactory>());
+ */
/**
- * Or you could do one of these
+ * Here are some alternate server types...
+
+ // This server only allows one connection at a time, but spawns no threads
+ TSimpleServer server(
+ boost::make_shared<CalculatorProcessor>(boost::make_shared<CalculatorHandler>()),
+ boost::make_shared<TServerSocket>(9090),
+ boost::make_shared<TBufferedTransportFactory>(),
+ boost::make_shared<TBinaryProtocolFactory>());
const int workerCount = 4;
boost::shared_ptr<ThreadManager> threadManager =
ThreadManager::newSimpleThreadManager(workerCount);
- boost::shared_ptr<PosixThreadFactory> threadFactory =
- boost::shared_ptr<PosixThreadFactory>(new PosixThreadFactory());
- threadManager->threadFactory(threadFactory);
+ threadManager->threadFactory(
+ boost::make_shared<PlatformThreadFactory>());
threadManager->start();
- TThreadPoolServer server(processor,
- serverTransport,
- transportFactory,
- protocolFactory,
- threadManager);
- TThreadedServer server(processor,
- serverTransport,
- transportFactory,
- protocolFactory);
-
+ // This server allows "workerCount" connection at a time, and reuses threads
+ TThreadPoolServer server(
+ boost::make_shared<CalculatorProcessorFactory>(boost::make_shared<CalculatorCloneFactory>()),
+ boost::make_shared<TServerSocket>(9090),
+ boost::make_shared<TBufferedTransportFactory>(),
+ boost::make_shared<TBinaryProtocolFactory>(),
+ threadManager);
*/
cout << "Starting the server..." << endl;