读书人

基于AJAX的长轮询(long-polling)模式实

发布时间: 2012-11-20 09:55:43 作者: rapoo

基于AJAX的长轮询(long-polling)方式实现COMET例子

public class TestComet extends HttpServlet implements CometProcessor {private static final long serialVersionUID = 1L;// 发送器private MessageSender messageSender = null;private static final Integer TIMEOUT = 60 * 1000;@Overridepublic void destroy() {messageSender.stop();messageSender = null;}@Overridepublic void init() throws ServletException {System.out.println("--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 {System.out.println("--event-----------------");// 获取事件对应的REQUEST 和 RESPONSEHttpServletRequest 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());// 注入RESPONSEmessageSender.setConnection(response);Weatherman weatherman = new Weatherman(messageSender, 95118, 32408);new Thread(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");}}}

?信息发送器:

public class MessageSender implements Runnable {// 标志位protected boolean running = true;// 信息列表protected final ArrayList<String> messages = new ArrayList<String>();// HTTP RESPONSEprivate ServletResponse connection;// 注入HTTP RESPONSEpublic synchronized void setConnection(ServletResponse connection) {this.connection = connection;notify();}// 发送信息public void send(String message) {// 同步队列,加入发送信息synchronized (messages) {messages.add(message);log("Message added #messages=" + messages.size());// 唤醒messages.notify();}}public void run() {// 线程启动log("start");while (running) {if (messages.size() == 0) {try {synchronized (messages) {log("MessageSender wait[空闲状态,线程等待]");// 释放锁messages.wait();}} catch (InterruptedException e) {e.printStackTrace();// Ignore}}String[] pendingMessages = null;synchronized (messages) {// 导出发送的信息至数组pendingMessages = messages.toArray(new String[0]);// 清空信息队列messages.clear();}try {if (connection == null) {try {synchronized (this) {// 等待注入HTTP RESPONSEwait();}} catch (InterruptedException e) {// Ignoree.printStackTrace();}}// 输出流操作OutputStream out = connection.getOutputStream();for (int j = 0; j < pendingMessages.length; j++) {final String forecast = pendingMessages[j] + "<br>";out.write(forecast.getBytes());out.flush();connection.flushBuffer();log("Writing[写入]:" + forecast);}} catch (IOException e) {log("IOExeption sending message", e);}}}// 停止public void stop() {running = false;}// 日志private void log(Object obj) {System.out.println(obj);}// 日志private void log(Object obj, Throwable e) {System.out.println(obj);e.printStackTrace();}}

?YAHOO天气预报:

public class Weatherman implements Runnable {// 链接列表private final List<URL> zipCodes;// YAHOO WEATHERprivate final String YAHOO_WEATHER = "http://weather.yahooapis.com/forecastrss?p=";// 发送器private MessageSender messageSender;public Weatherman(MessageSender messageSender, Integer... zips) {this.messageSender = messageSender;zipCodes = new ArrayList<URL>(zips.length);for (Integer zip : zips) {try {// 添加具体链接zipCodes.add(new URL(YAHOO_WEATHER + zip));} catch (Exception e) {e.printStackTrace();}}}public void run() {System.out.println("Weatherman 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(10000L);} catch (Exception e) {e.printStackTrace();}i++;}}// 格式转换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();}}

?WEB.XML配置:

<servlet>    <description>TestComet</description>    <display-name>TestComet</display-name>    <servlet-name>TestComet</servlet-name>    <servlet-class>cn.test.TestComet</servlet-class></servlet><servlet-mapping>    <servlet-name>TestComet</servlet-name>    <url-pattern>/TestComet</url-pattern></servlet-mapping>

?TOMCAT配置,NIO

<Connector connectionTimeout="20000" port="8888" protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8443"/>


?


?


?基于AJAX的长轮询(long-polling)模式实现COMET例子

2 楼 zhdalong 2011-12-30 public void event(final CometEvent event) throws IOException,
ServletException { }

什么时候调用

读书人网 >Ajax

热点推荐