Comet
Comet是一种用于web的推送技术,能使服务器实时地将更新的信息传送到客户端,而无须客户端发出请求 在WebSocket出来之前,如果不使用comet,只能通过浏览器端轮询Server来模拟实现服务器端推送。 Comet支持servlet异步处理IO,当连接上数据可读时触发事件,并异步写数据(阻塞)
Tomcat要实现Comet,只需继承HttpServlet同时,实现CometProcessor接口
Begin:新的请求连接接入调用,可进行与Request和Response相关的对象初始化操作,并保存response对象,用于后续写入数据
Read:请求连接有数据可读时调用
End:当数据可用时,如果读取到文件结束或者response被关闭时则被调用
Error:在连接上发生异常时调用,数据读取异常、连接断开、处理异常、socket超时
Note:
Read:在post请求有数据,但在begin事件中没有处理,则会调用read,如果read没有读取数据,在会触发Error回调,关闭socket
End:当socket超时,并且response被关闭时也会调用;server被关闭时调用
Error:除了socket超时不会关闭socket,其他都会关闭socket
End和Error时间触发时应关闭当前comet会话,即调用CometEvent的close方法 Note:在事件触发时要做好线程安全的操作
异步Servlet
传统流程:
首先,Servlet 接收到请求之后,request数据解析;
接着,调用业务接口的某些方法,以完成业务处理;
最后,根据处理的结果提交响应,Servlet 线程结束
异步处理流程:
客户端发送一个请求
Servlet容器分配一个线程来处理容器中的一个servlet
servlet调用request.startAsync(),保存AsyncContext, 然后返回
任何方式存在的容器线程都将退出,但是response仍然保持开放
业务线程使用保存的AsyncContext来完成响应(线程池)
客户端收到响应
Servlet 线程将请求转交给一个异步线程来执行业务处理,线程本身返回至容器,此时 Servlet 还没有生成响应数据,异步线程处理完业务以后,可以直接生成响应数据(异步线程拥有 ServletRequest 和 ServletResponse 对象的引用)
为什么web应用中支持异步?
推出异步,主要是针对那些比较耗时的请求:比如一次缓慢的数据库查询,一次外部REST API调用, 或者是其他一些I/O密集型操作。这种耗时的请求会很快的耗光Servlet容器的线程池,继而影响可扩展性。
Note:从客户端的角度来看,request仍然像任何其他的HTTP的request-response交互一样,只是耗费了更长的时间而已
异步事件监听
onStartAsync:Request调用startAsync方法时触发
onComplete:syncContext调用complete方法时触发
onError:处理请求的过程出现异常时触发
onTimeout:socket超时触发
Note : onError/ onTimeout触发后,会紧接着回调onComplete onComplete 执行后,就不可再操作request和response
总结:
开源的 Java Web 应用服务器,实现了 Java EE(Java Platform Enterprise Edition)的部 分技术规范,比如 Java Servlet、Java Server Page、JSTL、Java WebSocket。Java EE 是 Sun 公 司为企业级应用推出的标准平台,定义了一系列用于企业级开发的技术规范,除了上述的之外,还有 EJB、Java Mail、JPA、JTA、JMS 等,而这些都依赖具体容器的实现。