首页 > 其他分享 >使用Boost.asio与Boost.beast基于协程连接ws

使用Boost.asio与Boost.beast基于协程连接ws

时间:2024-11-10 16:45:48浏览次数:1  
标签:asio 协程 io Boost ws context boost

目录

前言

本文主要介绍一个使用Boost.asio和Boost.beast基于协程连接Websocket(ws)的方法。其中C++版本为20,Boost版本为1.82。

准备工作

首先需要构造一个最基本的ws服务器用于测试。
本文使用nodejs构造了一个简单的ws服务器,基于ws库。

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', function connection(ws) {
  console.log('New client connected')
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
    ws.send(message);
  });
});

console.log('WebSocket server is running on port 8080');

实现

初始化io_context并监听信号

boost::asio::io_context io_context;
boost::asio::signal_set signals(io_context, SIGINT, SIGTERM);
signals.async_wait([&](auto, auto){ io_context.stop(); });

启动连接ws的线程并启动io_context

boost::asio::co_spawn(io_context, ws, boost::asio::detached);
io_context.run();

其中ws的签名为boost::asio::awaitable<void> ws()

建立tcp链接(以下步骤皆位于ws函数中)

这一步可以分为两个步骤,解析dns以及建立tcp链接。

auto executor = co_await boost::asio::this_coro::executor;
boost::asio::ip::tcp::socket socket(executor);
boost::asio::ip::tcp::resolver resolver(executor);

// 如果不使用dns解析,也可以直接使用以下直接代替
// boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 8080)
auto point = co_await resolver.async_resolve("localhost", "8080", boost::asio::use_awaitable);

co_await socket.async_connect(
  point->endpoint(), 
  boost::asio::use_awaitable);

ws握手

先使用boost::beast::websocket::stream<boost::asio::ip::tcp::socket&>包装,然后进行握手。

boost::beast::websocket::stream<boost::asio::ip::tcp::socket&> ws(socket);
co_await ws.async_handshake("127.0.0.1", "/", boost::asio::use_awaitable);

握手过程中发送的信息类似于

GET / HTTP/1.1
Host: www.example.com
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Key: 2pGeTR0DsE4dfZs2pH+8MA==
Sec-WebSocket-Version: 13
User-Agent: Boost.Beast/216

传输数据

boost::asio::steady_timer timer(executor);
for (;;) {
  co_await ws.async_write(boost::asio::buffer("hello"), boost::asio::use_awaitable);
  std::cout << "send: hello" << std::endl;
  
  boost::beast::flat_buffer buffer;
  co_await ws.async_read(buffer, boost::asio::use_awaitable);
  std::cout << boost::format("recv: %s") % std::string((char *)buffer.data().data(), buffer.data().size()) << std::endl;
  
  timer.expires_after(std::chrono::seconds(1));
  co_await timer.async_wait(boost::asio::use_awaitable);
}

效果

效果图

总结

有了协程之后,boost感觉好用多了

标签:asio,协程,io,Boost,ws,context,boost
From: https://www.cnblogs.com/ink19/p/18538084/boost_asio_coroutine

相关文章

  • GoLang协程Goroutiney原理与GMP模型详解
    本文原文地址:GoLang协程Goroutiney原理与GMP模型详解什么是goroutineGoroutine是Go语言中的一种轻量级线程,也成为协程,由Go运行时管理。它是Go语言并发编程的核心概念之一。Goroutine的设计使得在Go中实现并发编程变得非常简单和高效。以下是一些关于Goroutine的关键特性:轻量......
  • FootyForecast足球数据预测软件——XGBoost算法实战
    足球数据分析——XGBoost算法实战基于上数据分析的AI足球大模型预测平台,感兴趣的可以下载。足球预测专家推荐链接:http://lcsjfx.com/FootyForecast/DownLoad随着足球数据的日益丰富,数据分析在足球领域的应用也越来越广泛。其中,XGBoost算法作为一种高效、强大的机器......
  • 协程相关及asyncio使用
    上下文什么意思?参考博客https://blog.csdn.net/caizir913/article/details/108826764上下文是针对中断来体现其具体含义的在内核设计者的眼中,当一个任务在中断时,CPU会去执行中断对应的任务。中断结束后,再执行之前的task时,原有任务的相关数据(在处理原任务所需要的数据)需要保......
  • 《XGBoost算法的原理推导》12-1加法模型表达式 公式解析
    本文是将文章《XGBoost算法的原理推导》中的公式单独拿出来做一个详细的解析,便于初学者更好的理解。公式(12-1)是XGBoost的加法模型表达式,用于描述如何通过多个基模型的组合来进行预测。我们来逐步解析这个公式。公式(12-1)的形式......
  • 提高Boost电路的性能的优化策略
    优化Boost电路的性能,可以从多个方面入手,以下是一些关键的优化策略: 1.拓扑结构优化多级转换结构:采用多级转换结构可以扩展电压调节范围和提高效率。通过增加转换级数,可以更精细地控制输出电压,同时减少每级转换的电压差,从而降低开关损耗。集成化设计:将多个功能模块集成在一个......
  • asio
    asio基于操作系统提供的异步机制,不要求使用多线程和锁,采用前摄器proactor设计模式,实现了可移植的异步IO操作目前asio主要关注于网络通信方面,封装了socketAPI,提供了TCP、UDP、ICMP等网络通信协议,但asio的异步操作不局限于网络编程,还支持UNIX信号,定时器,串口读写,SSL(安装openssl)等......
  • AdaBoost与前向分步算法
    1.加性模型的定义在AdaBoost算法中,我们可以将其视为一种加性模型。加性模型是指由多个基模型的线性组合构成的模型。图中的公式(10-9)描述了加性模型的形式:f(......
  • 银行信贷风控专题:Python、R 语言机器学习数据挖掘应用实例合集:xgboost、决策树、随机
    全文链接:https://tecdat.cn/?p=38026原文出处:拓端数据部落公众号分析师:FanghuiShao 在当今金融领域,风险管控至关重要。无论是汽车贷款违约预测、银行挖掘潜在贷款客户,还是信贷风控模型的构建,以及基于决策树的银行信贷风险预警,都是金融机构面临的关键挑战。本银行信贷风控专题......
  • buck电路 & boost电路
    buck电路buck电路是直流的降压电路,我们下面给大家讲下,如何把12V的直流电压降压成5V的直流电压 1、buck电路拓扑:12V----->5V 2、降压原理 a、开关闭合,电流走向电源的正极---->开关---->电感----->(电容和负载)----->电源负极这里由于二极管是单相导通的,所以此时二极管......
  • 如何在Swoole中使用协程实现高并发的swoole_smtp函数
    ​使用Swoole的协程功能可以高效地处理大量的并发请求。本文详细介绍如何在Swoole中通过协程实现高并发的swoole_smtp函数。我们将依次探讨:1.什么是Swoole和协程;2.swoole_smtp函数的基础知识;3.协程如何增强swoole_smtp的并发性能;4.具体的实现步骤;5.实践中的注意事项。1.什么是S......