最近工作比较轻松,有时间学习一些开源代码, 本系列文章主要分析网络服务器框架spserver, 采用的版本是最新的0.9.5(http://code.google.com/p/spserver/)。 在这个版本作者抛弃了libevent,而是自己实现了异步事件的机制。
一 主要的类和结构
SP_Handler 基于spserver实现网络服务的基类,包含start,handle等方法,用户可以通过覆盖这些方法,实现网络服务的真正逻辑。
SP_IOChannel 网络IO操作基类,包含receive,transmit等方法,用户可以通过覆盖这些方法,实现不同的IO操作,比如文件读写,SSL等。
SP_IocpServer 实现服务器的用户接口类,负责配置服务器的各项属性(例如:最大连接数, 连接超时等), 引用用户的业务服务类(SP_Handler)并引用底层IO类(SP_IOChannel),并提供runforever方法实现spserver运行。
SP_IocpEventCallback 定义了一系列回调函数,比如OnAccept(当发生accept事件时回调),eventloop(spserver主循环回调)等等
SP_IocpEventHelper 封装doClose,doStart,doError和doWork等成为SP_Task,利用线程池异步执行,这些被封装的函数会调用
SP_Handler中用户覆盖的方法,从而实现用户业务逻辑。
SP_MsgDecoder 把buffer内的数据(raw data)decode,例如接收数据后,decode判断接收到的数据是否拥有完整语义,如果完整就进行处理,如果不完整,就继续接收。
SP_Task 封装线程的函数名,传入参数等,线程池管理类读取SP_Task并运行
SP_ThreadPool 线程池类.
SP_Executor 线程池管理类,引用SP_ThreadPool,并实现线程池管理线程,当有任务(SP_Task)被加入后,该线程dispatch这个task到SP_ThreadPool。
SP_Request 封装client端的request,包含client端的ip,端口等等,同时也封装了SP_MsgDecoder。
SP_Response 封装server端回复client的reponse,所有的response被SP_Message封装。
二 从测试程序看spserver使用
在0.9.5代码中,作者提供了很多示例程序,下面以聊天室示例来快速了解spserver的使用方式。
首先,用户需要提供一个factory类用以创建SP_Handler类,这样spserver只需要调用factory的create方法便可以创建用户相应的SP_Handler类,保证了程序设计的低耦合。
其次,用户需要继承SP_Handler来实现自己的业务类,在这个示例内,作者的SP_ChatHandler类便是这样的一个类。
最后,用户需要按照各自服务器的性能和需求,设置spserver的具体参数,并调用runforever启动服务器。
SP_ChatHandler类中start方法用以当某个client连接到server上时调用,这里的示例会把该client的信息记录下来(任何连接都会被封装在一个session中,所有的session会被保存在hash table内,而这里仅仅是记录这个hash table的key),并发送欢迎信息,同时将这个client发送的信息,广播给所有clients(注意:这里的广播是基于应用层的,也就是把消息推给所有的clients并不是协议栈级别的广播)。
SP_ChatHandler类中handle方法是当decode成功(参见SP_MsgDecoder类说明)时调用的,同时将这个client发送的信息,广播给所有clients。
可以看到spserver使用是相当灵活的和简单的。
在本系列的第二章中,我将主要分析连接的建立。
(未完待续。。。)