• HTTP长连接实现“服务器推”的技术


    HTTP长连接实现“服务器推”的技术快速入门及演示示例
    在我的印象里HTTP是一种“无状态的协议”,也就是不知道以前请求的历史,无法保留上一次请求的结果。
    Cookie的诞生,弥补了这个不足,浏览器可以通过本地持久化请求数据来记录上次请求的环境。但这个没有根本上改变HTTP请求本身的这种“客户端请求服务器端相应”模式——客户端是主动的,而服务器是被动的。
    最近听说有“HTTP长连接”,去探索了一把,果然很有意思,能够实现“服务器推”的这种概念,也就是服务器是主动发送请求,客户端是被动接受请求。
    关于“服务器推”及“HTTP长连接”的概念网上很多,给一个比较系统的介绍文章:
    http://www.ibm.com/developerworks/cn/web/wa-lo-comet/

    HTTP长连接这种把数据从服务器主动“推”到客户端的技术,能带来的好处不言而喻。它可以把最新的统计数据输出到客户端,也可以实现即时通讯。

    下面是JSP实现的一个“监控服务器时间”程序的代码示例(片段)
    1、web.xml
    [html] view plaincopy
     
    1. <servlet>  
    2.     <servlet-name>ServerTimeMonitorServlet</servlet-name>  
    3.     <servlet-class>com.ebiz.test.ServerTimeMonitorServlet</servlet-class>  
    4.     <init-param>  
    5.         <param-name>interval</param-name>  
    6.         <param-value>1</param-value>  
    7.     </init-param>  
    8. </servlet>  
    9. <servlet-mapping>  
    10.     <servlet-name>ServerTimeMonitorServlet</servlet-name>  
    11.     <url-pattern>/ServerTimeMonitor</url-pattern>  
    12. </servlet-mapping>  

    2、servlet:ServerTimeMonitorServlet.java
    [java] view plaincopy
     
    1. package com.ebiz.test;  
    2.   
    3. import java.io.IOException;  
    4. import java.text.SimpleDateFormat;  
    5. import java.util.Date;  
    6.   
    7. import javax.servlet.ServletConfig;  
    8. import javax.servlet.ServletException;  
    9. import javax.servlet.http.HttpServlet;  
    10. import javax.servlet.http.HttpServletRequest;  
    11. import javax.servlet.http.HttpServletResponse;  
    12.   
    13. public class ServerTimeMonitorServlet extends HttpServlet {  
    14.   
    15.     private static final long serialVersionUID = -3981794330055840248L;  
    16.   
    17.     private String interval = "1";  
    18.   
    19.     public void init(ServletConfig config) throws ServletException {  
    20.         this.interval = config.getInitParameter("interval");  
    21.         super.init();  
    22.     }  
    23.   
    24.     public void destroy() {  
    25.         this.interval = null;  
    26.         super.destroy();  
    27.     }  
    28.   
    29.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,  
    30.             java.io.IOException {  
    31.         for (int i = 0; i < 100; i++) {  
    32.             try {  
    33.                 Thread.sleep(1000 * Integer.valueOf(interval));  
    34.             } catch (NumberFormatException e) {  
    35.                 e.printStackTrace();  
    36.             } catch (InterruptedException e) {  
    37.                 e.printStackTrace();  
    38.             }  
    39.               
    40.             SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss E");  
    41.             String date_str = df.format(new Date());  
    42.               
    43.             writerResponse(response, date_str, "showServerTime");// msg是test.jsp中的那个js方法的名称  
    44.         }  
    45.         return;  
    46.     }  
    47.   
    48.     protected void writerResponse(HttpServletResponse response, String body, String client_method) throws IOException {  
    49.         StringBuffer sb = new StringBuffer();  
    50.         sb.append("<script type="text/javascript">//<![CDATA[ ");  
    51.         sb.append("     parent.").append(client_method).append("("").append(body).append(""); ");  
    52.         sb.append("//]]></script>");  
    53.         System.out.println(sb.toString());  
    54.   
    55.         response.setContentType("text/html;charset=GBK");  
    56.         response.addHeader("Pragma", "no-cache");  
    57.         response.setHeader("Cache-Control", "no-cache,no-store,must-revalidate");  
    58.         response.setHeader("Cache-Control", "pre-check=0,post-check=0");  
    59.         response.setDateHeader("Expires", 0);  
    60.         response.getWriter().write(sb.toString());  
    61.         response.flushBuffer();  
    62.     }  
    63.   
    64.     public String getInterval() {  
    65.         return interval;  
    66.     }  
    67.   
    68.     public void setInterval(String interval) {  
    69.         this.interval = interval;  
    70.     }  
    71.   
    72. }  

    3、jsp:server-time-monitor.jsp
    [html] view plaincopy
     
    1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>  
    2. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  
    3. <c:set var="ctx" value="${pageContext.request['contextPath']}" />  
    4.   
    5. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
    6. <html xmlns="http://www.w3.org/1999/xhtml">  
    7. <head>  
    8. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
    9. <title>HTTP 长连接测试 —— 监控服务器时间 </title>  
    10. </head>  
    11.   
    12. <body>  
    13. <div id="monitor-window">服务器现在是:<span id="time"></span></div>  
    14. <form id="a-form" action="${ctx}/ServerTimeMonitor" method="post" target="handleFrame">  
    15.     <input type="submit" name="submit" id="submit" value=" 获取并监控服务器时间 " />  
    16. </form>  
    17. <iframe name="handleFrame" id="handleFrame" style="display:none"></iframe>  
    18.   
    19. <!-- <script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script> -->  
    20. <script type="text/javascript" src="jquery-1.10.2.min.js"></script>  
    21. <script type="text/javascript">//<![CDATA[ 
    22. function showServerTime(msg) { 
    23.     $("#time").html(msg); 
    24. //]]></script>  
    25. </body>  
    26. </html>  

    执行过程

    仔细看JSP这段HTML代码,很有意思。

    1、form通过POST请求把返回的Script代码输出到iframe中(form的target="handleFrame")。这段返回的Script代码在服务器的控制台输出如下:

    [javascript] view plaincopy
     
    1. <script type="text/javascript">//<![CDATA[  
    2.         parent.showServerTime("2013-08-17 12:08:14 星期六");  
    3. //]]></script>  
    2、iframe完成加载上面这段代码后解析并执行,这段代码的作用是调用父页面的“showServerTime”方法,把消息传入。

    3、父页面showServerTime函数负责处理接收到的消息。

    4、Servlet负责定时执行和输出,源源不断向客户端发送内容。

    原来,这个隐藏的iframe起到了一个“纽带”的作用。

    演示结果

    测试结果

    在Chrome中标题前面有一个正在加载的图标,感觉上页面一直在加载,IE9中没有这个现象,其他浏览器没有测试。

    (完)

  • 相关阅读:
    享受法国葡萄酒
    shell (bash) hot keys
    传统MapReduce框架
    【oracle】常用命令
    【转】商业J2EE中间件价值何在?
    【转】Linux(CentOS)服务器上安装Webmin
    【转】CentOS 5安装免费主机控制面板Webmin
    【源码】不规则矩形窗体的设计
    【转】虚拟机VirtualBox+Centos+NAT网络的配置过程
    【jsp】 config配置的关键字
  • 原文地址:https://www.cnblogs.com/Rozdy/p/4279358.html
Copyright © 2020-2023  润新知