我把
在实现过程中session被做成了一个SyncDriver, 可以给actor发信但是没有回调机制, 当session发出一个message后它需要调用Wait()等待actor通知它已经收到这个消息(通过actor回发一个MPK_OK)。由于session工作在ASIO的事件循环中, 所有的session都被这一个thread来驱动, 所以如果每次发出一个messge到actor都需要进行一次等待, 通讯thread的效率必然很差。我们需要communication thread不断读取网络层消息并转发给对应actor,并且不需要等待actor的回复。
我目前的想法是在session中注册一个actor的静态成员函数, 既然是static member function那么就可以保证不接触到actor的内部status, 仅仅每次收到一个package header时候这个static memeber function决定继续读取多少字节的package body。zero or non-zero, 等到读取成功后再一次性打包成一个message发给对应的actor。
这个package包含了1. package header, 2. package body。header是固定的1byte, body是变长buffer,这个buffer通过全局memory pool进行分配。当actor收到这个message后(MPK_NET), 处理对应的package然后释放掉package body。由于申请body buffer在ASIO时间循环thread中, 释放body buffer在actor message thread中, 所以需要设置memory pool为多线程enabled模式。
这里有个一假设, 网络层传入的package的header和body长度不依赖于actor当前状态。因为注册到session中的package header回调是static的, 无法获取actor的状态, 并且actor model也不允许session直接获取actor的internal status。这个假设是合理的。目前的逻辑如下:
1. actor拥有session的pointer, 并且在actor的生命周期内session保证valid。
2. 初始化后session先和monoserver交互, 等成功登陆后monoserver创建player(actor), 然后把session指针传给player, 把player地址传给session。
3. session收到header后通过player注册的static memeber function决定如何接受network data stream并打包成一个package, 这个过程中如果需要buffer就通过global memory pool申请。
4. session发送这个package(header, body pointer)到player, 然后接受下一个header。。。
5. player收到这个message, 处理, 释放body pointer回global memory pool。
整个过程中session没有等待actor回复, actor收到的总是一个完整的package。
网友评论