`
bethel
  • 浏览: 23186 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

IBM的一个Comet实现例子的问题

    博客分类:
  • IBM
阅读更多

源地址链接: http://www.ibm.com/developerworks/cn/web/wa-cometjava/

 

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;

import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;

public class TomcatWeatherServlet extends HttpServlet implements CometProcessor {

    private MessageSender messageSender = null;
    private static final Integer TIMEOUT = 60 * 1000;
    @Override
    public void destroy() {
    	log("destroy()!!!");
        messageSender.stop();
        messageSender = null;

    }

    @Override
    public void init() throws ServletException {
    	log("init()!!!");
        messageSender = new MessageSender();
        Thread messageSenderThread =
                new Thread(messageSender, "MessageSender[" + getServletContext().getContextPath() + "]");
        messageSenderThread.setDaemon(true);
        messageSenderThread.start();

    }

    public void event(final CometEvent event) throws IOException, ServletException {
        HttpServletRequest request = event.getHttpServletRequest();
        HttpServletResponse response = event.getHttpServletResponse();
        if (event.getEventType() == CometEvent.EventType.BEGIN) {
            request.setAttribute("org.apache.tomcat.comet.timeout", TIMEOUT);
            log("Begin for session: " + request.getSession(true).getId());
            messageSender.setConnection(response);
            Weatherman weatherman = new Weatherman(95118, 32408);
            weatherman.start();
        } else if (event.getEventType() == CometEvent.EventType.ERROR) {
        	log("Error for session: " + request.getSession(true).getId());
            event.close();
        } else if (event.getEventType() == CometEvent.EventType.END) {
        	log("End for session: " + request.getSession(true).getId());
            event.close();
        } else if (event.getEventType() == CometEvent.EventType.READ) {
            throw new UnsupportedOperationException("This servlet does not accept data");
        }

    }

private class Weatherman {

    private final List<URL> zipCodes;
    private final String YAHOO_WEATHER = "http://weather.yahooapis.com/forecastrss?p=";

    public Weatherman(Integer... zips) {
        zipCodes = new ArrayList<URL>(zips.length);
        for (Integer zip : zips) {
            try {
                zipCodes.add(new URL(YAHOO_WEATHER + zip));
            } catch (Exception e) {
                // dont add it if it sucks
            }
        }
    }

    public void start() {
        Runnable r = new Runnable() {

            public void run() {
                int i = 0;
                while (i >= 0) {
                    int j = i % zipCodes.size();
                    SyndFeedInput input = new SyndFeedInput();
                    try {
                        SyndFeed feed = input.build(new InputStreamReader(zipCodes.get(j).openStream()));
                        SyndEntry entry = (SyndEntry) feed.getEntries().get(0);
                        messageSender.send(entryToHtml(entry));
                        Thread.sleep(30000L);
                    } catch (Exception e) {
                        // just eat it, eat it
                    }
                    i++;
                }
            }
        };
        Thread t = new Thread(r);
        t.start();
    }
    private String entryToHtml(SyndEntry entry){
        StringBuilder html = new StringBuilder("<h2>");
        html.append(entry.getTitle());
        html.append("</h2>");
        html.append(entry.getDescription().getValue());
        return html.toString();
    }
}

   private class MessageSender implements Runnable {

        protected boolean running = true;
        protected final ArrayList<String> messages = new ArrayList<String>();
        private ServletResponse connection;

        private synchronized void setConnection(ServletResponse connection){
            this.connection = connection;
            notify();
        }

        public void stop() {
            running = false;
        }

        /**
         * Add message for sending.
         */
        public void send(String message) {
            synchronized (messages) {
                messages.add(message);
                log("Message added #messages=" + messages.size());
                messages.notify();
            }
        }

        public void run() {
        	log("start running!!!");
            while (running) {
                if (messages.size() == 0) {
                    try {
                        synchronized (messages) {
                        	log("start waiting!!!");
                            messages.wait();
                        }
                    } catch (InterruptedException e) {
                        // Ignore
                    }
                }
                String[] pendingMessages = null;
                synchronized (messages) {
                    pendingMessages = messages.toArray(new String[0]);
                    messages.clear();
                }
                try {
                    if (connection == null){
                        try{
                            synchronized(this){
                                wait();
                            }
                        } catch (InterruptedException e){
                            // Ignore
                        }
                    }
                    PrintWriter writer = connection.getWriter();
                    for (int j = 0; j < pendingMessages.length; j++) {
                        final String forecast = pendingMessages[j] + "<br>";
                        writer.println(forecast);
                        log("Writing:" + forecast);
                    }
                    writer.flush();
                    writer.close();
                    //connection = null;
                    log("Closing connection");
                } catch (IOException e) {
                	log("IOExeption sending message", e);
                }
            }
        }
    }
}

 

 

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!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>Comet Weather</title>
        <SCRIPT TYPE="text/javascript">
            function go(){
                var url = "http://localhost:8080/comet1/Weather";
                var request =  new XMLHttpRequest();
                request.open("GET", url, true);
                request.setRequestHeader("Content-Type","application/x-javascript;");
                request.onreadystatechange = function() {
                    if (request.readyState == 4) {
                        if (request.status == 200){
                            if (request.responseText) {
                                document.getElementById("forecasts").innerHTML = request.responseText;
                            }
                        }else{
                        	document.getElementById("forecasts").innerHTML = "Error!!!!";
                        }
                        //go();
                    }
                };
                request.send(null);
            }
        </SCRIPT>
    </head>
    <body>
        <h1>Rapid Fire Weather</h1>
        <input type="button" onclick="go()" value="Go!"></input>
        <div id="forecasts">
        
        </div>
    </body>
</html>

   

    做如下修改:    

        一、JSP页面中客户端多次调用go(),改为一次,把循环调用go()语句注释掉。

        二、每次request只有一次write,在MessageSender中注释掉 connection = null; 这样保证每次request有多次response。

      

        Tomcat上说明Comet的模型是“BEGIN -> READ -> READ -> READ -> ERROR/TIMEOUT”,这里使用的get请求,不是post请求,没有使用到Read事件。

 

 

分享到:
评论

相关推荐

    tomcat实现comet例子 comet tomcat 随机数

    tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不刷新显示。tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不刷新显示。tomcat实现comet例子,实现后台产生每隔几秒产生随机数,前台不...

    comet框架例子项目

    Comet的核心理念是通过长时间保持一个HTTP连接来实现服务器到客户端的数据推送,而不是每次有新数据时都创建新的连接。这种模式大大减少了网络开销,提高了大规模实时应用的性能。常见的Comet实现技术包括HTTP流、...

    asp.net comet例子

    标题"asp.net comet例子"指的是一个展示如何在ASP.NET环境中实现Comet技术的实际示例。这个例子可能包含了一个服务端页面(Service.aspx和服务.aspx.cs),以及一个客户端的HTML页面(ajax.html)。服务端页面处理与...

    Comet实现聊天室

    Comet实现聊天室 运行时请将Tomcat的server.xml文件内的 connectionTimeout="20000" redirectPort="8443" /&gt; 改为 connectionTimeout="20000" redirectPort="8443" /&gt; 登陆的时候请记得先修改index.jsp...

    comet4j 简单例子+文档

    Comet4j是一个Java框架,专门用于实现Comet技术,这是一种服务器推送技术,允许服务器向客户端实时推送数据,而不仅仅是响应客户端的请求。在Web应用中,这种技术常用于实现聊天、实时通知、股票更新等功能,它克服...

    comet demo 向客户端推送例子

    这个"comet demo"是一个展示如何在Java环境下利用Tomcat服务器实现Comet技术的实例。Tomcat 6.0是Apache软件基金会开发的开源Servlet容器,支持各种Java Web应用的部署,包括Comet技术。 首先,Comet的核心在于保持...

    一个comet应用的小例子

    这是我做的一个comet应用的小例子,使用tomcat 6实现的,例子只能在FireFox上运行,运行时打开两个浏览器就能达到你要的效果了,还要记住把conf/server中的连接类型改为NIO protocol="org.apache.coyote....

    tomcat+comet实现终端与服务端同步的小例子

    总结来说,"Tomcat+Comet实现终端与服务端同步的小例子"是一个学习实时通信和服务器推送技术的好起点。通过这个例子,开发者可以了解如何利用现有Web服务器的特性,创建高效、实时的Web应用。同时,这也是对传统HTTP...

    comet pushlet 例子

    3. **Pushlet**:Pushlet是一个开源的Java库,它是Comet技术的一个实现。Pushlet使用了Servlet API,通过HTTP长连接来实现服务器到客户端的实时数据推送。Pushlet服务器端处理来自客户端的连接,当有新数据可用时,...

    comet的ajax实现

    comet两种实现之一的ajax实现,内部有源代码,这是一个聊天室的例子

    Tomcat 开发Comet实例

    本文将深入探讨如何在Tomcat中开发一个Comet实例,这是一项用于实现服务器向客户端推送数据的技术,对于实时交互应用如聊天、股票更新或天气预报等场景非常关键。 Comet是一种持久连接技术,它打破了传统的HTTP请求...

    用DWR comet+Spring实现服务器推送的例子--网页聊天室

    在这个例子中,我们将学习如何构建一个基于DWR和Comet的网页聊天室,利用Spring来处理业务逻辑和控制流程。首先,我们需要在项目中集成DWR和Spring。这通常包括在`pom.xml`或`build.gradle`文件中添加相应的依赖,...

    comet4j实例

    Comet4j是一个Java库,专门用于实现Comet技术,这是一种服务器推送技术,允许服务器向客户端实时推送数据,而不仅仅是响应客户端的请求。在Web应用中,这种技术常用于实现聊天室、股票报价、在线游戏等实时交互功能...

    javaweb消息推送 基于comet实现局域网内部通讯(聊天室)demo

    javaweb消息推送 基于comet实现局域网内部通讯(聊天室)demo 功能特性 推送消息广播。 推送定向消息。 提供连接上线前、上线、下线前、下线、发送消息等多种可处理事件。 消息缓存机制,确保长轮询工作模式下不丢失...

    comet聊天室,Dojo使用,学习的好例子

    一个comet的实例,使用了dojoJavaScript等

    Spring整合DWR comet 实现无刷新 多人聊天室代码整理

    总之,这个项目展示了如何结合Spring、DWR和Comet技术构建一个实时的多人聊天室。通过这样的实践,开发者可以深入理解Web实时通信的原理,同时掌握前后端分离、异步通信以及服务器推送等现代Web开发的关键技术。

    comet 的http streaming简单实现

    在这个例子中,我们设置了"Content-Type"为"text/event-stream",这样浏览器会知道这是一个Server-Sent Events(SSE)流。我们还设置了"Cache-Control"和"Connection"头来保持连接开放。然后,在一个无限循环中,...

    Servlet3.0 异步处理 页面推送 Comet 实例

    在压缩包文件`CometTest`中,可能包含了一个简单的Comet实现示例,你可以通过学习和运行这个例子来深入理解Servlet3.0异步处理和Comet页面推送的工作原理。通过实践,你可以更好地掌握如何在实际项目中利用这些技术...

    wxv.comet一个comet的应用和demo

    描述中提到的是"服务器推送技术(server push)的一个实现demo",意味着这个项目提供了Comet技术的具体示例,可以帮助开发者理解和学习如何在实际项目中应用Comet。通常,这样的demo会包含代码示例、服务器配置以及...

Global site tag (gtag.js) - Google Analytics