Nginx拥有大名鼎鼎的事件模型,在初始化介绍后循环调用ngx_process_events_and_timers(cycle),来处理各种事件。并且其高效的时间模块,能很方便地控制各event的超时等。
这样的一套机制,不仅适用于http,mail等应用,甚至我们可以不管nginx里的网络功能,利用这套event机制,开发一个本地的小应用。这样做很好玩,也可以更好的学习nginx的事件、时间模型。
这里以一个简单的游戏服务器为例。
首先看一下nginx作为服务器,其网络功能的实现情况。Init_cycle()
Parse_conf(); //解析配置文件,找到所有的listen ip:port
Listen_fd = listen() //打开所有的监听
Listen_fd 分配一个connection结构
R/W事件则依附于connection结构,listen_fd的R->handler = ngx_event_accept()
这些构建过程可详细参考http、listen等指令的set()函数。这些listen_connection就是所有事件的起源,接受连接后,ngx_event_accept()会得到con_fd,并分配给它一个connection结构,并初始化之。ngx_event_accept()的最后会调用listen->handler,以确保用于不同功能的con_fd得到各自相应的初始化。
其中最重要的就是设置con_fd的R/W->handler,如http功能的R->handler= ngx_http_init_request()。当该con_fd接收到数据时,就会初始化http流程。
/* nginx.conf */
……
Event {
……
}
http {
……
}
Tplay {
Server {
Listen ip:port;
Game exnumber;
……
}
Server {
Listem *:port;
Game rld;
……
}
}
其中tplay,listen的set()函数,参考http的来写就行了,最后tplay_listen->handler()作为tplay_connect_fd的最后初始化,可以根据需要来写。
比如以这里的exnumber游戏为例(就是猜数,每次server返回偏大或偏小,直到猜对):最终设置con_fd的R->handler()为ngx_tplay_exnumber_judge(),来判断所猜数字偏大还是偏小,并且可以为R->ev->timer设置超时值,提高游戏的挑战性。