websocketpp上手笔记-Windows安装

WebSocketpp是什么

最近手上有一个c++项目,需要用websocket从服务器端收内容。于是网上找了圈,发现WebSocketpp库可以做websocket的客户端。

WebSocketpp也叫WebSocket++,github地址是:https://github.com/zaphoyd/websocketpp,6.7k Stars。最新版本0.8.2.

话不多少,先把代码从github上拉下来。查看README,找到UserManual,进入Getting Started。文档中如此描述:

WebSocket++ is a header only library. You can start using it by including the websocketpp source directory in your project's include path and including the appropriate WebSocket++ headers in your program. You may also need to include and/or link to appropriate Boost/system libraries. 

WebSocket++ includes cmake and scons scripts for building the examples and unit tests.

WebSocket++是一个只需要头文件的库,直接包含在到工程中就可以使用了。但是呢,还需要Boost库。

WebSocket++包含了cmake脚本来编译examples和unit tests。

我的目标就是编译成功examples和unit tests。

 查看WebSocketpp的CMakeLists.txt

WebSocketpp支持cmake脚本呢编译examples和tests。于是先查看CMakeLists.txt。迅速看到了依赖内容Dependencies,里面明确提到了要依赖Boost库。由于我之前没有使用过boost库,所以得先安装boost库。

由于我的程序同事支持Windows和Linux,所以两个平台都要安装。

安装Boost

首先从官网https://www.boost.org/users/download/下载boost源码。我没有想太多,直接下载的最新版本1.84.0,直觉感觉WebSocketpp未必能支持这么新的版本。先硬着头皮试试,不行再换低版本。

进入到boost源码目录,打开vs2019的命令行,先执行:

bootstrap.bat

执行完成之后,会生成一个b2.exe的可执行文件。接着执行:

.\b2 variant=debug link=static threading=multi runtime-link=static

参数含义:

  • variant=debug   编译Debug
  • link=static   静态库
  • threading=multi支持多线程
  • runtime-link=static  静态连接

也就是我要编译一个使用MTD运行库的debug版本的静态库。没有指定编译目录,默认本文件夹。

编译完成之后输出:

The Boost C++ Libraries were successfully built!The following directory should be added to compiler include paths:E:\boost_1_84_0The following directory should be added to linker library paths:E:\boost_1_84_0\stage\lib

先试试debug版本能不能用,如果可以,后续再编译Release版本。

尝试WebSocket++能否连接Boost(Debug)

再次进入WebSocket++的CMakeLists.txt文件,找到加载Boost的部分:

    set (Boost_ADDITIONAL_VERSIONS "1.39.0" "1.40.0" "1.41.0" "1.42.0" "1.43.0" "1.44.0" "1.46.1") # todo: someone who knows better spesify these!find_package (Boost 1.39.0 COMPONENTS "${WEBSOCKETPP_BOOST_LIBS}")if (Boost_FOUND)# Boost is a project wide global dependency.include_directories (${Boost_INCLUDE_DIRS})link_directories (${Boost_LIBRARY_DIRS})# Pretty print statusmessage (STATUS "-- Include Directories")foreach (include_dir ${Boost_INCLUDE_DIRS})message (STATUS "       " ${include_dir})endforeach ()message (STATUS "-- Library Directories")foreach (library_dir ${Boost_LIBRARY_DIRS})message (STATUS "       " ${library_dir})endforeach ()message (STATUS "-- Libraries")foreach (boost_lib ${Boost_LIBRARIES})message (STATUS "       " ${boost_lib})endforeach ()message ("")else ()message (FATAL_ERROR "Failed to find required dependency: boost")endif ()

把Boost的版本号修改为:1.84.0

 set (Boost_ADDITIONAL_VERSIONS "1.84.0" "1.39.0" "1.40.0" "1.41.0" "1.42.0" "1.43.0" "1.44.0" "1.46.1") # todo: someone who knows better spesify these!find_package (Boost 1.84.0 COMPONENTS "${WEBSOCKETPP_BOOST_LIBS}")

开始生成,首先在WebSocket++根目录下创建一个build目录,进入build目录,执行:

cmake .. -DBUILD_EXAMPLES=TRUE -DBUILD_TESTS=TRUE  -DBOOST_ROOT=E:\boost_1_84_0 -DCMAKE_BUILD_TYPE=debug

执行失败,找不到Boost:

e:\websocketpp-master\build>cmake .. -DBUILD_EXAMPLES=TRUE -DBUILD_TESTS=TRUE  -DBOOST_ROOT=E:\boost_1_84_0 -DCMAKE_BUILD_TYPE=debug
-- Selecting Windows SDK version 10.0.19041.0 to target Windows 10.0.18362.
* Configuring Boost
-- -- Using BOOST_ROOT
--        E:\boost_1_84_0
CMake Warning at C:/Program Files/CMake/share/cmake-3.20/Modules/FindBoost.cmake:1354 (message):New Boost version may have incorrect or missing dependencies and importedtargets
Call Stack (most recent call first):C:/Program Files/CMake/share/cmake-3.20/Modules/FindBoost.cmake:1476 (_Boost_COMPONENT_DEPENDENCIES)C:/Program Files/CMake/share/cmake-3.20/Modules/FindBoost.cmake:2086 (_Boost_MISSING_DEPENDENCIES)CMakeLists.txt:218 (find_package)

从网上搜索错误信息“New Boost version may have incorrect or missing dependencies and imported targets”。原因是cmake版本比boost版本旧,如果想使用特定版本的boost,就得使用在该boost发布后发布的cmake版本。

详见:https://stackoverflow.com/questions/65560775/cmake-new-boost-version-may-have-incorrect-or-missing-dependencies-and-importe 我的cmake版本是3.20.3,查看FindBoost.cmake的1354行:

if(Boost_VERSION_STRING VERSION_GREATER_EQUAL 1.77.0 AND NOT Boost_NO_WARN_NEW_VERSIONS)message(WARNING "New Boost version may have incorrect or missing dependencies and imported targets")
endif()

可以看到该版本的cmake最多支持1.77.0的Boost。不打算安装新版本的cmake,我本来就怀疑WebSocket++不支持Boost1.84.0,趁此机会使用一个确定可用的版本。在github上的Issues上https://github.com/zaphoyd/websocketpp/issues/912,作者回复到:

0.8.2 has been tested through Boost 1.72

所以,也不折腾Boost版本了,下载Boost1.72,重新生成vs工程。这次生成工程成功。然后使用vs2019打开工程,分别编译examples里面的echo_client和echo_server,编译时把运行库改为MTD,与Boost库保持一致。编译成功。

同时启动echo_client和echo_server,也成功,可以运行。

TODO:这里有一个疑问,只指定了boost库的路径,并没有设置要链接哪些boost库,vs是怎么链接到正确的库呢?

SSL

首先,在编译examples的是没有链接openssl的,肯定不支持的。但是,我决定先从代码层面上支持SSL。在CMakeLists中,是使用find_package加载openssl的,但是我电脑上没有没有openssl的cmake module。不过我有已经编译好的open ssl 静态库。于是把静态库copy到WebSocketPP文件夹中。然后手动修改了一下CMakeList.txt:

	#原来是用find_package来设置openssl的,现在改成手动添加OpenSSL的路径#find_package(OpenSSL)   set(OPENSSL_SSL_LIBRARY "libssl.lib")set(OPENSSL_CRYPTO_LIBRARY "libcrypto.lib")set(OPENSSL_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/openssl/include")	#添加openssl路径link_directories(${PROJECT_SOURCE_DIR}/openssl/win64_static)#设置变量OpenSSL_FOUND,后续会根据该标志来创建TLS的工程set(OPENSSL_FOUND ON)

然后重新cmake生成工程,可以看到,生成了print_client_tls。编译成功。在运行之前,我先看了一下大致的逻辑。print_client_tls默认的连接地址是echo_server_tls的地址。echo_server_tls默认使用的一个自签署的证书,print_client_tls使用提前生成的pem文件来验证。

但是,我想用一个有效的网址,采用根证书验证。于是,我把地址改为了:wss://echo.websocket.org。验证部分的代码也要做相应的调整:

void add_windows_root_certs(context_ptr ctx)
{    HCERTSTORE hStore = CertOpenSystemStoreA(0, "ROOT");if (hStore == NULL) {return;}X509_STORE* store = X509_STORE_new();PCCERT_CONTEXT pContext = NULL;while ((pContext = CertEnumCertificatesInStore(hStore, pContext)) != NULL) {X509* x509 = d2i_X509(NULL,(const unsigned char**)&pContext->pbCertEncoded,pContext->cbCertEncoded);if (x509 != NULL) {X509_STORE_add_cert(store, x509);X509_free(x509);}}CertFreeCertificateContext(pContext);CertCloseStore(hStore, 0);SSL_CTX_set_cert_store(ctx->native_handle(), store);
}context_ptr on_tls_init(const char * hostname, websocketpp::connection_hdl) {context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::sslv23);try {ctx->set_options(boost::asio::ssl::context::default_workarounds |boost::asio::ssl::context::no_sslv2 |boost::asio::ssl::context::no_sslv3 |boost::asio::ssl::context::single_dh_use);ctx->set_verify_mode(boost::asio::ssl::verify_peer);//设置verify_none就不要验证服务端,也不需要加载证书//ctx->set_verify_mode(boost::asio::ssl::verify_none);//ctx->set_verify_callback(bind(&verify_certificate, hostname, ::_1, ::_2));ctx->set_verify_callback(bind(&verify_certificate, "hostname", ::_1, ::_2));#ifndef _WIN32//这个方法在windows上不起作用ctx->set_default_verify_paths();
#else//加载系统的根证书链add_windows_root_certs(ctx);
#endif// 这个方法可以显示添加某个pem证书文件//ctx->load_verify_file("");} catch (std::exception& e) {std::cout << e.what() << std::endl;}return ctx;
}

运行成功。

TODO:open ssl 静态库没有debug版本,使用MT运行库,为什么可以和使用MTD运行库的examples一起编译?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/786672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vuepress-theme-hope 添加谷歌统计代码

最近做了个网站,从 cloudflare 来看访问量,过去 30 天访问量竟然有 1.32k 给我整懵逼了,我寻思不应该呀,毕竟这个网站内容还在慢慢补充中,也没告诉别人,怎么就这么多访问?搜索了下, cloudflare 还会把爬虫的请求也就算进来,所以数据相对来说就不是很准确 想到了把 Google An…

【C/C++】C语言实现顺序表

C语言实现顺序表 简单描述代码运行结果 简单描述 用codeblocks编译通过 源码参考连接 https://gitee.com/IUuaena/data-structures-c.git 代码 common.h #ifndef COMMON_H_INCLUDED #define COMMON_H_INCLUDED#define LIST_INIT_CAPACITY 100 //!< 线性表初始化长度 #def…

每日三个JAVA经典面试题(三十二)

1.Mybatis映射文件中&#xff0c;如果A标签通过include引用了B标签的内容&#xff0c;请问&#xff0c;B标签能否定义在A标签的后面&#xff0c;还是说必须定义在A标签的前面&#xff1f; Mybatis的映射文件中&#xff0c;当一个标签&#xff08;如A标签&#xff09;通过<i…

spring boot admin服务端配置邮件通知、钉钉通知

根据下面的可选项配置邮件 表格 6. 邮件提醒配置的可选项 属性名说明面若防治 spring.boot.admin.notify.mail.enabled 开启邮件提醒 true spring.boot.admin.notify.mail.ignore-changes 要忽略的状态变化&#xff0c;使用逗号分割。格式是: "<from-status>:&l…

远控桌面多任务并发文件保密传输

远程桌面文件传输是一个重要的功能&#xff0c;大多数远控都是用的桌面程序模式&#xff0c;利用系统自带复制粘贴拖拽文件拷贝功能&#xff0c;做一个ole调用对接&#xff0c;可以将很多控制权交给操作系统。 但我做的是浏览器版&#xff0c;浏览器是沙盒原理&#xff0c;为了…

【2024系统架构设计】案例分析- 5 Web应用

目录 一 基础知识 二 真题 一 基础知识 1 Web应用技术分类 大型网站系统架构的演化:高性能、高可用、可维护、应变、安全。 从架构来看:MVC,MVP,MVVM,REST,Webservice,微服务。

Intel FPGA (6):dac tlv5618a

Intel FPGA (6)&#xff1a;dac tlv5618a 前提摘要 个人说明&#xff1a; 限于时间紧迫以及作者水平有限&#xff0c;本文错误、疏漏之处恐不在少数&#xff0c;恳请读者批评指正。意见请留言或者发送邮件至&#xff1a;“Email:noahpanzzzgmail.com”。本博客的工程文件均存放…

Cesium 批量种树

1、准备树种建模 分各种级别建模LOD1-LODN 其中meta.json长这样&#xff1a; Gltf再3Dmax中导出Obj,再通过ObjToGltf的工具转换&#xff0c;参考 https://editor.csdn.net/md/?articleId96484597 2、准备shp点数据。&#xff08;shp中的点位就是种树的位置&#xff09; 3、准…

简单的HTML

1.HTML介绍 HTML(HyperText Markup Language,超文本标记语言)是用于创建网页的标准标记语言。它使用一系列的元素来描述网页的结构和内容,包括文本、图像、链接、表格等。 1.1HTML基础结构 HTML文件是一种纯文本文件,由一系列的元素构成。每个元素由一对尖括号<>包围,…

R语言技能 | 不同数据类型的转换

原文链接&#xff1a;R语言技能 | 不同数据类型的转换 本期教程 写在前面 今天是4月份的第一天&#xff0c;再过2天后再一次迎来清明小假期。木鸡大家是否正常放假呢&#xff1f; 我们在使用R语言做数据分析时&#xff0c;会一直对数据进行不同类型的转换&#xff0c;有时候…

Pytorch实用教程: torch.tensor()的用法

在PyTorch中&#xff0c;torch.tensor()函数是用来创建张量&#xff08;Tensor&#xff09;的一个非常基础和重要的函数。张量是PyTorch中的基本数据结构&#xff0c;用于存储和操作数据&#xff0c;可以看作是一个高维数组。torch.tensor()函数可以从数据创建新的张量&#xf…

String Encryptor custom Bean not found with name ‘jasyptStringEncryptor‘...

项目采用 spring boot 2.6.13 jasypt-spring-boot-starter 3.0.5 apollo-client 1.6.0 自定义jasyptStringEncryptor&#xff0c;服务器上启动死活报找不到bean jasyptStringEncryptor&#xff0c;采用默认的&#xff0c;密文配置项自然解密失败导致服务无法启动。 经过一…

海康Ehome2.0与5.0设备接入EasyCVR视频汇聚平台时的配置区别

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

LeetCode热题Hot100 - 最长回文子串

一刷 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 思路&#xff1a; 返回最长回文子串&#xff0c;用maxl、maxr记录最长回文子串的起始和终点位置即可。 二维数组&#xff0c;dp[i][j]…

【AI+编程】AI工具(通义灵码)编写yaml转换properties工具类思考

需求背景&#xff1a;由于公司安装的apollo比较老&#xff0c;虽然新版本已经支持yaml格式了&#xff0c;但升级apollo代价比较大&#xff0c;有个项目配置文件之前放在项目里基于yaml编写的&#xff0c;最近想切换到apollo存储配置文件。 先百度了下&#xff0c;找了一个在线…

plasmo内容UI组件层级过高导致页面展示错乱

我使用plasmo写了一个行内样式的UI组件&#xff0c;但是放到页面上之后&#xff0c;会和下拉组件出现层级错乱&#xff0c;看了一下样式&#xff0c;吓我一跳&#xff1a;层级竟然设置的如此之高 所以就需要将层级设置低一点&#xff1a; #plasmo-shadow-container {z-index: …

使用node更加方便的操作mysql数据库的小工具

这是一个自己封装的小工具,能够更加方便的操作数据库 地址: 工具首页 git仓库地址 功能还在继续开发当中… 安装 npm install mysqinfo已经引入mysql工具包,无需在项目中再次引入mysql工具包 导入 const db require(mysqinfo)获取数据库对象 // db.dbconnect(mysql地址,mys…

HTTPS ECDHE 握手解析(计算机网络)

使用了 ECDHE&#xff0c;在 TLS 第四次握手前&#xff0c;客户端就已经发送了加密的 HTTP 数据&#xff0c;而对于 RSA 握手过程&#xff0c;必须要完成 TLS 四次握手&#xff0c;才能传输应用数据。 所以&#xff0c;ECDHE 相比 RSA 握手过程省去了一个消息往返的时间&#…

【计算机网络】select/poll

多路转接 - select/poll 一、I/O 多路转接之 select1. select 接口2. select 的使用3. select 的优缺点 二、I/O 多路转接之 poll1. poll 接口2. poll 的使用3. poll 与 select 的对比 一、I/O 多路转接之 select 多路转接属于 IO 复用方式的一种。系统提供 select() 函数来实…

Pinia的数据持久化

Pinia的数据持久化可以通过多种方式实现&#xff0c;例如使用vuex-persistedstate插件或专门为Pinia设计的插件如pinia-plugin-persist。下面我将通过一个简单的例子来说明如何使用Pinia及其数据持久化功能。 假设我们有一个简单的Vue 3应用程序&#xff0c;其中包含一个用户模…