diff options
author | Ben Craig <bencraig@apache.org> | 2015-07-04 17:18:58 -0500 |
---|---|---|
committer | Ben Craig <bencraig@apache.org> | 2015-07-04 17:18:58 -0500 |
commit | 74086f18afa336000c3cf210939b1a1b843faaa5 (patch) | |
tree | 417f6208f7b7bbde5a7ea80e1a3afcdec01eb261 /tutorial/cpp | |
parent | 5903d6745989897fae58f8370c62a1dd5bfe7e66 (diff) | |
download | thrift-74086f18afa336000c3cf210939b1a1b843faaa5.tar.gz |
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
Diffstat (limited to 'tutorial/cpp')
-rw-r--r-- | tutorial/cpp/CMakeLists.txt | 51 | ||||
-rw-r--r-- | tutorial/cpp/CppServer.cpp | 81 |
2 files changed, 110 insertions, 22 deletions
diff --git a/tutorial/cpp/CMakeLists.txt b/tutorial/cpp/CMakeLists.txt new file mode 100644 index 000000000..2b0c1439b --- /dev/null +++ b/tutorial/cpp/CMakeLists.txt @@ -0,0 +1,51 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +find_package(Boost 1.53.0 REQUIRED) +include_directories(SYSTEM "${Boost_INCLUDE_DIRS}") + +#Make sure gen-cpp files can be included +include_directories("${CMAKE_CURRENT_BINARY_DIR}") +include_directories("${CMAKE_CURRENT_BINARY_DIR}/gen-cpp") +include_directories("${PROJECT_SOURCE_DIR}/lib/cpp/src") + +include(ThriftMacros) + +set(tutorialgencpp_SOURCES + gen-cpp/Calculator.cpp + gen-cpp/SharedService.cpp + gen-cpp/shared_constants.cpp + gen-cpp/shared_types.cpp + gen-cpp/tutorial_constants.cpp + gen-cpp/tutorial_types.cpp +) +add_library(tutorialgencpp STATIC ${tutorialgencpp_SOURCES}) +LINK_AGAINST_THRIFT_LIBRARY(tutorialgencpp thrift) + +add_custom_command(OUTPUT gen-cpp/Calculator.cpp gen-cpp/SharedService.cpp gen-cpp/shared_constants.cpp gen-cpp/shared_types.cpp gen-cpp/tutorial_constants.cpp gen-cpp/tutorial_types.cpp + COMMAND thrift-compiler --gen cpp -r ${PROJECT_SOURCE_DIR}/tutorial/tutorial.thrift +) + +add_executable(TutorialServer CppServer.cpp) +target_link_libraries(TutorialServer tutorialgencpp) +LINK_AGAINST_THRIFT_LIBRARY(TutorialServer thrift) + +add_executable(TutorialClient CppClient.cpp) +target_link_libraries(TutorialClient tutorialgencpp) +LINK_AGAINST_THRIFT_LIBRARY(TutorialClient thrift) diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/CppServer.cpp index 6b22193a4..eafffa973 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 @@ protected: 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; |