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(虽然老大表示文采太差,但是我觉得要是画图都不行,那我实在没辙了) [...]