ascs 简明开发教程(十六):如何运行时替换解包器

31 篇文章 0 订阅
31 篇文章 1 订阅

QQ交流群:198941541

ascs需要的解包器其实是一个i_unpacker<typename Unpacker::msg_type>对象指针,但构造client_socket_base和server_socket_base时,为什么需要具体的打包解包器类呢(或者通过宏ASCS_DEFAULT_PACKER和ASCS_DEFAULT_UNPACKER定义)?这是因为ascs无法创建i_unpacker对象,它是抽象的。所以假设你有两个解包器unpacker1和unpacker2,只要它们继承自相同的 template<typename MsgType> class i_unpacker,就可以运行时相互替换,替换函数如下(注意必须定义宏ASCS_PASSIVE_RECV接口才可见):

#ifdef ASCS_PASSIVE_RECV
void unpacker(const std::shared_ptr<i_unpacker<typename Unpacker::msg_type>>& _unpacker_)
#endif

因为ascs对数据的接收默认情况下是自动的,所以你不能随时想换解包器就替换,替换了解包器之后,其提供的缓存可能就不再合法,如果ascs还在读取数据,那写缓存的时候就将访问到非法地址,为此ascs引入了宏ASCS_PASSIVE_RECV,定义之后,ascs不再自动读取数据(除了连接建立起来之后的第一次读取),需要你来显示地调用recv_msg(这个函数在定义了宏ASCS_PASSIVE_RECV之后,也会变得可见以供你调用),那么你在什么地方调用recv_msg呢,答案是在派发消息的回调里面(同步读、on_msg或者on_msg_handle),也只有在派发消息的回调里面,你才可以替换解包器(且必须在recv_msg之前),并且还要注意如下几点:

1 派发消息有四个地方——同步读、on_msg、on_msg_handle(批量) 和 on_msg_handle(单消息),我推荐只用某种派发方式,那替换解包器也应该在同一个地方,如果你用了多种派发,多个地方替换解包器,那替换解包器的工作将会变得异常复杂且容易出错(消息派发支持多种同时进行,只要你能忍受消息乱序,前面教程说过了)。

2 当同步读或者on_msg派发时,可以替换解包器且理论上无需定义宏ASCS_PASSIVE_RECV(也就无需显示地调用recv_msg),但为了统一也为了强调替换解包器的危险性,ascs仍然要求定义宏ASCS_PASSIVE_RECV(也意味着需要显示调用recv_msg)。

3 一定要在处理完消息之后才替换解包器并调用recv_msg,recv_msg在最后调用。具体来讲,当同步读、on_msg派发或者on_msg_handle批量派发时,处理完消息之后,在最后替换解包器并调用recv_msg。如果消息未处理完,那么同步读时消息会被丢弃(此时相当于处理完了,所以仍然可以替换解包器并调用recv_msg);on_msg派发时,剩余的消息会继续异步派发,这种情况下我不推荐替换解包器(前面说了,情况异常复杂);on_msg_handle批量派发时,剩余的消息会继续异步派发,此时不能替换解包器并调用recv_msg,直到你处理完了消息(下次派发也是通过on_msg_handle批量派发)。on_msg_handle单消息派发时,当前是不是最后一个消息,需要通过get_pending_recv_msg_size接口判断,如果它返回0,就是最后一条消息,然后你又处理了这条消息的话,就可以替换解包器并调用recv_msg了。

4 当定义了宏ASCS_PASSIVE_RECV之后,如果解包器返回0个消息(比如只解了个心跳包,然后解包器过滤掉了没有通过parse_msg返回),那就不会派发消息了,岂不是没有机会替换解包器并调用recv_msg了?答案是否定的,当宏ASCS_PASSIVE_RECV被定义之后,如果解包器返回0个消息,ascs会自动补一个空消息,所以后面的流程仍然会走到消息派发上去的,这也意味着你的消息处理要注意过滤掉空消息的情况,这个空消息是给你机会替换解包器并调用recv_msg的。

5 当定义了宏ASCS_PASSIVE_RECV之后,如果没有替换解包器,仍然需要调用recv_msg,调用条件与上面第3点完全一样。

上一篇:ascs 简明开发教程(15) 下一篇:ascs 简明开发教程(17)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值