`
longgangbai
  • 浏览: 7251203 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论
阅读更多

      服务器推送技术的基础思想是将浏览器主动查询信息改为服务器主动发送信息,服务器发送一批数据,浏览器显示消息,同时保证与服务器的连接,当服务器需要再一次的发送数据,浏览器显示数据并保持连接。

comet基于HTTP长连接技术,无需安装插件。

 

 

 

  • comet:一个概念,web push
  • pushlet:comet的一个实现。
  • 就是保持长连接的策略问题,有人用jquery写了相应的util

 

  • Pushlet基于HTTP流,这种技术常常用在多媒体视频、通讯应用中,比如QuickTime。与装载HTTP页面之后马上关闭HTTP连接的做法相反,Pushlet采用HTTP流方式将新变动的数据主动地推送到client(客户端),再此期间HTTP连接一直保持打开。有关如何在Java中实现这种Keep-alive的长连接请参看Sun提供的《HTTP Persistent Connection》和W3C的《HTTP1.1规范》

 

  • Tomcat的comet原理其实同样很简单,它无非就是做了一件事情,它允许servlet执行完毕后的response没有被回收,我们只要拿到这个Reponse的引用并保存起来,就可以随时从Server向Client端Push数据了。每个连接一个线程的模型便非常简单。该模型对于 Comet 不大适用,但是,Java 对此同样有解决的办法。为了有效地处理 Comet,需要非阻塞 IO,Java 通过它的 NIO 库提供非阻塞 IO。两种最流行的开源服务器 Apache Tomcat 和 Jetty 都利用 NIO 增加非阻塞 IO,从而支持 Comet.

 

  • 而非阻塞I/O和同步I/O最明显的不同就是同步I/O所有可能被阻塞的地址在非阻塞I/O中都不会被阻塞。如在读取数据时,如果数据暂时无法被读取。那么在非阻塞I/O中会立刻返回,以便程序可以执行其他的代码,然后系统会不断侦测这个未完成的读取操作,直到可以继续读数据时再来完成这个操作。非阻塞式IO的出现的目的就是为了解决这个瓶颈。而非阻塞式IO是怎么实现的呢?非阻塞IO处理连接的线程数和连接数没有联系,也就是说处理10000个连接非阻塞IO不需要10000个线程,你可以用1000个也可以用2000个线程来处理。因为非阻塞IO处理连接是异步的。当某个连接发送请求到服务器,服务器把这个连接请求当作一个请求"事件",并把这个"事件"分配给相应的函数处理。我们可以把这个处理函数放到线程中去执行,执行完就把线程归还。这样一个线程就可以异步的处理多个事件。而阻塞式IO的线程的大部分时间都浪费在等待请求上了。
  • 在comet中,为了保持长连接,如果使用阻塞时IO,则不可避免的对每一个连接保持一个线程。不同于短连接,线程可以及时释放。长连接对应的线程可能永远不能释放,这样一个server能够服务的客户端的数量就受到了线程数量上限的限制。而使用NIO可以伺候多个连接而不必要保持相应数量的线程。就解决了这个问题。

 

  • Tomcat提供了CometProcessor接口,有这种特定标记的Servlet,Tomcat会做特殊处理,Tomcat不会把它当做普通Servlet实行完毕后,会回收request和response。注意:实现CometProcessor接口后不用在servlet中写doGet,doPoset方法,所有事件在BEGIN,READ,END,ERROR中实现。
  • 从event拿到的request和response不会在begin和end/error之间不会被释放,一直有效。可以用来传递消息。Note that the response object and dependent OutputStream and Writer are still not synchronized, so when they are accessed by multiple threads, synchronization is mandatory.
  • BEGIN:初始化参数和获取request和response,结束时,request is commited
  • READ(只有POST方法,才会触发该事件):有数据从request进来,可以从request读取数据。在此事件之外不允许读取request的数据。On some platforms, like Windows, a client disconnect is indicated by a READ event. Reading from the stream may result in -1, an IOException or an EOFException. Make sure you properly handle all these three cases. If you don't catch the IOException, Tomcat will instantly invoke your event chain with an ERROR as it catches the error for you, and you will be notified of the error at that time.
  • END: End may be called to end the processing of the request. Fields that have been initialized in the begin method should be reset. After this event has been processed, the request and response objects, as well as all their dependent objects will be recycled and used to process other requests. End will also be called when data is available and the end of file is reached on the request input (this usually indicates the client has pipelined a request).
  • ERROR: Error will be called by the container in the case where an IO exception or a similar unrecoverable error occurs on the connection. Fields that have been initialized in the begin method should be reset. After this event has been processed, the request and response objects, as well as all their dependent objects will be recycled and used to process other requests.(END,ERROR之后request和response就不要再用了)

 

  • ventSubType.TIMEOUT: The connection timed out (sub type of ERROR); note that this ERROR type is not fatal, and the connection will not be closed unless the servlet uses the close method of the event.
  • EventSubType.CLIENT_DISCONNECT: The client connection was closed (sub type of ERROR). method of the event.
  • EventSubType.IOEXCEPTION: An IO exception occurred, such as invalid content, for example, an invalid chunk block (sub type of ERROR).
  • EventSubType.WEBAPP_RELOAD: The web application is being reloaded (sub type of END).
  • EventSubType.SESSION_END: The servlet ended the session (sub type of END).

BEGIN-READ-READ-Error/TIMEOUT。随时可以event.close()。来终止连接。

 

 

  • writer.flush();writer.close();长轮询和流风格的comet的差别只是取决于是否有第二句(长轮询需要client端在response关闭后再重连)

 

If you are using the NIO connector, you can set individual timeouts for your different comet connections. To set a timeout, simply set a request attribute like the following code shows:

CometEvent event.... event.setTimeout(30*1000);

or

event.getHttpServletRequest().setAttribute("org.apache.tomcat.comet.timeout", new Integer(30 * 1000));

This sets the timeout to 30 seconds. Important note, in order to set this timeout, it has to be done on the BEGIN event. The default value is soTimeout

 

 

      简单的Comet servlet代码示例:

package com.easyway.comet.pushlet;

import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;
import org.apache.catalina.CometEvent.EventType;
/**
 * Tomcat6推送技术通过时现实tomcat的推送接口CometProcessor实现的servlet实现推送技术,在
 * servlet中out.close()方法不能使用,否則不能持續推送信息.
 * <p>功能描述,该部分必须以中文句号结尾。<p>
 *
 * 创建日期  2013-7-21<br>
 * @author  longgangbai <br>
 * @version $Revision$ $Date$
 * @since   3.0.0
 */
public class CometServlet extends HttpServlet implements CometProcessor {
    //
    private static final long serialVersionUID = 1L;

    public void event(CometEvent e) throws IOException, ServletException {
        if (e.getEventType() == EventType.BEGIN) {
            // fill in code handling here
           HttpServletResponse response = e.getHttpServletResponse();
            PrintWriter out = response.getWriter();
            out.write("Hello world");
            out.flush(); 
            //System.out.println("message sent");
        }else if (e.getEventType() == EventType.READ) {
        }else if (e.getEventType() == EventType.ERROR) {
        }else if(e.getEventType() == EventType.END){
        }
      
        // and continue handing other events
    }
}

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>CometTomcat6</display-name>
  <servlet>
     <servlet-name>cometTomcet6</servlet-name>
     <servlet-class>com.easyway.comet.pushlet.CometServlet</servlet-class>
  </servlet>
  <servlet-mapping>
      <servlet-name>cometTomcet6</servlet-name>
      <url-pattern>/cometServlet</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

 

html界面代碼:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
 <script>
 //服务器端代码类似与普通Ajax代码,其中,需要注意的是:request.readyState值如果设置为4,浏览器会处于长期等待状态,而收不到响应消息,设置为3后,firefox浏览器正常,但IE不能正常获得消息
 function CometEx() {
   var request =  new XMLHttpRequest();
   request.open("GET", "http://localhost:8080/CometTomcat6/cometServlet", true);
   request.onreadystatechange = function() {
     if (request.readyState == 3 && request.status == 200) {
            alert(request.responseText);     
     }
   }
   request.send(null);
 }
 </script>
<body onload="CometEx();">

</body>
</html>

 

分享到:
评论

相关推荐

    tomcat实现推送技术

    NULL 博文链接:https://tangguolong99.iteye.com/blog/1976417

    基于XMPP协议的Android消息推送设计与实现.pdf

    随着移动互联网的快速发展,消息推送已成为手机端产品...将其部署在MySQL 数据库和Tomcat 服务器下,实现并改进了实时推送消息、自定义消息结构和内容、推送服务开机启动、手机端服务唤醒、发送离线消息等实用技术。

    Comet4J服务器端推送技术

    Comet4J是一个微型的即时推送框架,它分为服务端与客户端两部分,你只要将服务器端(JAR文件,目前仅支持Tomcat6、7)放入WEB-INF\lib,客户端(JavaScript文件)引入到页面,那么你的应用就具备了向客户端推送信息的...

    Android完美的消息推送技术Androidpn,安装后改ip地址即可

    网上很多讲解androidpn推送的博客,也有很多源码,下载后导入有时也会有错误,此资源可以完美的运行,运行前你需要完成如下操作:1、启动Tomcat 2、下载androidpn 地址:http://sourceforge.net/projects/androidpn/...

    web推送 comet技术

    demo是采用comet的web推送技术,使用tomcat7做服务器,内含tomcat7上面配置说明,在MyEclipse、tomcat7上面完美运行,本人亲测!

    javaweb实现后台向前台的消息推送 comet4j

    这是一个利用comet4j第三方插件,实现javaweb项目中后台消息向前台推送的一个功能,前台只要利用jquery,后台是用java实现,tomcat用7的版本

    数据推送示例

    数据推送示例说明 (1)项目目标:日志实时展现 (2)实现过程:后台模拟生成动态日志,前端将日志实时展现在页面 (3)客户端所用技术:html5 websocket, 服务器端技术:spring websocket (spring 4.0版以上支持)...

    热度分析和自媒体推送平台代码 java热度分析和自媒体推送平台代码

    1、热度分析和自媒体推送平台的技术栈、环境、工具、软件: ① 系统环境:Windows/Mac ② 开发语言:Java ③ 框架:SpringBoot ④ 架构:B/S、MVC ⑤ 开发环境:IDEA、JDK、Maven、Mysql ⑥ JDK版本:JDK1.8 ⑦ Maven包...

    智能热度分析和自媒体推送平台代码 java智能热度分析和自媒体推送平台代码

    1、智能热度分析和自媒体推送平台的技术栈、环境、工具、软件: ① 系统环境:Windows/Mac ② 开发语言:Java ③ 框架:SpringBoot ④ 架构:B/S、MVC ⑤ 开发环境:IDEA、JDK、Maven、Mysql ⑥ JDK版本:JDK1.8 ⑦ ...

    基于tomact,comet4j,java服务器端推送消息到web页面

    这个项目是基于tomcat,comet4j的技术来实现推送消息到web页面,可以直接导入,直接运行的,里面包含了项目所需要的comet4j-tomcat7.jar(tomcat7的就导入这个),comet4j.js(页面引入这个js),等jar包,对于想要学习...

    基于springboot的热度分析和自媒体推送平台代码

    1、热度分析和自媒体推送平台的技术栈、环境、工具、软件: ① 系统环境:Windows/Mac ② 开发语言:Java ③ 框架:SpringBoot ④ 架构:B/S、MVC ⑤ 开发环境:IDEA、JDK、Maven、Mysql ⑥ JDK版本:JDK1.8 ⑦ Maven包...

    基于springboot的智能热度分析和自媒体推送平台代码

    1、智能热度分析和自媒体推送平台的技术栈、环境、工具、软件: ① 系统环境:Windows/Mac ② 开发语言:Java ③ 框架:SpringBoot ④ 架构:B/S、MVC ⑤ 开发环境:IDEA、JDK、Maven、Mysql ⑥ JDK版本:JDK1.8 ⑦ ...

    comet4j-tomcat6.jar.rer

    comet4j-tomcat7.jar 配合comet4j.js使用实现实时推送技术

    服务器推送技术之comet4j资源包

    此资源包中包含了tomcat7所需要的jar包与comet4j.js请各位自取,谢谢!

    最新SpringBoot项目智能热度分析和自媒体推送平台.zip

    这个资源是一个基于Spring Boot的智能热度分析和自媒体推送平台项目,它旨在帮助自媒体人员分析内容的热度,并根据分析结果进行有针对性的内容推送。以下是对该项目的详细介绍: 1. **技术栈与框架**: - 后端使用...

    消息推送项目源码

    该项目使用的框架为spring struts2 hibernate ,用到的技术为socket长连接技术,项目解压后直接部署在tomcat中即可运行访问。

    项目源码-SpringBoot整合微信模板消息实现每日给女友发送早安问候语和天气预报.zip

    今天我们给大家分享一个使用微信消息模板每日定时推送早安问候语和天气预报的功能,学会了,块给你女朋友安排上吧 功能点: 1、微信公众平台申请账号及微信开放接口的调用。 2、百度地图天气API接口的调用。 3、...

    HTML5 WebSocket

    以前的服务器消息推送大部分采用的都是“轮询”和“长连接”技术,这两中技术都会对服务器产生相当大的开销,而且实时性不是特别高。WebSocket技术对只会产生很小的开销,并且实时性特别高。下面就开始讲解如何利用...

Global site tag (gtag.js) - Google Analytics