C/S框架 st_asio_wrapper 开发教程——宏(2019.10.17更新)

1.全局宏,服务端客户端均需要:

ST_ASIO_USE_STEADY_TIMER定时器采用boost::asio::steady_timer来实现。
ST_ASIO_USE_SYSTEM_TIMER定时器采用boost::asio::system_timer来实现,否则将采用boost::asio::deadline_timer来实现。

ST_ASIO_MAX_SEND_BUF

ST_ASIO_MAX_RECV_BUF

每个socket消息缓存最大字节数(接收和发送缓存共用,所以总的最大数为两倍),默认1M。注意这个缓存不会像ST_ASIO_MSG_BUFFER_SIZE一样预分配,而是用到多少分配多少。
ST_ASIO_ENHANCED_STABILITY增强的健壮性,如果开启这个宏,所有service对象都会在最外层(io_service::run)包一层try catch,以增加健壮性(当然,增加try  catch 是会有效率损失的),当捕捉到异常的时候,会回调on_exception虚函数,用户通过该函数的返回值来控制是否继续调用io_service::run。
ST_ASIO_PASSIVE_RECV 不主动接收消息,用户需要显示调用recv_msg来发起异步数据读取,如果你想在运行时替换解包器,必须定义该宏,且保证在调用recv_msg之前把解包器替换掉,否则会有race condition。
ST_ASIO_WANT_MSG_SEND_NOTIFY每次消息发送成功之后(成功送到本地SOCKET缓存),回调on_msg_send虚函数。
ST_ASIO_WANT_ALL_MSG_SEND_NOTIFY当发送缓存发空了之后,回调on_all_msg_send虚函数。
ST_ASIO_UNIFIED_OUT_BUF_NUM输出日志时用的缓存大小,注意是在栈上分配,注意栈溢出问题,如果你自定义了日志输出,该宏显然无意义。
ST_ASIO_NO_UNIFIED_OUT让st_asio_wrapper里面的所有输出失效。
ST_ASIO_CUSTOM_LOG自定义输出,此时你需要提供5个日志函数,函数名和签名参看unified_out类,且要么是静态的,要么是全局的。
ST_ASIO_FULL_STATISTIC详细的统计信息,包括时间消耗,如果不定义,所有时间消耗项都被不统计。统计的内容有请参看socket::statistic类的定义。
ST_ASIO_SERVICE_THREAD_NUMIO线程数量,用于运行io_service.run函数,所有回调函数(以on_开头的虚函数)都将会在这些线程中的某一个中被回调。
ST_ASIO_MAX_OBJECT_NUM对象池最多支持的对象数量,默认4096。
ST_ASIO_REUSE_OBJECT是否开启对象池,如果开启,当创建新对象时,将尝试使用已经被关闭的对象,此时将不会自动定时的释放被关闭的对象链表,请参看ST_ASIO_FREE_OBJECT_INTERVAL宏,默认不开启本宏。
ST_ASIO_FREE_OBJECT_INTERVAL说这个宏之前,要说一下object_pool的内部工作原理:当调用del_socket的时候(server_socket_base在on_recv_error里面的默认行为),object_pool的作法并不是删除这个对象,而是把这个对象移动到另外一个链表里面,这个链表里面的对象会被每ST_ASIO_FREE_OBJECT_INTERVAL秒遍历一次,以找到已经真正关闭了的对象(所谓真正关闭,就是已经被close了,而不仅仅是被shutdown了的对象,且没有任何未完成的异步调用),然后真正的从内存中释放它,原因是当del_socket的时候,可能还有其它的异步操作还没完成,或者完成了,但还在队列中没有被分发,如果此时从内存中释放对象,那么后面的异步回调的时候,可能会出现内存访问越界。如果未定义ST_ASIO_REUSE_OBJECT宏,ST_ASIO_FREE_OBJECT_INTERVAL宏会被自动定义(如果未显示定义的话)。单位为秒,默认10秒。
ST_ASIO_CLEAR_OBJECT_INTERVAL定时循环调用clear_obsoleted_object()以清除失效对象(移动到另外一个链表里面),如果在连接断开时你不方便调用del_socket,则对象池里面将会累积越来越多的失效对象(如果有连接出错,或者退出的话),你可以打开这个宏,让object_pool为你定时的做这些清除工作;注意,如果对象链表非常大,遍历链表是会影响效率的,如果你的连接是短连接,推荐开启这个功能(那你就不要再任何地方调用del_socket了),这样一次可清除多条连接,否则不推荐。单位为秒,该宏默认不开启。
ST_ASIO_DELAY_CLOSE关闭连接(shutdown)多少秒钟之后,可以安全释放对象或者重用对象(取决于ST_ASIO_REUSE_OBJECT是否被定义,定义了就是重用,否则释放)。如果定义为0,则st_asio_wrapper库将始终保证在没有任何异步调用之后才释放或者重用对象(会对效率造成一点点影响)。
ST_ASIO_GRACEFUL_SHUTDOWN_MAX_DURATION优雅关闭时,最长等待时间,单位为秒,默认5。
ST_ASIO_INPUT_QUEUE指定输入队列(send_msg用到的队列),目前有带锁和不带锁(线程不安全,所以需要你的业务保证线程的安全性)两种队列。
ST_ASIO_INPUT_CONTAINER指定输入队列所使用的容器,比如list、deque等,也可以是你自己的容器,只要提供必要的接口。
ST_ASIO_OUTPUT_QUEUE指定输出队列,目前有带锁和不带锁(线程不安全,所以需要你的业务保证线程的安全性)两种队列。
ST_ASIO_OUTPUT_CONTAINER指定输出队列所使用的容器,比如list、deque等,也可以是你自己的容器,只要提供必要的接口。
ST_ASIO_RECV_BUFFER_TYPE接收缓存的类型,比如它可以是boost::asio::mutable_buffers_1,或者std::vector<boost::asio::mutable_buffers_1>等,可以为所有asio支持的缓存类型。对于具体使用场合我举个例子,比如你正在使用ring buffer,那么一次你可能会提供两块非连续的缓存,那这个宏就能派上用场了。
ST_ASIO_HEARTBEAT_INTERVAL检测心跳包的频率,单位为秒,检测之前先检测连接有效性,如果心跳包超时,将断开连接(UDP不会)并回调on_heartbeat_error()函数,否则将发送一个心跳包。注意:如果从现在开始往前推ST_ASIO_HEARTBEAT_INTERVAL,在这个范围之内有消息被发送(接收的不算),则不会发送心跳包。
ST_ASIO_HEARTBEAT_MAX_ABSENCE如果判断心跳包超时,单位为次数,如果心跳包检测频度为5秒,这个值为3,则15秒后认为心跳包超时。
ST_ASIO_REUSE_SSL_STREAM让ssl支持重用和重连。如果ST_ASIO_REUSE_OBJECT被定义,而ST_ASIO_REUSE_SSL_STREAM没有,则编译任何ssl对象时,将报错。
ST_ASIO_AVOID_AUTO_STOP_SERVICE用asio::io_service::work (asio::executor_work_guard)包装io_service以绝对的防止service自动退出(除非是stop_service或者end_service)。
ST_ASIO_DECREASE_THREAD_AT_RUNTIME支持运行时增减service线程。
ST_ASIO_EXPOSE_SEND_INTERFACE暴露send_msg接口。


2.tcp客户端专用宏:

ST_ASIO_SERVER_IP服务器IP地址,用字符串形式表示,默认"127.0.0.1"
ST_ASIO_SERVER_PORT服务器端口,默认5050。
ST_ASIO_RECONNECT_INTERVAL当连接服务器失败时,延时多长时间重连,负数表示不重连,单位是毫秒,默认500毫秒。


3.tcp服务端专用宏:

ST_ASIO_SERVER_PORT服务器端口(服务器IP如果要设置的话,只能调用set_server_addr接口,不能通过宏来实现),默认5050。
ST_ASIO_TCP_DEFAULT_IP_VERSION在不指定服务端IP时,通过这个宏指定IP协议的版本(v4还是v6,取值分别是boost::asio::ip::tcp::v4()和boost::asio::ip::tcp::v6()),如果指定了IP,则版本从IP地址中分析得来。
ST_ASIO_ASYNC_ACCEPT_NUM最多同时投递多少个异步accept调用,默认1。
ST_ASIO_NOT_REUSE_ADDRESS关闭端口重用,udp也用使用此宏


4.udp客户端专用宏:

ST_ASIO_UDP_DEFAULT_IP_VERSION在不指定IP时,通过这个宏指定IP协议的版本(v4还是v6,取值分别是boost::asio::ip::udp::v4()和boost::asio::ip::udp::v6()),如果指定了IP,则版本从IP地址中分析得来。


5.打包解包器专用宏(不属于st_asio_wrapper库):

ST_ASIO_MSG_BUFFER_SIZE用于解包的缓存大小,默认4000。它应该大于等于最长的消息包(打包后),拿默认的packer来说,它最大仅支持3998消息长度,因为还有一个2字节的包头。对于默认打包解包器,这个值的范围只能是1至65536,因为包头只用了两个字节来表达长度,如果想要超过这个限制,可定义HUGE_MSG宏。这个缓存越大,那么一次可接收的消息越多(如果SOCKET的缓存里面有数据的话),但不是越大越好,因为每一个解包器里面都有一个大小固定为MSG_BUFFER_SIZE的缓存(不管你用到了多少),而每一个tcp::socket_base都会有一个解包器(udp::socket_base类似),所以这个值越大,占用的内存也就越大。当然,如果你自定义了打包解包器,那上面等于没说,怎么控制内存分配由你说了算。
ST_ASIO_DEFAULT_PACKER自定义打包器,它是一个类名,必须提供默认构造函数(即没有参数的构造函数)。
ST_ASIO_DEFAULT_UNPACKER自定义解包器,它是一个类名,必须提供默认构造函数(即没有参数的构造函数)。
ST_ASIO_HUGE_MSG开启大消息支持,默认关闭。注意,大消息会占用更多内存,请看asio_client这个demo,里面有演示用法(注释状态),以及对于占用更多内存的解释。
ST_ASIO_HEAD_TYPE消息头数据类型,不可设置,如果定义了ST_ASIO_HUGE_MSG,则为uint32_t,否则为uint16_t。
ST_ASIO_HEAD_N2H网络序转主机序,不可设置,如果定义了ST_ASIO_HUGE_MSG,则为ntohl,否则为ntohs。
ST_ASIO_HEAD_N2H主机序转网络序,不可设置,如果定义了ST_ASIO_HUGE_MSG,则为htonl,否则为htons。
ST_ASIO_SCATTERED_RECV_BUFFER在接收数据时是否支持scattered缓存(parse_msg之前用的缓存),如果你正在使用ring buffer,你可能会一次提供两块不连续的缓存,此时这个宏就有用了。


以上宏都可以按工程为单位来修改,你只需要在include相应st_asio_wrapper相关头文件之前定义这些宏即可(但推荐定义在工程属性里面,以完全杜绝不同的cpp文件拿到不同的宏定义的情况),具体例子demo里面都有。

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值