[分享] yasio - 轻量级跨平台网络库 (支持jsb,jsb20,lua,unity3d)

概述

之前已经在社区分享过,早期库名称叫xxsocket,后来改mini-asio, 再后来到现在库名称为yasio, 得益于智能手机移动平台的崛起和cocos社区的生命力,时至今日该网络库已有8年以上历史,几乎和作者从业生涯一样长。否则早就废弃了。

目前,该库已经支持lua,jsb,jsb2.0以及unity3d的c#绑定,最新稳定分支为v3.31

主要变化

自v3.26以来,主要是在库稳定性,易用性的,诸如忽略SIGPIPE信号,组播支持,Transport抽象,UDP android切后台问题,文件传输事件优化,cmake travis ci持续集成保证全平台代码质量,C++接口脚本绑定,YASIO_NI接口优化等

核心设计理念

yasio的设计核心是信道(Channel)负责连接管理,由io_service提供的类似文件io的open和close接口来操作,传输器(Transport)负责实际数据收发,可以理解为文件打开后的句柄,由io_service的write接口写入数据,dispatch分派网络服务的输入事件(对端发来的数据)

另外io_service接口设计上还借鉴了著名的下载库curl,通过set_option设置一下选项,之后start_service,网络线程就可以正常工作了,之前旧版本是在start_service初始化信道,会导致关于信道YOPT_C_XXX的选项在启动服务之前设置不生效,为了更方便使用,新版本将信道初始化放到了io_service构造函数,这样所有选项都可以在启动服务前设置。不过为了保持代码兼容,C++保留了原来的接口参数并标记为deprecated,但在脚本绑定和接下来的v3.31版本已经移除。

v3.31.3已发布,相对于3.30主要新增如下支持

  • SSL/TLS支持
  • TCP自动拆包netty网络框架LengthBasedFrameDecoder的InitialBytesToStrip参数支持
  • c-ares集成

目录结构说明:

yasio/yasio:  核心源码  
yasio/tests/tcp: c++ tcp通讯案例
yasio/tests/kcp: c++ kcp传输速度测试案例
yasio/tests/mcast: 组播支持测试案例
yasio/tests/udp_echo_server: UDP回显服务器
yasio/examples/lua:  lua案例, tcp通讯,1个包拆分两次发送,验证框架拆包组包特性
yasio/examples/js: js案例,同lua案例一样
yasio/examples/ftp_server: 比较完整的TCP通讯案例,实现了标准ftp服务下载功能,可直接访问ftp://ftp.x-studio.net

编译个demo

确保安装vs2013以上或GCC4.9以上编译器, cmake最新版本后,执行如下命令:

git submodule --init --recursive
cd build
cmake .. && cmake --build . --config Debug

参考

yasio-releases下载链接: https://github.com/simdsoft/yasio/releases (updated)
该下载链接同时提供了creator v2.2.1的win版模拟器(需要已安装vs2019),creator测试工程inettester

yasio库被用于腾讯发行的手游“红警OL”: https://hjol.qq.com/

框架实现原理知乎文章: https://zhuanlan.zhihu.com/p/94633699

10赞

希望可以加一些小白教程,和tcp udp kcp之类的例子

帖子已更新,案例请参见主题内容

mask

mark

yasio-3.31.0发布

  1. 添加initialBytesToStrip参数设置支持, 使用选项YOPT_C_LFBFD_IBTS设置
  2. 添加ssl支持,使用YASIO_HAVE_SSL编译宏启用, 用信道码YCM_SSL_CLIENT打开ssl客户端,需要openssl支持,默认cocos2dx已包含openssl库.
  3. 集成 c-ares 异步域名解析库,使用YASIO_HAVE_CARES编译宏启用,确保已集成c-ares库,最新版c-ares有cmake文件,可以非常方便地编译各平台库
  4. 重构超时选项使用YOPT_S_CONNECT_TIMEOUT, YOPT_S_DNS_CACHE_TIMEOUT, YOPT_S_DNS_QUERIES_TIMEOUT替代YOPT_S_TIMEOUTS.
  5. 优化 schedule_timer 行为, 始终替换已有timer的回调
  6. 移除废弃的函数
  7. 移除unity3d tolua支持

特别说明,使用c-ares优缺点:
优点: 域名解析不需要开线程
缺点: 不支持自定义域名解析,例如集成httpdns等

yasio-3.31.1

如果启用c-aes异步域名解析库,则在android平台若无法获取系统dns地址,则使用8.8.8.8替代,确保c-ares能正常解析域名

yasio-3.31.2[stable]更新

  1. 优化单利类模板实现,详见: https://github.com/yasio/yasio/issues/200
  2. 修正配置宏拼写YASIO_VERBOS_LOG修正为YASIO_VERBOSE_LOG.
  3. 调用bsd socket API getaddrinfo解析域名时明确传入socktype, 默认值SOCK_STREAM, 避免在mac或linux返回多个相同IP地址 , 详见: https://github.com/yasio/yasio/issues/201
  4. 增强socket API包装类xxsocket的超时发送和接受API: send_n/recv_n实现, 详见: https://github.com/yasio/yasio/issues/202

yasio-3.31.3 [stable] 更新

  1. Optimize API io_service::write, add write raw buf support.
  2. Fix issue: https://github.com/yasio/yasio/issues/208
  3. Fix issue: https://github.com/yasio/yasio/issues/209

支持一下。

yasio-3.33.0正式发布:

  • 重构UDP Transport,和TCP一样使用发送队列,UDP客户端默认不使用connect绑定四元组,同时提供选项YOPT_T_CONNECT和YOPT_T_DISCONNECT来修改绑定行为
  • 增加io_service::write_to接口用户发送到指定地址,可作用于已绑定或未绑定的UDP Transport
  • 移除信道掩码 : YCM_MCAST_CLIENT, YCM_MCAST_SERVER
  • 移除信道标记: YCF_MCAST_LOOPBACK
  • 添加选项: YOPT_C_ENABLE_MCAST, YOPT_C_DISABLE_MCAST用于组播支持
  • 修改定时器回调原型为 []()->bool {},用户可以返回false来通知service继续调度定时器
  • 添加highp_timer::async_wait_once接口来注册一次性定时器回调
  • 修改 YCM_XXX_[CLIENT/SERVER]为YCK_XXX_[CLIENT/SERVER]以明确io_service::open时传递的应该是channle类型,而非掩码
  • 增加API: yasio::xhighp_clock获取纳秒级时间戳
  • 修复xxsocket API send_n和recv_n未处理EINTR信号问题
  • 调整obstream/obstream API, 默认write_v/read_v使用7Bit Encoded Int编码字符串的长度域
  • 重命名io_service的start_service/stop_service为start/stop
  • 修复开启c-ares非阻塞域名解析支持时超时行为
  • 增强c-ares清理机制
  • 增强cxx17::string_view兼容性,可用于c++11的unordered_map/unordered_set容器
  • 使用shared_ptr + shared_mutex来增强io_service在未开启c-ares情况下的析构行为的稳定性
  • 修复DNS缓存机制无效问题
  • 简化启用c-ares时dns服务器列表初始化,在android平台静态链接只需要在JNI_OnLoad调用yasio__jni_onload, 动态链接则无需任何操作
  • 修复yasio::_strfmt字符串格式化在某些低版本编译器,某些特殊字符输出情况下可能crash的问题
  • 增强io_service内部当检测到发送缓冲区已满时驱动行为,不再固定sleep,而是注册可写事件由select驱动
  • 优化UDP Transport内部对错误的关闭行为,默认不会因为发送错误而关闭Transport,而是由用户在发送回调中根据错误码自行决定是否关闭Transport.
  • 修改发送完成回调原型为 std::function<void(int ec, size_t bytes_transferred)>
  • 实现cxx17::string_view在c++11标准编译器下的字符串字面值操作符重载, 例如 “abcd”_sv;
  • 修复访问某些https服务器SSL握手失败问题
  • 修复在只支持c++11标准编译器下,使用kaguya lua绑定库,导致io_service对象不随着lua gc析构问题
  • 增加io_service::init_globals(const print_fn_t&)接口来支持重定向初始化日志到自定义文件(例如U3D和UE4游戏引擎的编辑器日志输出窗口)
  • 增强编译器支持,c++14,17,20均可通过编译
  • 优化Lua绑定库自动选择的最低标准,编译器支持c++14或以上,均选择 sol2 作为lua 绑定库
  • 在发送中断器socket_select_interrupter发生错误时,重建之
  • 更新kcp到v1.7版本,先前版本在ARM处理器下可能发生SIGBUS崩溃
  • 简化io_service API, 去除reopen, 使用open替代,open自带重连或重新打开信道行为
  • 修复当af=0时yasio::inet::ip::endpoint::ip崩溃问题
  • 修改io_service::write kcp的返回值,保持和其他类型Transport一致
  • 修复KCP server不解码KCP协议包问题
  • 增加xxsocket::disconnect以支持解除UDP socket和远端的4元组绑定关系
  • 重命名io_service选项 YOPT_I_SOCKOPT 为 YOPT_B_SOCKOPT
  • 其他代码质量和稳定性优化

V3.33.1发布

  1. 优化select interrupter代码
  2. 使用事件对象来设置和传递Transport的用户数据,确保使用者可以安全地管理用户数据生命周期
  3. 修复yasio::wcsfmt截断问题

Creator 2.3.4集成demo: https://github.com/yasio/inettester

yasio-3.33.2发布

  1. 修复使用c-ares时在ios平台获取不到系统dns问题
  2. 增加YOPT_S_DNS_DIRTY选项,启用c-ares时,当手机设备网络环境发生变化时,应当设置此选项
  3. 增强当内核发送缓冲区满时事件注册逻辑

核心源码有3M……
我看到kcp应该是非必要的。
那么还有啥是非必要的呀。
确实太大了。

建议支持模块裁剪

如果不需要脚本绑定,sol2, kaguy都是不需要的

GitHub最新master所有可选3方库已移动至external目录, 核心源码仅550K

2赞

yasio-3.33.2~3.34.0f3

  • 增加xxsocket::tcp_rtt用于获取tcp的rtt
  • 网络日志回调增加分级支持
  • 增加io_service设置kcp会话id选项: YOPT_C_KCP_CONV
  • 优化xxsocket::close行为,防止阻塞模式时在其他线程调用close导致recv线程卡主问题
  • 优化win32 udp server实现
  • 增加obstream和dotnet兼容整数压缩编码方式7 Bit Encoded Int64支持
  • lua绑定的demo cmake编译宏定义LUAI_USER_ALIGNMENT_T和llvm-clang保持一致
  • 支持集成到虚幻4的lua绑定方案sluaunreal和UnLua
1赞

yasio-3.35.0

  • 提供更加通用的字节序转换函数模板host_to_network和network_to_host,在yasio::endian命名空间下,可匹配全部数值类型
  • 采用convert_traits抽象二进制序列化工具类obstream, ibstream的字节序转换
  • 新增无字节序转换的快速二进制序列化类:fast_obstream, fast_ibstream
  • 修复io_service的reuse_address设置错误问题
  • 增加新选项: YOPT_S_DEFER_EVENT_CB
    a. 用户可以使用此选项设置事件预分派回调,在网络线程调度, 可以将数据包的解压缩和crc校验等操作此放到此回调,进一步为渲染线程让出CPU.
    b. 回调函数原型: typedef std::function<bool(event_ptr& event)> defer_event_cb;
    c. 回调返回true, io_service继续分派事件
    d. 回调返回false, io_service丢弃事件