WebSocketPP常见问题解答与技术指南

WebSocketPP常见问题解答与技术指南

websocketpp C++ websocket client/server library websocketpp 项目地址: https://gitcode.com/gh_mirrors/we/websocketpp

概述

WebSocketPP是一个功能强大的C++ WebSocket库,为开发者提供了构建WebSocket客户端和服务器的完整工具集。本文将深入解析该库使用过程中的常见问题和技术要点,帮助开发者更好地理解和应用这个库。

核心使用问题

连接建立后修改或移除处理器

在WebSocketPP中,端点(Endpoint)上设置的处理器会被自动复制到该端点创建的所有连接中。修改端点上的处理器只会影响后续创建的连接。

对于已建立的特定连接,可以通过调用set_*_handler方法单独修改其处理器。修改后,该连接后续所有该类型事件都将使用新的处理器。

如果需要移除已设置的处理器,只需将处理器设置为nullptrNULL即可。

连接接受与拒绝机制

WebSocketPP提供了灵活的连接验证机制。validate处理器在完成初始握手但尚未响应时被调用,开发者可以在此检查连接请求、头信息、来源、子协议和远程端点IP等信息。

返回true接受连接,返回false拒绝连接。拒绝时还可以通过websocketpp::connection::set_status设置自定义HTTP错误状态码,以及使用websocketpp::connection::set_body()设置错误消息正文。

子协议协商机制

WebSocket连接可以协商使用特定的子协议。WebSocketPP服务器可以在validate处理器中通过websocketpp::connection::get_requested_subprotocols读取客户端请求的子协议列表(按客户端优先级排序),并通过websocketpp::connection::select_subprotocol选择其中一个子协议。

客户端在建立连接前可以通过websocketpp::connection::add_subprotocol添加子协议,添加顺序将被解释为优先级顺序。

连接建立后,可通过websocketpp::connection::get_subprotocol获取最终选择的子协议。

使用Asio传输时的优雅退出

使用Asio传输的客户端和服务器依赖于Asio的io_service处理异步网络操作。要实现优雅退出:

  1. 服务器调用websocketpp::transport::asio::endpoint::stop_listening关闭监听套接字
  2. 如果客户端启用了永久模式(start_perpetual),需调用stop_perpetual禁用
  3. 对所有活动连接调用close方法
  4. 等待异步操作完成

重要警告:避免直接使用io_service::stopendpoint::stop,这会中断所有操作,可能导致套接字处于不稳定状态。

连接句柄有效性检查

WebSocketPP提供了有限的连接句柄有效性检查机制:

  1. 尝试通过websocketpp::endpoint::get_con_from_hdl将句柄升级为完整连接指针
  2. 如果升级失败,则句柄肯定无效
  3. 如果升级成功,仍需通过实际发送操作(消息或ping)确认连接有效性

服务器重启时的"地址已使用"错误

操作系统通常防止程序监听其他程序创建的套接字。程序崩溃重启后,新实例被视为不同程序,必须等待超时才能重用原地址/端口。

解决方案:

  1. 实现干净的服务器关闭机制
  2. 考虑使用SO_REUSEADDR套接字选项(通过websocketpp::transport::asio::endpoint::set_reuse_addr设置)

注意:在共享资源环境中,不独占锁定监听套接字可能带来安全风险。

二进制消息处理

WebSocketPP支持RFC6455定义的两种消息格式:UTF-8文本和二进制。对于传入消息,使用websocketpp::message_buffer::message::get_opcode确定类型(websocketpp::frame::opcode::textwebsocketpp::frame::opcode::binary)。

发送消息时,可通过send方法的第二个参数指定类型。有两个主要重载版本:

  1. 接受std::string,默认为文本类型
  2. 接受void const*size_t长度,默认为二进制类型

依赖管理

无Boost环境使用

WebSocketPP仅在缺少C++11功能时使用Boost作为替代。如果使用C++11或更高标准的编译器和标准库,可以无需Boost。

对于iostream/raw传输,C++11标准库已足够。对于Asio传输,即使使用C++11构建系统,仍需要独立的Asio库(如果Boost Asio不可用)。

独立Asio使用

定义ASIO_STANDALONE后即可使用独立Asio。需要单独下载Asio头文件并确保其在构建系统的包含路径中。

无TLS/OpenSSL使用

使用iostream/raw传输时无需TLS功能。使用Asio传输时TLS功能是可选的,仅当需要加密连接时才需要OpenSSL。

是否使用TLS由配置模板参数决定。默认的websocketpp::config::asiowebsocketpp::config::asio_client配置不支持TLS,而websocketpp::config::asio_tlswebsocketpp::config::asio_tls_client支持。

OS X上的TLS构建问题

Mac OS X自带的OpenSSL版本较旧。要安全使用TLS,需要通过Homebrew或源码编译安装现代版OpenSSL。

MinGW兼容性

MinGW在C++11模式下目前不支持C++11 STL <thread>库。WebSocketPP需要线程/互斥库,选项包括Boost线程或mingw-std-threads

压缩功能

0.6.0-permessagedeflate和0.7.0版本的permessage-deflate使用

这些版本需要通过自定义配置使用permessage-deflate扩展。示例配置如下:

服务器配置示例

#include <websocketpp/extensions/permessage_deflate/enabled.hpp>

struct deflate_server_config : public websocketpp::config::asio {
    struct permessage_deflate_config {};
    
    typedef websocketpp::extensions::permessage_deflate::enabled
        <permessage_deflate_config> permessage_deflate_type;
};

typedef websocketpp::server<deflate_server_config> server_endpoint_type;

客户端配置示例

#include <websocketpp/extensions/permessage_deflate/enabled.hpp>

struct deflate_client_config : public websocketpp::config::asio_client {
    struct permessage_deflate_config {};
    
    typedef websocketpp::extensions::permessage_deflate::enabled
        <permessage_deflate_config> permessage_deflate_type;
};

typedef websocketpp::client<deflate_client_config> client_endpoint_type;

在这些版本中,压缩是自动协商的,默认情况下会压缩所有消息,但可以强制特定消息不压缩。

安全相关

恶意连接的快速终止

WebSocketPP会自动检测并终止违反WebSocket协议的连接。对于被认为恶意或严重损坏的连接,将省略关闭握手。

应用程序可以在协议层面之上检测恶意条件,并使用特殊关闭代码立即终止连接:

  1. websocketpp::close::status::omit_handshake:省略关闭握手,但干净地关闭TCP连接
  2. websocketpp::close::status::force_tcp_drop:强制丢弃TCP连接

注意:这些方法违反了WebSocket协议,可能对远程端点造成负面影响,应谨慎使用。

构建问题

与计时相关的编译错误

如果遇到与std::chronoboost::chronowaitable_timersteady_clock相关的编译错误,可能是构建系统混淆了boost::chronostd::chrono的使用。定义BOOST_ASIO_HAS_STD_CHRONO可能有助于解决此问题。

通过本文的详细解析,开发者可以更全面地理解WebSocketPP库的各种特性和使用场景,从而在实际项目中做出更合理的技术决策和实现。

websocketpp C++ websocket client/server library websocketpp 项目地址: https://gitcode.com/gh_mirrors/we/websocketpp

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邬楠满Seaman

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值