目录

前言

本文主要介绍一个使用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感觉好用多了

使用Boost.asio与Boost.beast基于协程连接ws的更多相关文章

  1. Python实现基于协程的异步爬虫

    一.课程介绍 1. 课程来源 本课程核心部分来自<500 lines or less>项目,作者是来自 MongoDB 的工程师 A. Jesse Jiryu Davis 与 Python ...

  2. python基于协程的网络库gevent、eventlet

    python网络库也有了基于协程的实现,比较著名的是 gevent.eventlet 它两之间的关系可以参照 Comparing gevent to eventlet, 本文主要简单介绍一下event ...

  3. lua:写了个基于协程的task调度库

    写了一个(不完整的)基于协程的task调度库 sample code如下 my_spawn( function () print('f: 1') local t1 = my_spawn( functi ...

  4. Swoole 实战:MySQL 查询器的实现(协程连接池版)

    目录 需求分析 使用示例 模块设计 UML 类图 入口 事务 连接池 连接 查询器的组装 总结 需求分析 本篇我们将通过 Swoole 实现一个自带连接池的 MySQL 查询器: 支持通过链式调用构造 ...

  5. 发布一个基于协程和事件循环的c++网络库

    目录 介绍 使用 性能 实现 日志库 协程 协程调度 定时器 Hook RPC实现 项目地址:https://github.com/gatsbyd/melon 介绍 开发服务端程序的一个基本任务是处理 ...

  6. 基于协程的Python网络库gevent

    import gevent def test1(): print 12 gevent.sleep(0) print 34 def test2(): print 56 gevent.sleep(0) p ...

  7. 分析easyswoole3.0源码,协程连接池(五)

    连接池的含义,很多都知道,比如mysql的数据库连接是有限的,一开始连接mysql创建N个连接,放到一个容器里,每次有请求去容器中取出,取出用完再放回去. es3demo里,有mysql的连接池. E ...

  8. boost.asio与boost.log同时使用导致socket不能正常收发数据

    现象: 1. 没有使用boost.log前能正常收发数据 2.加入boost.log后async_connect没有回调 fix过程: 1. gdb调试发现程序block在pthread_timed_ ...

  9. Go基于协程的归并排序简单实现

    归并排序这个可能很多人都不知道,今天用Go语言简单的实现下,其他语言可能要基于线程来实现. //产生一个源 func ArraySource(a ...int) chan int{ out :=mak ...

  10. 基于ASIO的协程库orchid简介

    什么是orchid? orchid是一个构建于boost库基础上的C++库,类似于python下的gevent/eventlet,为用户提供基于协程的并发模型. 什么是协程: 协程,即协作式程序,其思 ...

随机推荐

  1. AvaloniaChat—从源码构建指南

    AvaloniaChat介绍 一个使用大型语言模型进行翻译的简单应用. 我自己的主要使用场景 在看英文文献的过程中,比较喜欢对照着翻译看,因此希望一边是英文一边是中文,虽然某些软件已经自带了翻译功能, ...

  2. 关于EF延时加载的面试题

    public async Task<ActionResult> GetData() { var data = (from leftdata in GetLeft() join rightd ...

  3. P7706 文文的摄影布置 题解

    P7706 文文的摄影布置 题解 原题 读完题,发现是线段树.单点修改+区间查询. 不过查询的值有些奇怪,就是了,我们考虑用线段树维护这个 ψ 值(下称待求值). 对于一个区间的待求值,大概有四种情况 ...

  4. 玄机蓝队靶场_应急响应_01:linux日志分析

    个人感觉这个靶场主要考验对linux的命令的基础掌握,对日志路径的基本了解. 一:解题 (1)ssh连接靶场,先用命令lsb_release -a看看是什么系统.然后发现是Debian GNU/Lin ...

  5. Java基础 韩顺平老师的 泛型 的部分笔记

    553,泛型引入 package com.hspedu.list_; import java.util.*; import java.util.concurrent.CompletionService ...

  6. Electron32-ViteOS桌面版os系统|vue3+electron+arco客户端OS管理模板

    基于electron32+vue3 setup+pinia2桌面端os管理解决方案ElectronVue3OS. vue3-electron32-os全新原创Electron32+Vite5+Vue3 ...

  7. Openharmony 跑 CV 应用

    最近有个项目,老同学让帮忙验证一个在ARM 板上跑 OpenHarmony,然后再集成一个CV算法上去,写这个文章主要是整理一下思路.如果有思路不对的地方,也烦请指出. 1. 个人做纯软件比较多,所以 ...

  8. MoCov1: 无监督视觉表征学习的动量对比《Momentum Contrast for Unsupervised Visual Representation Learning》(MoCo、动量对比、动态字典、队列维护、对比损失InfoNCE)

    现在是2024年6月11日,21:49,刚找好要看的论文,师兄推荐的. 先占个坑,明天看,我累了(我没脑子了). 现在是6月12日,15:49,干正事了(又被别人影响了情绪,这不好,希望你改掉,好的, ...

  9. UWP 通过 .NET 9 和Native AOT 的支持实现 UWP 应用的现代化

    微软(9 月 11 日)发布博文,微软正在预览对 .NET 9 的 UWP(通用 Windows 平台)支持,为现有 UWP 开发人员提供一条使用最新的 .NET 和本机 AOT 实现其应用程序现代化 ...

  10. SpringMVC —— 请求参数(传递json数据)

    接收请求中的json数据             注解       json格式(POJO)    json数组(POJO)    @RequestBody与@RequestParam区别