WebSocket 客户端可以使用 WebSocket++ 库,加密可以使用 OpenSSL 库。
下面是一个简单的例子:
”`cpp
#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助手提供,问题来源于学员提问




