/** * */ package com.chamago.cometserver.connection; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.jetty.continuation.Continuation; import com.chamago.cometserver.LinkListQueue; import com.chamago.cometserver.PullEvent; import com.chamago.cometserver.StreamConstants; import com.chamago.cometserver.connection.StreamCometConnection.PullTask; /** * @author Gavin.peng * * 2014-2-21 下午02:51:54 × cometserver */ public abstract class CometConnection { protected final static Log LOG = LogFactory .getLog(CometConnection.class); private String appkey; private String secret; //相当于主题,有ORDER,ITEM 等 private String connectId; //目前暂时不用 private String groupId;// //连接维持的时间,单位秒 private long connectionTime; //待推送消息队列 protected LinkListQueue<PullEvent> msgQueue; protected Set<String> subs; //标记该链接的消息队列是否有工作线程在下发消息 true 标示没有,false标示有 protected AtomicBoolean needWorkFlag = new AtomicBoolean(true); private Long activeTime; protected Continuation continuation; private HttpServletResponse response; private HttpServletRequest request; protected StreamMsgPullFactory streamMsgPullFactory; public CometConnection(StreamMsgPullFactory streamMsgPullFactory){ this.streamMsgPullFactory = streamMsgPullFactory; this.connectionTime = System.currentTimeMillis(); this.msgQueue = new LinkListQueue<PullEvent>(); this.subs = new HashSet<String>(5); this.activeTime = System.currentTimeMillis(); } public String getAppkey() { return appkey; } public void setAppkey(String appkey) { this.appkey = appkey; } public String getSecret() { return secret; } public void setSecret(String secret) { this.secret = secret; } public String getConnectId() { return connectId; } public void setConnectId(String connectId) { this.connectId = connectId; } public String getGroupId() { return groupId; } public void setGroupId(String groupId) { this.groupId = groupId; } public void addSubject(String subject){ this.subs.add(subject); } public long getConnectionTime() { return connectionTime; } public void setConnectionTime(long connectionTime) { this.connectionTime = connectionTime; } public LinkListQueue<PullEvent> getMsgQueue() { return msgQueue; } public void setMsgQueue(LinkListQueue<PullEvent> msgQueue) { this.msgQueue = msgQueue; } public Continuation getContinuation() { return continuation; } public void setContinuation(Continuation continuation) { this.continuation = continuation; } public HttpServletResponse getResponse() { return response; } public void setResponse(HttpServletResponse response) { this.response = response; } public HttpServletRequest getRequest() { return request; } public void setRequest(HttpServletRequest request) { this.request = request; } /** * 业务推送消息入口 * @param msg */ abstract void pullMessage(PullEvent event); public void holdingConnection(HttpServletResponse response,HttpServletRequest request){ Continuation contin = this.getContinuation(); this.response = response; this.request = request; contin.suspend(response); } /** * 关闭连接 */ public void closeConnection(){ //说明该链接通道正在下发数据,需要挂取该线程,。 if(!this.needWorkFlag.get()||(this.needWorkFlag.get()&&this.msgQueue.size()>0)){ LOG.info("连接["+this.getAppkey()+"]还有下发线程在工作,或者链接下发队列还有消息需要发送,需要等待发送完"); final CometConnection curcon = this; //这里异步是为了防止挂起管理连接的线程。 new Thread(new Runnable(){ @Override public void run() { if(!curcon.needWorkFlag.get()){ synchronized(curcon){ try { curcon.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } }else if(curcon.needWorkFlag.get()&&curcon.msgQueue.size()>0){ PullEvent sysEvent = new PullEvent(curcon.appkey,"100",null,null); curcon.pullMessage(sysEvent); synchronized(curcon){ try { curcon.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } clean(); } }).start(); }else{ clean(); } } abstract void clean(); public long getActiveTime() { return activeTime; } public void setActiveTime(Long activeTime) { this.activeTime = activeTime; } }