From 01963a23ea37684139a1873df5ff2234cd5726f0 Mon Sep 17 00:00:00 2001 From: Peter Thorson Date: Thu, 21 Nov 2013 20:17:39 -0600 Subject: [PATCH] working copy of app client tutorial example --- examples/app_client/CMakeLists.txt | 11 ++ examples/app_client/SConscript | 23 ++++ examples/app_client/app_client.cpp | 169 +++++++++++++++++++++++++++++ 3 files changed, 203 insertions(+) create mode 100644 examples/app_client/CMakeLists.txt create mode 100644 examples/app_client/SConscript create mode 100644 examples/app_client/app_client.cpp diff --git a/examples/app_client/CMakeLists.txt b/examples/app_client/CMakeLists.txt new file mode 100644 index 0000000000..d8a2efca2f --- /dev/null +++ b/examples/app_client/CMakeLists.txt @@ -0,0 +1,11 @@ + +file (GLOB SOURCE_FILES *.cpp) +file (GLOB HEADER_FILES *.hpp) + +init_target (app_client) + +build_executable (${TARGET_NAME} ${SOURCE_FILES} ${HEADER_FILES}) + +link_boost () +final_target () + diff --git a/examples/app_client/SConscript b/examples/app_client/SConscript new file mode 100644 index 0000000000..9795d7ebe3 --- /dev/null +++ b/examples/app_client/SConscript @@ -0,0 +1,23 @@ +## App client example +## + +Import('env') +Import('env_cpp11') +Import('boostlibs') +Import('platform_libs') +Import('polyfill_libs') + +env = env.Clone () +env_cpp11 = env_cpp11.Clone () + +prgs = [] + +# if a C++11 environment is available build using that, otherwise use boost +if env_cpp11.has_key('WSPP_CPP11_ENABLED'): + ALL_LIBS = boostlibs(['system'],env_cpp11) + [platform_libs] + [polyfill_libs] + prgs += env_cpp11.Program('app_client', ["app_client.cpp"], LIBS = ALL_LIBS) +else: + ALL_LIBS = boostlibs(['system','random'],env) + [platform_libs] + [polyfill_libs] + prgs += env.Program('app_client', ["app_client.cpp"], LIBS = ALL_LIBS) + +Return('prgs') diff --git a/examples/app_client/app_client.cpp b/examples/app_client/app_client.cpp new file mode 100644 index 0000000000..13bb6a0b7b --- /dev/null +++ b/examples/app_client/app_client.cpp @@ -0,0 +1,169 @@ +#include +#include +#include + +#include +#include +#include +#include + +typedef websocketpp::client client; + +using websocketpp::lib::placeholders::_1; +using websocketpp::lib::placeholders::_2; +using websocketpp::lib::bind; + +// pull out the type of messages sent by our config +typedef websocketpp::config::asio_client::message_type::ptr message_ptr; + +int case_count = 0; + +void on_message(client* c, websocketpp::connection_hdl hdl, message_ptr msg) { + client::connection_ptr con = c->get_con_from_hdl(hdl); + + if (con->get_resource() == "/getCaseCount") { + std::cout << "Detected " << msg->get_payload() << " test cases." + << std::endl; + case_count = atoi(msg->get_payload().c_str()); + } else { + c->send(hdl, msg->get_payload(), msg->get_opcode()); + } +} + +class app_connection { +public: + typedef websocketpp::lib::shared_ptr ptr; + + app_connection(size_t id, websocketpp::connection_hdl hdl) + : m_id(id) + , m_hdl(hdl) {} + + void on_message(websocketpp::connection_hdl, message_ptr msg) { + m_messages.push_back(msg->get_payload()); + } + void on_fail(websocketpp::connection_hdl) { + + } + void on_open(websocketpp::connection_hdl) { + + } + void on_close(websocketpp::connection_hdl) { + + } + + bool print_new_messages() { + websocketpp::lib::lock_guard guard(m_mutex); + + if (m_messages.empty()) { + return false; + } + + while(!m_messages.empty()) { + std::cout << m_messages.front() << std::endl; + m_messages.pop_front(); + } + } + + websocketpp::connection_hdl get_hdl() const { + return m_hdl; + } +private: + websocketpp::lib::mutex m_mutex; + size_t m_id; + // list of messages + std::queue m_messages; + websocketpp::connection_hdl m_hdl; +}; + +class continuous_client_manager { +public: + continuous_client_manager() : next_id(0) { + // clear all error/access channels + m_endpoint.clear_access_channels(websocketpp::log::alevel::all); + m_endpoint.clear_error_channels(websocketpp::log::elevel::all); + + // Initialize the endpoint + m_endpoint.init_asio(); + + // Mark this endpoint as perpetual. Perpetual endpoints will not exit + // even if there are no connections. + m_endpoint.start_perpetual(); + + // Start a background thread and run the endpoint in that thread + m_thread.reset(new thread_type(&client::run, &m_endpoint)); + } + + app_connection::ptr connect(std::string const & uri) { + websocketpp::lib::error_code ec; + + // connect to this address + client::connection_ptr con = m_endpoint.get_connection(uri,ec); + if (ec) { + return app_connection::ptr(); + } + + + app_connection::ptr app(new app_connection(next_id++,con->get_handle())); + + con->set_open_handler(bind(&app_connection::on_open,*app)); + con->set_fail_handler(bind(&app_connection::on_fail,*app)); + con->set_message_handler(bind(&app_connection::on_message,*app)); + con->set_close_handler(bind(&app_connection::on_close,*app)); + + m_endpoint.connect(con); + + return app; + } + + void close(websocketpp::connection_hdl hdl) { + + } + + void shutdown() { + // for each connection call close + + // Unflag the endpoint as perpetual. This will instruct it to stop once + // all connections are finished. + m_endpoint.stop_perpetual(); + + // Block until everything is done + m_thread->join(); + } +private: + typedef websocketpp::lib::thread thread_type; + typedef websocketpp::lib::shared_ptr thread_ptr; + + size_t next_id; + + std::map m_connections; + client m_endpoint; + thread_ptr m_thread; +}; + +int main(int argc, char* argv[]) { + continuous_client_manager client; + + std::string command; + bool done = false; + + while (!done) { + std::getline(std::cin, command); + + if (command == "quit") { + done = true; + } else if (command == "list") { + + } else if (command.substr(0,7) == "connect") { + + } else if (command.substr(0,5) == "close") { + + } else if (command.substr(0,8) == "messages") { + + } else { + std::cout << "Invalid Command" << std::endl; + } + } + + // close connections and stop the endpoint + client.shutdown(); +}