首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

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

2012-10-28 
IBM的一个Comet实现例子的问题源地址链接: http://www.ibm.com/developerworks/cn/web/wa-cometjava/?impo

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

源地址链接: 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事件。

?

?

热点排行