我们准备实现一个简单的http服务器。它具备有接收客户端请求,并通过读取相应的数据进行协议分析,最后返回相应的数据的能力。
从根本上来说,http服务器也就是一个网络服务器,nio框架netty也有一个参考的http协议实现。本参考实现不使用第三方网络包,仅通过javaSE来完成一个http协议实现,以用于在读取http协议时有一个更清晰的认识。
本实现的细节在一定程度上参考了netty,tomcat等现有的实现,但这里详细地把相应的理论细节解释清楚。
本篇为第1节,即通过构建一个nio服务端来作基本的网络处理。
在nio中,服务端建立起相应的serverSocket,并向selector注册相应的事件。当事件发生时去做相应的事情即可,在这个过程中数据的传输和代码实现是异步的,即在有数据的情况下才能做相应的事情,但数据和操作之间并不同步,即不能一次性地把所有的数据都读取完毕,或者不能一次性地把所有的数据都返回给客户端。所以,在整个实现中,需要在事件处理中不断地监听相应的事件,并通过在处理数据和事件切换中不断地变换具体的业务处理,直到一个完整地业务被处理掉。
在整个实现中,涉及到2个问题。一是事件的划分和处理,二是具体事件的隔离和处理。
1 事件的划分和处理
在服务端,需要处理3类事件信息,接收数据请求,读取请求数据,写入响应数据。读取数据和写入数据都是在connection已经建立好的情况下进行,而接收数据请求则表示服务端已经准备好接收由客户端发起的一个请求。这里将数据的处理和请求的接收分开,即分成2个大的处理部分。一个简单的原因即在于当连接已经建立起之后,服务端是一定要处理这个数据请求的;而连接还没有建立时,是可以拒绝处理的。即在当请求端有大量的请求在准备接收时,服务端不会因为请求的处理太多影响到后端的数据处理。
这里涉及到线程网络处理的问题,如果大量的处理线程都处理请求接收时,就意味着后台有大量的连接需要处理,而之前已经接收到的请求处理就会受到相应的影响,进而影响到整个系统的稳定性。将接收和处理分离,有利于更好地实现请求限制和分发。