当前位置: 首页 > article >正文

c++ websocket简单讲解

只做简单讲解。

一.定义和原理

        WebSocket 是从 HTML5 开始⽀持的⼀种⽹⻚端和服务端保持⻓连接的消息推送机制,传统的 web 程序都是属于 "⼀问⼀答" 的形式,即客⼾端给服务器发送了⼀个 HTTP 请求,服务器给客⼾端返回⼀个 HTTP 响应。这种情况下服务器是属于被动的⼀⽅,如果客⼾端不主动发起请求服务器就⽆法主动给客⼾端响应。

        WebSocket 更接近于 TCP 这种级别的通信⽅式,⼀旦连接建⽴完成客⼾端或者服务器都可以主动的向对⽅发送数据。WebSocket 协议本质上是⼀个基于 TCP 的协议。为了建⽴⼀个 WebSocket 连接,客⼾端浏览器⾸先 要向服务器发起⼀个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了⼀些附加头信息,通过 这个附加头信息完成握⼿过程并升级协议的过程。

        首先先经过TCP三次握手,然后再通过HTTP协议发送更新协议请求,最终切换为websocket协议进行通信。 

        WebSocketpp同时⽀持HTTP和Websocket两种⽹络协议。

二.搭建服务器简易流程

        由于库里的接口服务器过于复杂,需要的请查看⽤⼾⼿册: http://docs.websocketpp.org/。

重要的接口在下面用到讲解。

int main()
{   //1. 实例化server对象
    wsserver_t wssrv;
    //2. 设置日志等级
    wssrv.set_access_channels(websocketpp::log::alevel::none);
    //3. 初始化asio调度器
    wssrv.init_asio();
    wssrv.set_reuse_addr(true);
    //4. 设置回调函数
    wssrv.set_open_handler(std::bind(wsopen_callback, &wssrv, std::placeholders::_1));
    wssrv.set_http_handler(std::bind(http_callback, &wssrv, std::placeholders::_1));
    wssrv.set_message_handler(std::bind(wsmsg_callback, &wssrv, std::placeholders::_1, 
    wssrv.set_close_handler(std::bind(wsclose_callback, &wssrv, std::placeholders::_1));
   std::placeholders::_2));
    //5. 设置监听端口
    wssrv.listen(8085);
    
    //6. 开始获取新连接
    wssrv.start_accept();
    //7. 启动服务器
    wssrv.run();
    return 0;
}

四个回调函数分别为: websocket握⼿成功回调处理函数,http请求回调处理函数,websocket消息回调处理函数,websocket连接关闭回调处理函数。在对应的事件触发后自动调用。

三.简单服务器的搭建

        编写一个简单服务器,对浏览器的请求返回一个简单的http界面。代码如下:

#include <iostream>
#include <string>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>

typedef websocketpp::server<websocketpp::config::asio> wsserver_t;

void print(const std::string &str)
{
    std::cout << str << std::endl;
}

void http_callback(wsserver_t *srv, websocketpp::connection_hdl hdl) {
    //给客户端返回一个hello world的页面
    wsserver_t::connection_ptr conn = srv->get_con_from_hdl(hdl);
    std::cout << "body: " << conn->get_request_body() << std::endl; 
    websocketpp::http::parser::request req = conn->get_request();
    std::cout << "method: " << req.get_method() << std::endl;
    std::cout << "uri: " << req.get_uri() << std::endl;

    std::string body = "<html><body><h1>Hello World</h1></body></html>";
    conn->set_body(body);
    conn->append_header("Content-Type", "text/html");
    conn->set_status(websocketpp::http::status_code::ok);
   // wsserver_t::timer_ptr tp = srv->set_timer(5000, std::bind(print, "bitejiuyeke"));
   // tp->cancel();//定时任务的取消,会导致定时任务立即被执行
}
void wsopen_callback(wsserver_t *srv, websocketpp::connection_hdl hdl) {
    std::cout << "websocket握手成功!!\n";
}
void wsclose_callback(wsserver_t *srv, websocketpp::connection_hdl hdl) {
    std::cout << "websocket连接断开!!\n";
}
void wsmsg_callback(wsserver_t *srv, websocketpp::connection_hdl hdl, wsserver_t::message_ptr msg) {
    wsserver_t::connection_ptr conn = srv->get_con_from_hdl(hdl);
    std::cout << "wsmsg: " << msg->get_payload() << std::endl;
    std::string rsp = "client say: " + msg->get_payload();
    conn->send(rsp, websocketpp::frame::opcode::text);
}
int main()
{
    //1. 实例化server对象
    wsserver_t wssrv;
    //2. 设置日志等级
    wssrv.set_access_channels(websocketpp::log::alevel::none);
    //3. 初始化asio调度器
    wssrv.init_asio();
    wssrv.set_reuse_addr(true);
    //4. 设置回调函数
    wssrv.set_http_handler(std::bind(http_callback, &wssrv, std::placeholders::_1));
    wssrv.set_open_handler(std::bind(wsopen_callback, &wssrv, std::placeholders::_1));
    wssrv.set_close_handler(std::bind(wsclose_callback, &wssrv, std::placeholders::_1));
    wssrv.set_message_handler(std::bind(wsmsg_callback, &wssrv, std::placeholders::_1, std::placeholders::_2));
    //5. 设置监听端口
    wssrv.listen(8085);
    //6. 开始获取新连接
    wssrv.start_accept();
    //7. 启动服务器
    wssrv.run();
    return 0;
}

        


http://www.kler.cn/news/290163.html

相关文章:

  • 大势智慧携“实景三维+AI”信创产品体系亮相2024中国地理信息产业大会
  • 详解 HTTPS 与 TLS证书链校验
  • 避坑之:深信服AC跨三层取MAC(核心交换机是锐捷S7808C_RGOS 11.0(4)B2P1)
  • 实验室ICPR 2024论文分享┆DS MYOLO:一种基于状态空间模型的驾驶场景可靠目标检测器
  • Edge资源占用优化:调整浏览器设置与关闭自动更新检查
  • 工业主板在轨道交通中的应用特点
  • 【网络】P2P打洞原理
  • 专项练习-数据思维-49题
  • PostgreSQL技术内幕4:PostgreSQL存储引擎内存管理
  • 使用udp进行通信
  • 视频结构化从入门到精通——行为分析类应用
  • IEEE PDF eXpress 报错解决 Error in converting file + font not embedded
  • 海康二次开发学习笔记9-通讯触发及模块列表获取
  • LLM手撕
  • JS笔记
  • js逆向——RSA实战案例讲解
  • UART串口通信——FPGA学习笔记9
  • tekton什么情况下在Dockerfile中需要用copy
  • anaconda创建虚拟环境
  • 机器学习数学公式推导之高斯分布
  • 雨情教务排课系统
  • 数字化转型升级探索(二)
  • Java | Leetcode Java题解之第387题字符串中的第一个唯一字符
  • 计算机网络 数据链路层2
  • 网络编程学习:TCP/IP协议
  • 【安全科普】学完网络安全出去能做什么工作?
  • 【ES实战】Elasticsearch中Task的简单管理说明
  • css加载一张图片 设置整个页面背景
  • 淘宝扭蛋机小程序开发,吸引更多的消费者
  • 【嵌入式学习笔记】---- STM32里的DMA