/** * Copyright (c)2010-2011 Enterprise Website Content Management System(EWCMS), All rights reserved. * EWCMS PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * http://www.ewcms.com */ package com.ewcms.web.pubsub; import java.io.IOException; import java.io.PrintWriter; import java.lang.InterruptedException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * 推送信息到客户端 * * @author wangwei */ public abstract class PubsubSender implements PubsubSenderable{ private static final Logger logger = LoggerFactory.getLogger(PubsubSender.class); protected final String path; protected final ServletContext context; private final List<HttpServletResponse> connections =Collections.synchronizedList(new ArrayList<HttpServletResponse>()); private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); private Boolean alreadyStart = Boolean.FALSE; private long initialDelay = 5; private long delay = 15; public PubsubSender(String path,ServletContext context) { this.path = path; this.context = context; init(path,context); } protected abstract void init(String path,ServletContext context); @Override public void addClient(HttpServletResponse connection){ synchronized(connections){ connections.add(connection); String out ="<html><head></head><body>" + constructFirstOutput(); render(out,connection); connections.notifyAll(); } } /** * 第一次推送内容 * * @return */ protected String constructFirstOutput(){ return constructOutput(); } @Override public void removeClient(HttpServletResponse connection){ synchronized(connections){ if(connections.contains(connection)){ String out ="</body></html>"; render(out,connection); connections.remove(connection); } } } @Override public void setInitialDelay(long initialDelay) { this.initialDelay = initialDelay; } @Override public void setDelay(long delay) { this.delay = delay; } @Override public void start() { synchronized(alreadyStart){ if(alreadyStart){ return; } executor.scheduleWithFixedDelay(new Runnable(){ @Override public void run() { synchronized (connections) { try{ if(connections.isEmpty()){ connections.wait() ; } }catch(InterruptedException e){ logger.error("Running wait error:{}",e); } String out = constructOutput(); logger.debug("Output :{}",out); for (HttpServletResponse connection : connections) { render(out,connection); } } } }, initialDelay , delay , TimeUnit.SECONDS); alreadyStart = Boolean.TRUE; } } private void render(String m,HttpServletResponse response){ try { PrintWriter writer = response.getWriter(); writer.println(m); writer.flush(); } catch (IOException e) { logger.error(e.toString()); } } /** * 构造输出内容 * * @return */ protected abstract String constructOutput(); }