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~