jabberd2的mio和sx目录是灰常重要的两个目录,关系底层逻辑:
mio封装了一套多路io的实现,支持kqueue,epoll,poll,select,可以在configure的时候通过--enable-mio=指定。
sx目录的代码则在mio的上层实现了一条支持插件的逻辑通道,一些非核心xmpp协议都可以通过插件的形式加入,例如sx/compress.c可以实现流的压缩。
代码包装层次比较深,看起来比较绕,所以以c2s目录里的main.c为入口,画了一张c2s与router的第一次写读的流程,当然这里没有错误处理部分。基本上展现了jabberd2的io逻辑。
+--------------------------------------------------------------+
| main.c |
| 初始化mio和sx |
| 调用sx_client_init |
| 调用注册client初始化的插件 |
| 构造stream头 |
| 调用注册stream头处理的插件 |
| 将头追加到写缓存 |
+-+ 触发event_WANT_WRITE:_sx_event(s, event_WANT_WRITE, NULL); |
| | |
| | main loop(mio_run()) |
| | while true: |
+--|-+>if FD(m,fd)->type == type_NORMAL && MIO_CAN_READ(m,iter) |
| | | 触发:action_READ |
| | | 回调:c2s_router_mio_callback |
| | | 调用:sx_can_read |
| | | 触发:event_READ -------------------------+
| | | if 读入.length > 0 | |
| | | 调用注册io读的插件:_sx_chain_io_read(s, out); | |
| | | 调用:_sx_process_read(s, out); | |
| | | xml->nad | |
| | | 调用注册xml处理的插件 | |
| | | 触发:event_PACKET -| | |
| | +--------------------+-----------------------------------------+ |
| | | |
| | | |
| | | |
| | v |
| | +-----------------------------------------+ |
| | | event_PACKET | |
| | +-----------------------------------------+ |
| | | 回调:c2s_router_sx_callback | |
| | | 接收到的xml在这里已经被解成nad结构体 | |
| | | 正式逻辑开始 | |
| | +-----------------------------------------+ |
| | |
| | |
| | |
| | +--------------------------------+ +------------------------------+ |
| |> event_WANT_WRITE | +---> | event_WRITE | |
| +--------------------------------+ | +------------------------------+ |
| | 回调:c2s_router_sx_callback | | | 回调:c2s_router_sx_callbac | |
| | 调用:_mio_write | | | 调用:send()将数据送出 | |
| | 触发:action_WRITE | | +------------------------------+ |
| | 回调:c2s_router_mio_callback | | |
| | 调用:sx_can_write | | |
| | if 写缓存.length > 0 | | |
| | 触发:event_WRITE -----+ |
| | endif | |
| | 触发:event_WANT_READ -------+ |
| | | | |
| +--------------------------------+ | |
| | |
| +----------------------------------+ | +-------------------------------+ |
| | event_WANT_READ <+-+ | event_READ <+-------+
| +----------------------------------+ +-------------------------------+
| | 回调:c2s_router_sx_callback | | 回调:c2s_router_sx_callback |
| | 调用:_mio_read | | 调用:recv()将数据读入 |
+----+-调用:MIO_SET_READ(m, FD(m,fd)); | | |
| | | |
+----------------------------------+ +-------------------------------+
-----------
post by gmail~
很厉害的说, 最近在看这个东西, 搞的头晕.
[...] 下面是各个阶段在代码中的体现,主要从c2s的角度分析: 在这之前你必须首先理解jabberd2的io逻辑:http://bluehua.org/2010/11/28/1479.html(虽然老大表示文采太差,但是我觉得要是画图都不行,那我实在没辙了) [...]