ZBLOG

C++实现websocket 加密客户端

WebSocket 客户端可以使用 WebSocket++ 库,加密可以使用 OpenSSL 库。

下面是一个简单的例子:

”`cpp #include #include #include #include #include #include

using websocketpp::lib::placeholders::_1; using websocketpp::lib::placeholders::_2; using websocketpp::lib::bind;

typedef websocketpp::clientwebsocketpp::config::asio_tls_client client;

class connection_metadata { public:

typedef std::shared_ptr<connection_metadata> ptr;

connection_metadata(int id, websocketpp::connection_hdl hdl, std::string uri)
    : m_id(id), m_hdl(hdl), m_status("Connecting"), m_uri(uri), m_server("N/A") {}

void on_open(client *c, websocketpp::connection_hdl hdl) {
    m_status = "Open";

    client::connection_ptr con = c->get_con_from_hdl(hdl);
    m_server = con->get_response_header("Server");
}

void on_fail(client *c, websocketpp::connection_hdl hdl) {
    m_status = "Failed";

    client::connection_ptr con = c->get_con_from_hdl(hdl);
    m_server = con->get_response_header("Server");
    m_error_reason = con->get_ec().message();
}

void on_close(client *c, websocketpp::connection_hdl hdl) {
    m_status = "Closed";
    client::connection_ptr con = c->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();
}

std::string get_status() {
    return m_status;
}

void record_sent_message(std::string message) {
    m_sent_messages.push_back(message);
}

private:

int m_id;
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_sent_messages;

};

class websocket_endpoint { public:

typedef websocketpp::lib::shared_ptr<websocket_endpoint> ptr;

 websocket_endpoint(const std::string& uri)
     :m_client(),m_endpoint(m_client.get_io_service()),m_status("Connecting"),m_uri(uri),m_open(false) {

     // set access channels
     m_client.clear_access_channels(websocketpp::log::alevel::all);
     m_client.set_access_channels(websocketpp::log::alevel::connect);
     m_client.set_access_channels(websocketpp::log::alevel::disconnect);

     // Initialize ASIO
     m_client.init_asio();

     // Register our message handler
     using namespace websocketpp;   

     //设置加密证书
    if (SSL_library_init()<0) {    
         printf("Could not initialize the OpenSSL library !\n");
    }

    SSL_load_error_strings();  

    const SSL_METHOD *method = TLSv1_2_client_method();    

    SSL_CTX* ctx = SSL_CTX_new(method); 

   if (!ctx){    
       printf("Unable to create a new SSL context structure.\n");    
       exit(0);    
   }    

  //加载受信任的根证书 
  if (SSL_CTX_load_verify_locations(ctx, "path/to/ca-bundle.crt", NULL) <= 0){    
      printf("Unable to load CA reference!\n");    
      SSL_CTX_free(ctx); 
      exit(0);    
  } 

    m_client.set_tls_init_handler(bind(&websocket_endpoint::on_tls_init,this,_1));

     m_client.set_message_handler(bind(&websocket_endpoint::on_message,this,_1,_2));
     m_client.set_open_handler(bind(&websocket_endpoint::on_open,this,_1));
     m_client.set_close_handler(bind(&websocket_endpoint::on_close,this,_1));
     m_client.set_fail_handler(bind(&websocket_endpoint::on_fail,this,_1));

 }

void connect() {
    try {
        websocketpp::lib::error_code ec;

        client::connection_ptr con = m_client.get_connection(m_uri, ec);

        if (ec) {
            std::cout << "could not create connection because: " << ec.message() << std::endl;
            return;
        }

        // Grab a handle for this connection so we can talk to it in a thread
        // safe manor after the event loop starts.
        websocketpp::connection_hdl hdl = con->get_handle();
        connection_metadata::ptr metadata_ptr(new connection_metadata(0, hdl, m_uri));
        m_connection_metadata.push_back(metadata_ptr);

        // Set the initial status of this connection to connecting. This will
        // change to open or closed appropriately once the socket is connected
        // successfully or fails to connect.
         metadata_ptr->m_status = "Connecting";

         metadata_ptr->record_sent_message("hello world");

         //在http header 中设置加密key

         unsigned char key[17]={'\0'};
         for(int i=0;i<16;i++){
             key[i]=(unsigned char)(rand()%256);
             key[16]= '\0';
         }

        std::string base64Key = base64_encode(reinterpret_cast<const unsigned char*>(key), 16);
        con->replace_header("Sec-WebSocket-Key",base64Key);

        // Perform the connect operation. This will block until the connection is
        // complete or fails.
        m_client.connect(con);

    } catch (websocketpp::exception const & e) {
        std::cout << "Exception: " << e.what() << std::endl;
    }
}

void close(websocketpp::close::status::value code, std::string reason) {
    websocketpp::lib::error_code ec;

    for (auto it : m_connection_metadata) {
        if (it->m_status == "Open") {
            m_client.close(it->m_hdl, code, reason, ec);
            if (ec) {
                std::cout << "> Error closing connection " << it->m_hdl.lock().get()
                          << ": " << ec.message() << std::endl;
            }
        }
    }
}

private:

void on_open(websocketpp::connection_hdl hdl) {
    auto metadata_ptr = get_metadata(hdl);
    metadata_ptr->on_open(&m_client,hdl);
    metadata_ptr->m_status = "Open";
    m_open=true;




内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=7058

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?