zoukankan      html  css  js  c++  java
  • Qt编写websocketpp客户端

    1、下载websocketpp,地址为https://github.com/zaphoyd/websocketpp,版本为0.7。

    2、下载boost,地址为https://www.boost.org/,版本为1.6.3。

    3、说明:websocketpp并不是必须需要boost,如果C++编译为C11以上,是可以不用的。

    4、Qt创建一个console工程(如:websocketClient),将下载下来的websocket_master里面的websocket文件夹放到该工程目录下,在webSocketClient.pro文件中添加include(websocket/websocket.pri),       

    5、创建websocket_client类,头文件websocket_client.h内容如下:

      #include <websocketpp/config/asio_no_tls_client.hpp>

      #include <websocketpp/client.hpp>

      #include <websocketpp/common/thread.hpp>

      #include <websocketpp/common/memory.hpp>

      #include <iostream>

      #include <sstream>

      #include <cstdlib>

      #include <string>

      #include <map>

      using namespace websocketpp::lib::placeholders;

      typedef websocketpp::client<websocketpp::config::asio_client> client;

      class connection_metadata
      {
      public:
        typedef websocketpp::lib::shared_ptr<connection_metadata> ptr;

        connection_metadata(websocketpp::connection_hdl hdl, std::string uri)

              : m_hdl(hdl)

              , m_status("Connecting")

              , m_uri(uri)

              , m_server("N/A")

        {}  

        void on_open(client *echo_client, websocketpp::connection_hdl hdl)

        {

          m_status = "Open";

               client::connection_ptr con = echo_client->get_con_from_hdl(hdl);

               m_server = con->get_response_header("Server");

        }

        void on_fail(client *echo_client, websocketpp::connection_hdl hdl

        {

          m_status = "Failed";

               client::connection_ptr con = echo_client->get_con_from_hdl(hdl);

               m_server = con->get_response_header("Server");

               m_error_reason = con->get_ec().message();

        }  

        void on_close(client *echo_client, websocketpp::connection_hdl hdl)

        {

               m_status = "Closed";

               client::connection_ptr con = echo_client->get_con_from_hdl(hdl);

               std::stringstream s;

             s << "close code: " << con->get_remote_close_code() << " ("

                  << websocketpp::close::status::get_string(con->get_remote_close_code())

                  << "), close reason: " << con->get_remote_close_reason();

               m_error_reason = s.str();

        }

        void on_message(websocketpp::connection_hdl hdl, client::message_ptr msg)

        {

              if(msg->get_opcode() == websocketpp::frame::opcode::text)

              {

                    std::cout << "on message called with hdl: " << hdl.lock().get() << "and message: " << msg->get_payload() << std::endl;

                    m_messages.push_back("<< " + msg->get_payload());

              }

             else

             {

                  m_messages.push_back("<< " + websocketpp::utility::to_hex(msg->get_payload()));

             }

        }   

        websocketpp::connection_hdl get_hdl() const

             {

              return m_hdl;

             }

        std::string get_status() const

        {

          return m_status;

        }

        std::string get_uri() const

        {

          return m_uri;

        }

        void record_sent_message(std::string message)

        {

          m_messages.push_back(">> " + message);

        }

        friend std::ostream & operator<< (std::ostream & out, connection_metadata const & data);

      private:

        websocketpp::connection_hdl m_hdl;

        std::string m_status;

        std::string m_uri;

        std::string m_server;

        std::string m_error_reason;

        std::vector<std::string> m_messages;

      };

      std::ostream & operator<< (std::ostream & out, connection_metadata const & data);

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

      class websocket_client

      {
      public:
        websocket_client();
        ~websocket_client();

        int connect(std::string const & uri);
        void close();

        void send(std::string message);
        void show();

      private:

          client echo_client;

          connection_metadata::ptr Con;

          websocketpp::lib::shared_ptr<websocketpp::lib::thread> m_thread;

      };

      websocket_client.cpp文件内容如下:

      std::ostream & operator<< (std::ostream & out, connection_metadata const & data)

      {

        out << "> URI: " << data.m_uri << " "

          << "> Status: " << data.m_status << " "

          << "> Remote Server: " << (data.m_server.empty() ? "None Specified" : data.m_server) << " "

          << "> Error/close reason: " << (data.m_error_reason.empty() ? "N/A" : data.m_error_reason) << " ";

        out << "> Messages Processed: (" << data.m_messages.size() << ") ";

        for (std::vector<std::string>::const_iterator it = data.m_messages.begin(); it != data.m_messages.end(); ++it)

        {

          out << *it << " ";

        }

        return out;

      }

      websocket_endpoint::websocket_endpoint()

      {

        echo_client.clear_access_channels(websocketpp::log::alevel::all);

        echo_client.clear_error_channels(websocketpp::log::elevel::all);

        echo_client.init_asio();

         echo_client.start_perpetual();

        m_thread = websocketpp::lib::make_shared<websocketpp::lib::thread>(&client::run, &echo_client);

      }

      websocket_endpoint::~websocket_endpoint()

      {

        echo_client.stop_perpetual();

        if(Con->get_status() == "Open")

        {

          websocketpp::lib::error_code ec;

          echo_client.close(Con->get_hdl(), websocketpp::close::status::going_away, "", ec);

          if(ec)

          {

            std::cout << "> Error closing ws connection " << Con->get_uri() << " :" << ec.message() << std::endl;

          }

        }

        m_thread->join();

      }

      int websocket_endpoint::connect(std::string const & uri)

      {

        websocketpp::lib::error_code ec;

        client::connection_ptr pConnection = echo_client.get_connection(uri,ec);

        if(ec)

        {

          std::cout << "> Connect initialization error: " << ec.message() << std::endl;

          return -1;

        }

        Con = websocketpp::lib::make_shared<connection_metadata>(pConnection->get_handle(),uri);

        pConnection->set_open_handler(websocketpp::lib::bind(&connection_metadata::on_open,Con,&echo_client,::_1));

        pConnection->set_fail_handler(websocketpp::lib::bind(&connection_metadata::on_fail,Con,&echo_client,::_1));

        pConnection->set_close_handler(websocketpp::lib::bind(&connection_metadata::on_close,Con,&echo_client,::_1));

        pConnection->set_message_handler(websocketpp::lib::bind(&connection_metadata::on_message,Con,::_1,::_2));

        echo_client.connect(pConnection);

        return 0;

      }

      void websocket_endpoint::close()

      {

        if(Con->get_status() == "Open")

        {

          websocketpp::lib::error_code ec;

          echo_client.close(Con->get_hdl(),websocketpp::close::status::normal,"",ec);

          if(ec)

          {

            std::cout << "> Error initiating close: " << ec.message() << std::endl;

          }

        }

      }

      void websocket_endpoint::send(std::string message)

      {

        websocketpp::lib::error_code ec;

        echo_client.send(Con->get_hdl(), message, websocketpp::frame::opcode::text, ec);

        if(ec)

        {

          std::cout << "> Error sending messages: " << ec.message() <<std::endl;

          return;

        }

        Con->record_sent_message(message);

      }

      void websocket_endpoint::show()

      {

        std::cout << *Con << std::endl;

      }

    6、运行程序后,在终端输入命令

     Enter Command: send 11111111(向服务器发送1111111111)

    Enter Command:show(显示websocketpp客户端信息及已经发送和接收的数据)

    Enter Command:quit(退出)

  • 相关阅读:
    23.什么是控制文件?
    路由器原理及路由协议
    大家帮忙看看,不会即使显示串口缓冲数据
    c# interface
    ip classless&no ip classless
    Visual Studio 2010 Visual C++ 确定要重新分发的 DLL
    fibonacci算法
    loopback端口作用
    疑惑的virtual method
    Read MBR via ReadFile function
  • 原文地址:https://www.cnblogs.com/zhangnianyong/p/9090987.html
Copyright © 2011-2022 走看看