zoukankan      html  css  js  c++  java
  • 用 servlet实现http长连接

    为了实现服务端向客户端推送的模式,如果自己写的socket到时顺理成章的很容易实现。但是,甲方要我们用标准的http协议。当然,自己写http服务器倒是也没什么题,我开始也时这么想的,而且都设计好了分布计算和负载平衡的方式。但有人暂时还建议我们用中间件,他们的意见就像天气的脸,一会儿这样,一会儿那样。于是在这方面考虑,无奈和喜悦同时而生。无奈的是,直接应用中间件,成就感将大打折扣。喜悦的是,直接应用中间件,我的开发量几乎可以说就是实现商业逻辑,分布计算和负载平衡都可以配置中间件实现。

    那么如果用中间件写http服务,来应付客户端的请求并实现推送模式呢。在开会的时候, 一个同事使我猛醒。他说他就直接写一个servlet,这就是标准的http服务。这时,我便想起了我曾写过用Java中URL累实现的http客户端。不妨用之,这样服务端客户端就都有了试验的依据。其中我问及同事是否实现长连接,结果他说没有 (应该是没想到这点),但是我们知道,服务推送的模式每次都打开和关闭与客户端的连接必然很耗资源。而我们实现的系统就是具备长连接,而且很耗带宽的连接,不管是长连接还是短连接。如果每次数据传送都要建立连接,而且请求非常频繁的假推送模式效能很低的话,我们就可以试一试长连接推送的方式。

    也许你会想,servlet的长连接怎么实现呢。不错,用while循环就可以了。平常我们用浏览器浏览网页,大都一次请求,然后得到结果,关闭连接。其实如果服务端用一个死循环,一直在发送数据,而且客户端没有关闭的话,连接是一直存在的。我们完全可以用这条连接实现服务推模式。当然,监听的客户端自己写一个很简单,如下:

    Java代码  收藏代码
    1. package test;  
    2.   
    3. import java.io.InputStream;  
    4. import java.net.URL;  
    5.   
    6. public class LongConnectionClient {  
    7.       
    8.     public static void main(String args[]) {  
    9.         try {  
    10.               
    11.             //确定服务地址  
    12.             URL url = new URL("http://localhost:8080/HttpConnectionTest/LongConnectionTest");  
    13.             InputStream in=url.openStream();  
    14.             int n = -1;  
    15.             byte[] b = new byte[1024];  
    16.             //从服务端读取数据并打印  
    17.             while((n=in.read(b))!=-1)  
    18.             {  
    19.                 String s=new String(b,0,n, "UTF-8");  
    20.                 System.out.println(s);      
    21.             }  
    22.               
    23.         } catch (Exception e) {  
    24.             e.printStackTrace();  
    25.         }  
    26.     }  
    27.   
    28. }  



    服务端的代码也异常简单:

    Java代码  收藏代码
      1. package test;  
      2.   
      3. import java.io.IOException;  
      4. import java.io.PrintWriter;  
      5.   
      6. import javax.servlet.ServletException;  
      7. import javax.servlet.http.HttpServletRequest;  
      8. import javax.servlet.http.HttpServletResponse;  
      9.   
      10.  public class LongConnectionTest extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {  
      11.    static final long serialVersionUID = 1L;  
      12.      
      13.     public LongConnectionTest() {  
      14.         super();  
      15.     }         
      16.       
      17.     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
      18.         this.doPost(request, response);  
      19.     }     
      20.       
      21.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
      22.   
      23.          response.setCharacterEncoding("UTF-8");  
      24.          response.setContentType("text/html");  
      25.           
      26.          PrintWriter pr = response.getWriter();  
      27.            
      28.          try {  
      29.              while(true) {  
      30.                  pr.print("有时候你不得不相信");  
      31.                  //flush的作用很重要,当你任务写给客户端的数据总够多的时候  
      32.                  //调用之,客户端方能读取到。  
      33.                  //否则,在数据长度达到上限或者连接关闭之前,客户端读不到数据  
      34.                  pr.flush();  
      35.                  Thread.sleep(500);  
      36.              }  
      37.          } catch(Exception e) {  
      38.              e.printStackTrace();  
      39.          }  
      40.           
      41.     }                 
      42. }  
  • 相关阅读:
    转:单链表有环判断及其起始位置定位
    转:C++经典排序算法总结
    转:堆排序
    转载:C++快速排序
    转载:平衡二叉树(AVL Tree)
    设计模式原则
    适配器模式
    单例模式
    工厂模式
    Head First设计模式 装饰者模式
  • 原文地址:https://www.cnblogs.com/wangyage/p/7169925.html
Copyright © 2011-2022 走看看