最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++編寫的WebSocket服務(wù)端客戶端實現(xiàn)示例代碼

 更新時間:2021年10月28日 10:38:11   作者:kagula086  
本文主要介紹了C++編寫的WebSocket服務(wù)端客戶端實現(xiàn)示例代碼,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

使用過標準的libwebsockets服務(wù)端庫測試過,主要是短小精悍,相對于libwebsockets不需要依賴zlib和openssl 以及其他庫,直接make就可以使用了,linux跟windows都可以使用。

測試用例:

#include "easywsclient.hpp"
#include <assert.h>
#include <stdio.h>
#include <string>
 
using easywsclient::WebSocket;
static WebSocket::pointer ws = NULL;
 
void handle_message(const std::string & message)
{
    printf(">>> %s\n", message.c_str());
    if (message == "world") { ws->close(); }
}
 
int main()
{
    ws = WebSocket::from_url("ws://localhost:8126/foo");
    assert(ws);//判斷ws對象是否為空null
    ws->send("goodbye");
    ws->send("hello");
    //如果你需要多線程,可以在一個thread 維護該ws的連接重連機制
    while (ws->getReadyState() != WebSocket::CLOSED) //判斷ws是否正常連接
    {
      ws->poll();//這個必須要調(diào)用,否則不能發(fā)送,發(fā)送跟接收都是異步的,都是在這個poll函數(shù)里監(jiān)測處理的
      ws->dispatch(handle_message);
    }
    delete ws;
    return 0;
}
//線程thread  維護重連連接
void run()
{
    bool conn = FLASE;
    ws = WebSocket::from_url("ws://localhost:8126/foo");
   
    //如果你需要多線程,可以在一個thread 維護該ws的連接重連機制
    while (1) //判斷ws是否正常連接
    {
      if(ws != NULL)
      {
          ws->poll(0);//這個必須要調(diào)用,否則不能發(fā)送,發(fā)送跟接收都是異步的,都是在這個poll函數(shù)里監(jiān)測處    理的
          ws->dispatch(handle_message);
          if(ws->getReadyState() == WebSocket::CLOSED)  
          {
             //ws連接斷開 重連
             delete ws;
             ws = NULL;
             ws = WebSocket::from_url("ws://localhost:8126/foo");
          }
          else if(wss->getReadyState()== WebSocket::OPEN)
          {
             //ws連接ok
             //    ws->send("goodbye");
             ws->send("hello");
          }
          
      }
      else
      {
        ws = WebSocket::from_url("ws://localhost:8126/foo");
        sleep(1);
      }
      usleep(100);
    }
    if(ws!=NULL)
    delete ws;
}

有細心的朋友發(fā)現(xiàn)在發(fā)送中文GBK 的時候與服務(wù)端會斷開

//GBK -> UTF-8 
//遇到發(fā)送的字符串里有中文的話需要send 前進行轉(zhuǎn)換一下,
//這個是網(wǎng)友提供的在windows下的轉(zhuǎn)換函數(shù)
std::string Server_Stream::GBKToUTF8(const std::string& strGBK)
{
 std::string strOutUTF8 = "";
 WCHAR * str1;
 int n = MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, NULL, 0);
 str1 = new WCHAR[n];
 MultiByteToWideChar(CP_ACP, 0, strGBK.c_str(), -1, str1, n);
 n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
 char * str2 = new char[n];
 WideCharToMultiByte(CP_UTF8, 0, str1, -1, str2, n, NULL, NULL);
 strOutUTF8 = str2;
 delete[]str1;
 str1 = NULL;
 delete[]str2;
 str2 = NULL;
 return strOutUTF8;
}

下面是C++實現(xiàn)的WebSocket客戶端,寫好后這里記一下,免得以后忘記。

本示例共有三個文件組成,依賴Websocket++第三方庫

其中main.cpp是使用示例

#include <iostream>
#include <string>
#include <sstream>
 
#include "websocket_endpoint.h"
 
int main(int argc, char **argv)
{
 bool done = false;
 std::string input;
 kagula::websocket_endpoint endpoint;
 
 endpoint.connect("ws://localhost:9002");
 
 while (!done) {
  std::cout << "Enter Command: ";
  std::getline(std::cin, input);
 
  if (input == "quit") {
   done = true;
  }
  else if (input.substr(0, 4) == "send") {
   std::stringstream ss(input);
 
   std::string cmd;
   std::string message;
 
   ss >> cmd;
   std::getline(ss, message);
 
   endpoint.send(message);
  }
  else if (input.substr(0, 4) == "show") {
   endpoint.show();
  }
  else {
   std::cout << "> Unrecognized Command" << std::endl;
  }
 }
 
 endpoint.close();
 
 return 0;
}

其它兩個文件是封裝

websocket_endpoint.h文件清單

#ifndef _WEBSOCKET_ENDPOINT_
#define _WEBSOCKET_ENDPOINT_
 
#include <string>
 
/*
Title: Web Socket Client
Author: kagula
Date: 2016-11-21
Dependencies: Websocket++、Boost::ASIO
Test Environment: VS2013 Update5, WebSocket++ 0.70, Boost 1.61
Description:
[1]Support connect a web socket server.
[2]If server is crash, client will not follow crash.
*/
 
namespace kagula
{
 class websocket_endpoint {
 public:
  websocket_endpoint();
  ~websocket_endpoint();
 
  int connect(std::string const & uri);
  void close();
 
  void send(std::string message);
  void show();
 };
}
 
#endif

websocket_endpoint.cpp文件清單

#include <websocketpp/config/asio_no_tls_client.hpp>
#include <websocketpp/client.hpp>
 
#include <websocketpp/common/thread.hpp>
#include <websocketpp/common/memory.hpp>
 
#include <cstdlib>
#include <iostream>
#include <map>
#include <string>
#include <sstream>
 
#include "websocket_endpoint.h"
 
typedef websocketpp::client<websocketpp::config::asio_client> ws_client;
 
namespace kagula
{
 
 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(ws_client *client, websocketpp::connection_hdl hdl) {
   m_status = "Open";
 
   ws_client::connection_ptr con = client->get_con_from_hdl(hdl);
   m_server = con->get_response_header("Server");
  }
 
  // if connection failed, the function will be invoke.
  void on_fail(ws_client *client, websocketpp::connection_hdl hdl) {
   m_status = "Failed";
 
   ws_client::connection_ptr con = client->get_con_from_hdl(hdl);
   m_server = con->get_response_header("Server");
   m_error_reason = con->get_ec().message();
  }
 
  void on_close(ws_client *client, websocketpp::connection_hdl hdl) {
   m_status = "Closed";
   ws_client::connection_ptr con = 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, ws_client::message_ptr msg) {
   if (msg->get_opcode() == websocketpp::frame::opcode::text) {
    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) {
  out << "> URI: " << data.m_uri << "\n"
   << "> Status: " << data.m_status << "\n"
   << "> Remote Server: " << (data.m_server.empty() ? "None Specified" : data.m_server) << "\n"
   << "> Error/close reason: " << (data.m_error_reason.empty() ? "N/A" : data.m_error_reason) << "\n";
  out << "> Messages Processed: (" << data.m_messages.size() << ") \n";
 
  std::vector<std::string>::const_iterator it;
  for (it = data.m_messages.begin(); it != data.m_messages.end(); ++it) {
   out << *it << "\n";
  }
 
  return out;
 }
 
 ws_client g_wsEndPoint;
 connection_metadata::ptr g_wsClientConnection;
 
 websocketpp::lib::shared_ptr<websocketpp::lib::thread> g_threadWS;
 
 websocket_endpoint::websocket_endpoint(){
   g_wsEndPoint.clear_access_channels(websocketpp::log::alevel::all);
   g_wsEndPoint.clear_error_channels(websocketpp::log::elevel::all);
 
   g_wsEndPoint.init_asio();
   g_wsEndPoint.start_perpetual();
 
   g_threadWS = websocketpp::lib::make_shared<websocketpp::lib::thread>(&ws_client::run, &g_wsEndPoint);
 }
 
 websocket_endpoint::~websocket_endpoint() {
  g_wsEndPoint.stop_perpetual();
  
  if (g_wsClientConnection->get_status() == "Open") {
   // Only close open connections
   websocketpp::lib::error_code ec;
   g_wsEndPoint.close(g_wsClientConnection->get_hdl(), websocketpp::close::status::going_away, "", ec);
   if (ec) {
    std::cout << "> Error closing ws connection " << g_wsClientConnection->get_uri() << " :" << ec.message() << std::endl;
   }
  }
 
  g_threadWS->join();
 }
 
 int websocket_endpoint::connect(std::string const & uri) {
  websocketpp::lib::error_code ec;
 
  ws_client::connection_ptr pConnection = g_wsEndPoint.get_connection(uri, ec);
 
  if (ec) {
   std::cout << "> Connect initialization error: " << ec.message() << std::endl;
   return -1;
  }
 
  g_wsClientConnection = websocketpp::lib::make_shared<connection_metadata>(pConnection->get_handle(), uri);
 
  pConnection->set_open_handler(websocketpp::lib::bind(
   &connection_metadata::on_open,
   g_wsClientConnection,
   &g_wsEndPoint,
   websocketpp::lib::placeholders::_1
   ));
  pConnection->set_fail_handler(websocketpp::lib::bind(
   &connection_metadata::on_fail,
   g_wsClientConnection,
   &g_wsEndPoint,
   websocketpp::lib::placeholders::_1
   ));
  pConnection->set_close_handler(websocketpp::lib::bind(
   &connection_metadata::on_close,
   g_wsClientConnection,
   &g_wsEndPoint,
   websocketpp::lib::placeholders::_1
   ));
  pConnection->set_message_handler(websocketpp::lib::bind(
   &connection_metadata::on_message,
   g_wsClientConnection,
   websocketpp::lib::placeholders::_1,
   websocketpp::lib::placeholders::_2
   ));
 
  g_wsEndPoint.connect(pConnection);
 
  return 0;
 }
 
 void close(websocketpp::close::status::value code, std::string reason) {
  websocketpp::lib::error_code ec;
 
  g_wsEndPoint.close(g_wsClientConnection->get_hdl(), code, reason, ec);
  if (ec) {
   std::cout << "> Error initiating close: " << ec.message() << std::endl;
  }
 }
 
 void websocket_endpoint::close()
 {
  if (g_wsClientConnection->get_status()=="Open")
  {
   int close_code = websocketpp::close::status::normal;
   kagula::close(close_code, "");
  }
 } 
 
 void websocket_endpoint::send(std::string message) {
  websocketpp::lib::error_code ec;
 
  g_wsEndPoint.send(g_wsClientConnection->get_hdl(), message, websocketpp::frame::opcode::text, ec);
  if (ec) {
   std::cout << "> Error sending message: " << ec.message() << std::endl;
   return;
  }
 
  g_wsClientConnection->record_sent_message(message);
 } 
 
 void websocket_endpoint::show()
 {
  std::cout << * g_wsClientConnection << std::endl;
 }
}

到此這篇關(guān)于C++編寫的WebSocket客戶端實現(xiàn)示例代碼的文章就介紹到這了,更多相關(guān)C++ WebSocket客戶端內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++實現(xiàn)修改函數(shù)代碼HOOK的封裝方法

    C++實現(xiàn)修改函數(shù)代碼HOOK的封裝方法

    這篇文章主要介紹了C++實現(xiàn)修改函數(shù)代碼HOOK的封裝方法,有助于深入了解C++的HOOK原理,需要的朋友可以參考下
    2014-10-10
  • C++遞歸刪除一個目錄實例

    C++遞歸刪除一個目錄實例

    這篇文章主要介紹了C++遞歸刪除一個目錄的實現(xiàn)方法,涉及到目錄的操作及遞歸算法的應(yīng)用,需要的朋友可以參考下
    2014-10-10
  • C++中字符串的查找與插入方式

    C++中字符串的查找與插入方式

    本文介紹了三種查找子字符串的方法,包括暴力匹配、使用函數(shù)和使用循環(huán),同時,介紹了三種插入內(nèi)容的方法,包括直接插入、使用substr截取和使用for循環(huán)逐個字符拼接,最后強調(diào)了這些方法僅為個人經(jīng)驗,希望能提供參考
    2026-04-04
  • C++利用LuaIntf調(diào)用Lua的方法示例

    C++利用LuaIntf調(diào)用Lua的方法示例

    這篇文章主要給大家介紹了關(guān)于C++利用LuaIntf調(diào)用Lua以及利用lua-intf來調(diào)用C++函數(shù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-11-11
  • C語言數(shù)組越界引發(fā)的死循環(huán)問題解決

    C語言數(shù)組越界引發(fā)的死循環(huán)問題解決

    本文主要介紹了C語言數(shù)組越界引發(fā)的死循環(huán)問題解決,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Qt控件之QDialog使用及技巧小結(jié)

    Qt控件之QDialog使用及技巧小結(jié)

    QDialog是Qt中的一個類,繼承自QWidget類,用于創(chuàng)建對話框窗口,可以顯示模態(tài)或非模態(tài)的對話框,本文就來介紹一下Qt控件之QDialog使用及技巧小結(jié),感興趣的可以了解一下
    2023-10-10
  • C++ template用法案例詳解

    C++ template用法案例詳解

    這篇文章主要介紹了C++ template用法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • QT實現(xiàn)五子棋游戲

    QT實現(xiàn)五子棋游戲

    這篇文章主要為大家詳細介紹了QT實現(xiàn)五子棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • C++ namespace案例詳解

    C++ namespace案例詳解

    這篇文章主要介紹了C++ namespace案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C/C++之字面量詳解(代碼中的固定值,用于表示各種數(shù)據(jù)類型的常量)

    C/C++之字面量詳解(代碼中的固定值,用于表示各種數(shù)據(jù)類型的常量)

    C++字面量是直接表示常量的固定值,涵蓋整型、浮點、字符、字符串、布爾、指針等類型,支持多進制、后綴及轉(zhuǎn)義,用戶定義字面量(C++11+)提供自定義解析方式,類型推導(dǎo)自動確定類型以避免隱式轉(zhuǎn)換和溢出問題
    2025-09-09

最新評論

柳江县| 林州市| 乌兰察布市| 色达县| 阳西县| 临夏县| 凯里市| 庄河市| 富源县| 长治县| 福州市| 右玉县| 舒城县| 明光市| 宁陵县| 景东| 独山县| 清流县| 敖汉旗| 福鼎市| 平江县| 资中县| 会泽县| 临夏市| 南安市| 南平市| 开化县| 双峰县| 沅陵县| 宣汉县| 五峰| 绩溪县| 霞浦县| 青阳县| 东平县| 都江堰市| 富裕县| 石城县| 鄂尔多斯市| 任丘市| 宁强县|