skynet 初步分析

自己想实现一个tcp 粘包,残包的功能。  先看看一些开源的库是怎么实现的。

首先开启一个线程。使劲的执行: skynet_socket_poll
skynet_socket_poll  这个玩意是干嘛的呢?就是处理socket消息
工作流:
socket_message -> skynet_socket_message -> skynet_message -> skynet_context_push(message_queue)
通过源码追踪,发现数据都到message_queue了
 
 
既然有一个功能是:  把原始数据经过各种封装处理后流向message_queue了
猜测: 那么肯定有一个功能: 使劲的取message_queue,然后把原始数据加工成程序方便使用的对象
 
根据这个思路查找:
在skynet_start.c文件中, 很容易就找到了和队列相关的东西。 
就是thread_worker, 这个线程就是使劲的执行: skynet_context_message_dispatch
skynet_context_message_dispatch 这个玩意是干嘛的呢?
就是从全局队列拿出一个队列, 然后对这个队列使劲 skynet_mq_pop 并 dispatch_message
dispatch_message就是把  skynet_message 交给 skynet_cb 回调处理。
 
那么在这之前肯定有注册回调地方。
 

 

通过全局查找,找到了注册的地方。

有几个默认的处理skynet_message回调:

forward_cb 

mainloop

logger_cb

launch_cb

 

在lua-skynet.c中有一个没有圈出来, 这个调的到了_cb, 里面有一个lua_pcall,  这个其实已经调用到了lua的逻辑层。

此lua回调是通过 skynet.core.callback  注册的。
简单跟踪了一下: 最终都会到 skynet.dispatch_message
到lua层,应该不会用lua去处理粘包的问题吧。 
 
 
在service_gate.c文件中有一个_cb,这个回调的功能是,处理了三种原始数据
PTYPE_TEXT,
PTYPE_CLIENT,
PTYPE_SOCKET
 
PTYPE_SOCKET分支处理流程:
dispatch_socket_message  -> dispatch_message -> databuffer_push -> _forward(  
databuffer_read, 读取一个完整包
skynet_send,发送一个完整包
)
 
至此找到了skynet处理粘包和残包的地方。 文件在: databuffer.h。  
有点不明白云风为什么不写在 c文件里,而要写在头文件里。
 
 
话说回来,我怎么记得有人说粘包残包的逻辑在netpack文件, 我就问你真的看源码了吗,还是对分包残包有什么误解。
 
 
扫了一遍c代码,总体感觉还不错。性能应该不错。但是我怎么感觉可以更高效啊,层次更合理啊。
居然处理分包是在一个gate服务中。
gate只是一个名字吧,其实就是对三种数据类型处理的一个封装。  
总的来说,这个逻辑处理都在worker上面完成。  
 
发送数据都是在worker线程。
 
send ->  skynet_socket_sendbuffer -> socket_server_send
发送是没有队列的,直接走socket立即发送
 
有一个线程thread_socket, 只处理外部发过来的数据。  包括连接,断开等等
 
 至少得4核的CPU才能把skynet发挥到极致。
posted @ 2020-05-09 11:55  Please Call me 小强  阅读(451)  评论(0编辑  收藏  举报