起先的话,是先安装下citadel套件,进行体验下其是怎么样的一个工作及如何应用。这样对于后来的学习会比较有个感觉吧。因为可能会在其功能上做二次开发或可能学习其框架而自己实现一套。总之,还是要阅读其代码,学习其工作的一些流程等。本文的话,将说的是citadel提供的事件列表,事件优先级,及钩子函数的注册等一些与函数钩子及事件相关的内容。代码目前看得还不够深,只是很初级的笔记吧(现在阅读的版本是citadel 8.24版本的代码,所以如果版本不一样的话,会有所出入)。
事件
citadel的事件是使用宏定义来实现的,具体为什么使用宏定义,citadel团队也给出了答案:
Event types can’t be enum’ed, because they must remain consistent between builds (to allow for binary modules built somewhere else)
事件列表
事件 | 数值 | 说明 |
---|---|---|
EVT_STOP | 0 | 会话终止,使用CtdlRegisterSessionHook进行钩子注册 |
EVT_START | 1 | 会话开始,使用CtdlRegisterSessionHook进行钩子注册 |
EVT_LOGIN | 2 | 用户登陆,使用CtdlRegisterSessionHook进行钩子注册 |
EVT_NEWROOM | 3 | Changing rooms,应该是改变房间,但字面意思又为创建新的房间。使用CtdlRegisterRoomHook进行钩子注册 |
EVT_LOGOUT | 4 | 用户退出,使用CtdlRegisterSessionHook进行钩子注册 |
EVT_SETPASS | 5 | 设置或修改密码,使用CtdlRegisterSessionHook进行钩子注册 |
EVT_CMD | 6 | Called after each server command,每次服务端命令后调用,使用CtdlRegisterSessionHook进行钩子注册 |
EVT_RWHO | 7 | An RWHO command is being executed,RWHO命令正在被执行,display who’s online,也就是用于显示在线用户的时候,会被调用,使用CtdlRegisterSessionHook进行钩子注册 |
EVT_ASYNC | 8 | Doing asynchronous messages,执行异步消息,使用CtdlRegisterSessionHook进行钩子注册 |
EVT_STEALTH | 9 | Entering stealth mode,进入隐蔽模式,使用CtdlRegisterSessionHook进行钩子注册 |
EVT_UNSTEALTH | 10 | 退出隐蔽模式,使用CtdlRegisterSessionHook进行钩子注册 |
EVT_TIMER | 50 | Timer events are called once per minute and are not tied to any session,定时器事件,每分钟调用一次,并不属于任何一个会话,使用CtdlRegisterSessionHook进行钩子注册 |
EVT_HOUSE | 51 | as needed housekeeping stuff,需要管家?实验得知,如果注册该事件的钩子,基本上每秒会打印一次,使用CtdlRegisterSessionHook进行钩子注册 |
EVT_SHUTDOWN | 52 | 服务器关机,使用CtdlRegisterSessionHook进行钩子注册 |
EVT_PURGEUSER | 100 | 删除一个用户,使用CtdlRegisterUserHook进行钩子注册 |
EVT_NEWUSER | 102 | 创建一个用户,使用CtdlRegisterUserHook进行钩子注册 |
EVT_BEFOREREAD | 200 | 没有注释,使用CtdlRegisterMessageHook进行钩子注册 |
EVT_BEFORESAVE | 201 | 没有注释,使用CtdlRegisterMessageHook进行钩子注册 |
EVT_AFTERSAVE | 202 | 没有注释,使用CtdlRegisterMessageHook进行钩子注册 |
EVT_SMTPSCAN | 203 | called before submitting a msg from SMTP,在提交从SMTP获得的信息前调用,使用CtdlRegisterMessageHook进行钩子注册 |
基本上每个事件都有其对应的优先级,从代码上看,优先级是允许执行优先级的加法操作。也就是在同个优先级下,还可以允许用户对优先级做加法操作来细化同个级别的优先级。
优先级
优先级列表
优先级 | 数值 | 说明 |
---|---|---|
PRIO_QUEUE | 500 | 无注释,字面意思应该是队列的优先级 |
PRIO_AGGR | 1000 | 无注释, |
PRIO_SEND | 1500 | 无注释,字面意思应该是发送的优先级 |
PRIO_CLEANUP | 2000 | 无注释,字面意思应该是cleanup的优先级 |
PRIO_HOUSE | 3000 | 事件EVT_HOUSE的优先级 |
PRIO_CREATE | 10000 | 注释上面应该是写错的,并且搜索下去,并没有被调用,因此不是很清楚具体是哪个事件的优先级,字面理解的话,应该为创建的优先级,可能是通用性的创建吧,不特定指某个事件。 |
PRIO_LOGOUT | 15000 | EVT_LOGOUT的优先级 |
PRIO_LOGIN | 20000 | EVT_LOGIN优先级 |
PRIO_START | 25000 | EVT_START优先级 |
PRIO_STOP | 30000 | EVT_STOP优先级 |
PRIO_ASYNC | 35000 | EVT_ASYNC优先级 |
PRIO_SHUTDOWN | 40000 | EVT_SHUTDOWN优先级 |
PRIO_UNSTEALTH | 45000 | EVT_UNSTEALTH优先级 |
PRIO_STEALTH | 50000 | EVT_STEALTH优先级 |
钩子函数同个优先级的话,从实验上来看,是依据后来居上的原则,也就是如果同个事件,在同个优先级上,后面注册的,会先被回调。然后在执行前面注册的回调。
钩子函数,都在源码serv_extensions.c中实现,有大量的钩子,基本上每个钩子都有其对应的CtdlRegisterXXXHook操作,CtdlDestroyXXXHooks操作及,CtdlUnregisterXXXHook操作,PerformXXXHooks操作,其中PerformXXXHooks就是钩子最终被调用的函数。部分钩子可能不需要那么完善的功能,所以部分操作会有所缺失。
比较重要的钩子函数有以下一些:
- ServiceHooks:该钩子是用于注册对于文件描述符的监听,比如XMPP,SMTP都需要对指定的一些端口进行监听,所以注册的时候,可以设置监听指定的端口号或Unix domain socket的路径。
- SessionHooks:会话的钩子,citadel的框架就是基于会话操作的,所以这个也是重中之重,基本上大部分的事件,都围绕着会话来实现。
- UserHooks:起先,我还以为是用户自定义钩子,后来细看了,原来是用户管理钩子,这个系列的钩子,就是修改/删除/添加用户的一些操作,比如修改密码什么的,就会执行该钩子函数。
- RoomHooks:citadel本质是实现聊天室的功能,所以这个钩子也就不得不说了,也就是聊天室的一些操作了,会执行该钩子的回调。
还有其他的一些钩子,由于我这边只是为了实现XMPP的一些功能,并没有深入的去看,目前就只是看了一些部分代码。做一些笔记,及整理吧。
转载请注明: 转载自elkPi.com
本文链接地址: citadel学习笔记2——事件、优先级、钩子函数