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

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;
}

        

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 峟思大坝安全监测系统:科技筑牢工程稳定的基石
  • C++:模拟实现list
  • 国赛论文写作教学指南——模型的建立与求解
  • SprinBoot+Vue学生选课小程序的设计与实现
  • 全国设计院排名 工程总承包营业额二〇二三年排名
  • 线段树维护更多类型的信息
  • 数据爬虫工作中的IP清理频率
  • 代码随想录算法训练营第五十八天 | 图论part08
  • 24数学建模国赛准备!!!!(10——马氏链模型)
  • 【甲方安全建设】富文本编辑器XSS漏洞攻击及防御详析
  • Android APK打包脚本
  • JavaScript练习(二)
  • TCP数据包——报文头部组成
  • golang zap日志模块封装sentry
  • 【 html+css 绚丽Loading 】 000027 旋风破云扇
  • learning koa2.x
  • php面试题 汇集2
  • SOFAMosn配置模型
  • 聚簇索引和非聚簇索引
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 探索 JS 中的模块化
  • 应用生命周期终极 DevOps 工具包
  • 原生JS动态加载JS、CSS文件及代码脚本
  • 原生js练习题---第五课
  • 回归生活:清理微信公众号
  • 没有任何编程基础可以直接学习python语言吗?学会后能够做什么? ...
  • 通过调用文摘列表API获取文摘
  • 移动端高清、多屏适配方案
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • #565. 查找之大编号
  • #include到底该写在哪
  • $ git push -u origin master 推送到远程库出错
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (3)医疗图像处理:MRI磁共振成像-快速采集--(杨正汉)
  • (day18) leetcode 204.计数质数
  • (MTK)java文件添加简单接口并配置相应的SELinux avc 权限笔记2
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (poj1.3.2)1791(构造法模拟)
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (办公)springboot配置aop处理请求.
  • (二)正点原子I.MX6ULL u-boot移植
  • (学习日记)2024.01.09
  • (一)appium-desktop定位元素原理
  • (转)shell调试方法
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • (轉貼) UML中文FAQ (OO) (UML)
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .Net Core 微服务之Consul(二)-集群搭建
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .NET CORE使用Redis分布式锁续命(续期)问题
  • .net web项目 调用webService
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .NET和.COM和.CN域名区别
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • .net快速开发框架源码分享