SX模块提供了Jabberd2的插件机制。在代码的关键部位为了扩展方便设置执行点,如果在此执行点上设置了“插件”,则按照注册插件的顺序执行这些注册的函数。
Jabberd2定义了一下结构体:
sx_env_t用于保存Jabberd2中所有的插件。使用sx_env_new分配一个sx_env_t结构体变量。
sx_plugin_t用来保存具体的插件信息,其中包含一些函数指针,这些函数会在设定的位置调用。
函数:sx_plugin_t sx_env_plugin(sx_env_t env, sx_plugin_init_t init, ...)
返回一个sx_plugin_t结构体,在 sx_env_plugin函数中会调用传入的init函数。 然后将动态分配sx_plugin_t变量加入到sx_env_t中。
一般情况下传入的init函数都是初始化sx_plugin_t结构体中的函数指针。
======
插件:
1,client ssl
2, router ssl
3, compression
4, stanza ack
5, user ip address
6, sasl
7, bind
/** things that can happen */
typedef enum {
event_WANT_READ, /* we want read actions */
event_WANT_WRITE, /* we want write actions */
event_READ, /* read some stuff for me */
event_WRITE, /* write this to the fd */
event_STREAM, /* stream is ready to go */
event_OPEN, /* normal operation */
event_PACKET, /* got a packet */
event_CLOSED, /* its over */
event_ERROR /* something's wrong */
} sx_event_t;
sx中定义的事件
sx_t sx_new(sx_env_t env, int tag, sx_callback_t cb, void *arg)
分配一个sx_t结构体
void sx_client_init(sx_t s, unsigned int flags, char *ns, char *to, char *from, char *version)
主动连接另一个服务器的时候,调用这个函数 。
在c2s中当连接到router后,调用sx_client_init函数。
在该函数中:
1, 调用插件中void (*client)(sx_t s, sx_plugin_t p)函数
2, 构造stream
3, 调用插件中void (*header)(sx_t s, sx_plugin_t p, sx_buf_t buf)函数
4, 将构造好的stream字符串加入到wbufq中,然后设置event_WANT_WRITE
int __sx_event(const char *file, int line, sx_t s, sx_event_t e, void *data)
参数中file, line是用来调试用的。
这里会调用传入sx_new函数的cb回调函数。
void sx_kill(sx_t s)
关闭socket
int sx_can_write(sx_t s)
mio中当事件action_WRITE被设置表明有数据需要发送,这时会调用这个函数。
在函数中会调用插件函数int (*wio)(sx_t s, sx_plugin_t p, sx_buf_t buf); 如果确实有数据要写,则设置事件event_WRITE。如果数据一次行全部发送完毕,调用sx_buffer_new设置的回调函数;如果只发送了部分数据,则需要重新设置发送标志,以及设置下一次发送剩余数据的起始位置和大小。
int sx_can_read(sx_t s)
mio中当事件action_READ被设置表明有数据需要读取,这时会调用这个函数。
调用回调函数读取数据,读到数据后,如果设置了rio插件,则将数据传入给插件处理,最后交由_sx_process_read处理读到的数据。
void _sx_process_read(sx_t s, sx_buf_t buf)
解析XML数据
解析成功后,做必要的错误检查。如果没有错误发生,设置event_PACKET标志,交由回调函数处理。
=======================================
c2s中重要的两个回调函数:
int c2s_router_sx_callback(sx_t s, sx_event_t e, void *data, void *arg)
调用sx_new函数时设置的回调函数
该回调函数实现了针对sx_event定义的事件
event_WANT_READ
设置mio读事件
event_WANT_WRITE
设置mio写事件
event_PACKET
读到一个XML Stanza后设置event_PACKET 事件,由回调函数继续处理。