博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Serlvet 处理http请求并保持长连接
阅读量:6358 次
发布时间:2019-06-23

本文共 2942 字,大约阅读时间需要 9 分钟。

一.Servlet,一个请求在容器中是如何处理的

Servlet规定的,相应客户请求访问特定Servlet流程如下:

1.客户端发出请求。

2.Servlet容器接收客户请求解析。

3.Servlet容器创建一个ServletRequest对象。

其中包含客户请求信息及其他关于客户的信息如请求头,请求正文,客户机的IP等。

4.容器创建一个ServletResponse对象。

5.容器调用客户请求的Servlet的service方法,并且把ServletRequest和ServletResponse作为参数传入。

6.Servlet从客户参数中获得客户请求信息,并调用对应的doGet或doPost处理。

7.Servlet利用ServletResponse对象来生产相应结果。

8.Servlet容器把Servlet生成的结果发给客户。

二.Servlet3.0长连接

servlet3.0规范中添加了异步处理,即一部分操作处理完成之后,先行把数据返回来,对于另一部分比较耗时的操作可以放置到另外一个线程中进行处理,该线程保留有连接的请求和响应对象,在处理完成之后可以把处理的结果通知到客户端,实例代码如下:

 

[java]   
 
 
  1. import java.io.IOException;  
  2. import java.io.PrintWriter;  
  3. import java.util.Date;  
  4. import javax.servlet.AsyncContext;  
  5. import javax.servlet.AsyncEvent;  
  6. import javax.servlet.AsyncListener;  
  7. import javax.servlet.ServletException;  
  8. import javax.servlet.annotation.WebServlet;  
  9. import javax.servlet.http.HttpServlet;  
  10. import javax.servlet.http.HttpServletRequest;  
  11. import javax.servlet.http.HttpServletResponse;  
  12. @WebServlet(urlPatterns="/demo", asyncSupported=true)  
  13. public class AsynServlet extends HttpServlet {  
  14.     private static final long serialVersionUID = -8016328059808092454L;  
  15.       
  16.     /* (non-Javadoc) 
  17.      * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 
  18.      */  
  19.     @Override  
  20.     protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {  
  21.             resp.setContentType("text/html;charset=UTF-8");  
  22.             PrintWriter out = resp.getWriter();  
  23.             out.println("进入Servlet的时间:" + new Date() + ".");  
  24.             out.flush();  
  25.   
  26.             //在子线程中执行业务调用,并由其负责输出响应,主线程退出  
  27.             final AsyncContext ctx = req.startAsync();  
  28.             ctx.setTimeout(200000);  
  29.             new Work(ctx).start();  
  30.             out.println("结束Servlet的时间:" + new Date() + ".");  
  31.             out.flush();  
  32.     }  
  33. }  
  34.   
  35. class Work extends Thread{  
  36.     private AsyncContext context;  
  37.       
  38.     public Work(AsyncContext context){  
  39.         this.context = context;  
  40.     }  
  41.     @Override  
  42.     public void run() {  
  43.         try {  
  44.             Thread.sleep(2000);//让线程休眠2s钟模拟超时操作  
  45.             PrintWriter wirter = context.getResponse().getWriter();           
  46.             wirter.write("延迟输出");  
  47.             wirter.flush();  
  48.             context.complete();  
  49.         } catch (InterruptedException e) {  
  50.               
  51.         } catch (IOException e) {  
  52.               
  53.         }  
  54.     }  
  55. }  

 

有些时候,我们可能需要客户端和服务器保持长连接的时候,我们可以使用这个特性,让服务器长时间保持客户端的请求以及对客户端的响应,做法如下:

对于异步执行,我们可以添加一个监听器,监听异步执行的状态。

[java]   
 
 
  1. ctx.addListener(new AsyncListener() {  
  2.     @Override  
  3.     public void onTimeout(AsyncEvent arg0) throws IOException {  
  4.         // TODO Auto-generated method stub                
  5.     }             
  6.     @Override  
  7.     public void onStartAsync(AsyncEvent arg0) throws IOException {  
  8.         // TODO Auto-generated method stub                
  9.     }             
  10.     @Override  
  11.     public void onError(AsyncEvent arg0) throws IOException {  
  12.         // TODO Auto-generated method stub  
  13.     }  
  14.     @Override  
  15.     public void onComplete(AsyncEvent arg0) throws IOException {  
  16.         // TODO Auto-generated method stub  
  17.     }  
  18. });  

在Servlet返回之前,我们可以把持有request和response对象的AsyncContext对象放置到一个全局可访问的静态容器中

map.put("id",ctx);

如果连接出错或者连接完的时候我们可以在onError以及onComplete方法中移除掉对应连接的AsyncContext

map.remove("id",ctx);

在超时的回调方法onTimeout中,我们可以往浏览器发送指定的信息,让客户端重新发起请求,这样就可以保持客户端和服务器的长久连接。

如下服务器和客户端之间数据交互的模型图

转载于:https://www.cnblogs.com/wangyage/p/7183331.html

你可能感兴趣的文章
CentOS7.4安装配置mysql5.7 TAR免安装版
查看>>
解决IE二级链接无法打开故障
查看>>
Windows phone应用开发[16]-数据加密
查看>>
SQL Server 迁移数据到MySQL
查看>>
通用数据压缩算法简介
查看>>
The next Industry Standard in IT Monitoring, a python implementation Nagios like tool --- Shinken
查看>>
(笔记)找工作,该怎么进补
查看>>
div的显示和隐藏以及点击图标的更改
查看>>
(轉貼) Ubuntu將在ARM平台netbook上現身 (SOC) (News) (Linux) (Ubuntu)
查看>>
SQL注入测试工具:Pangolin(穿山甲)
查看>>
在html 的img属性里只显示图片的部分区域(矩形,给出开始点和结束点),其他部份不显示,也不要拉伸...
查看>>
程序员第二定律:量化管理在程序员身上永无可能
查看>>
ubuntu一些脚本的执行顺序
查看>>
类继承的结构
查看>>
Intel 被 ARM 逼急了
查看>>
testng + reportng 测试结果邮件发送
查看>>
百度亮相iDASH,推动隐私保护在人类基因组分析领域的应用
查看>>
Python「八宗罪」
查看>>
你的隐私还安全吗?社交网络中浏览历史的去匿名化
查看>>
NeurIPS 2018|如何用循环关系网络解决数独类关系推理任务?
查看>>