summaryrefslogtreecommitdiff
path: root/tutorial/cpp
diff options
context:
space:
mode:
authorBen Craig <bencraig@apache.org>2015-07-04 17:18:58 -0500
committerBen Craig <bencraig@apache.org>2015-07-04 17:18:58 -0500
commit74086f18afa336000c3cf210939b1a1b843faaa5 (patch)
tree417f6208f7b7bbde5a7ea80e1a3afcdec01eb261 /tutorial/cpp
parent5903d6745989897fae58f8370c62a1dd5bfe7e66 (diff)
downloadthrift-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.txt51
-rw-r--r--tutorial/cpp/CppServer.cpp81
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;