/**
*
*/
package com.chamago.cometserver.connection;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletResponse;
import org.eclipse.jetty.continuation.Continuation;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import com.chamago.cometserver.LinkListQueue;
import com.chamago.cometserver.PullEvent;
import com.chamago.cometserver.StreamConstants;
/**
* @author Gavin.peng
*
* 2014-2-21 下午03:13:51 × cometserver
*/
public class StreamCometConnection extends CometConnection {
private CometConnectionManager connectionManager;
public StreamCometConnection(StreamMsgPullFactory streamMsgPullFactory,CometConnectionManager connectionManager) {
super(streamMsgPullFactory);
this.connectionManager = connectionManager;
}
/*
* (non-Javadoc)
*
* @see
* com.chamago.cometserver.connection.CometConnection#pullMessage(java.lang
* .String)
*/
@Override
void pullMessage(PullEvent event) {
if(event.getCode().equals("100")){
commitTask();
}else if(event.getCode().equals(StreamConstants.HEAT_BEAT)
||event.getCode().equals(StreamConstants.SERVER_DEPLOY)
||event.getCode().equals(StreamConstants.CONNECT_REACH_MAX_TIME)
||this.subs.contains(event.getSubject())){
//先写到redis上
if(event.getCode().equals(StreamConstants.NEW_MESSAGE)){
RedisClientManager rcm = RedisClientManager.getInstance();
rcm.saveMsg(event.getAppkey(), event.getId(), event.toString());
}
this.msgQueue.offer(event);
commitTask();
}else{
LOG.info("连接通道["+this.getAppkey()+"],没有订阅["+event.getSubject()+"]主题事件,忽略该事件");
}
}
/**
*
* @param events
*/
public void batchPullEvent(List<PullEvent> events){
if(events!=null&&events.size()>0){
for(PullEvent pe:events){
if(pe.getCode().equals(StreamConstants.HEAT_BEAT)
||pe.getCode().equals(StreamConstants.SERVER_DEPLOY)
||pe.getCode().equals(StreamConstants.DISCARD_MESSAGE)
||this.subs.contains(pe.getSubject())){
if(pe.getCode().equals(StreamConstants.NEW_MESSAGE)){
RedisClientManager rcm = RedisClientManager.getInstance();
rcm.saveMsg(pe.getAppkey(), pe.getId(), pe.toString());
}
this.msgQueue.offer(pe);
}else{
LOG.info("连接通道["+this.getAppkey()+"],没有订阅["+pe.getSubject()+"]主题事件,忽略该事件");
}
}
commitTask();
}
}
private void commitTask(){
//如果该链接的消息队列没有下发任务,在创建一个rask
if(this.needWorkFlag.compareAndSet(true,false)){
PullTask pt = new PullTask(this);
this.streamMsgPullFactory.commit(pt);
}
}
public class PullTask implements Runnable {
private CometConnection connect;
public PullTask(CometConnection connect) {
this.connect = connect;
}
//@Override
public void run() {
ServletResponse resp = this.connect.getResponse();
while(this.connect.msgQueue.size()>0){
PullEvent msg = null;
try {
msg = this.connect.msgQueue.take();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if(LOG.isDebugEnabled()){
LOG.debug("向连接通道下发消息:"+msg.toString());
}
ServletOutputStream os = null;
try {
os = resp.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
os.write(msg.toString().getBytes());
os.flush();
} catch (Exception e) {
LOG.warn("客户端连接["+this.connect.getAppkey()+"]出现异常,需要关闭该连接");
//标记该链接通道上没有消息要发送。
this.connect.msgQueue.clear();
this.connect.needWorkFlag.compareAndSet(false,true);
this.connect.closeConnection();
e.printStackTrace();
break;
}
this.connect.setActiveTime(System.currentTimeMillis());
}
//标记该链接通道上没有消息要发送。
this.connect.needWorkFlag.compareAndSet(false,true);
//通知关闭长连接的线程
synchronized(this.connect){
this.connect.notifyAll();
}
}
}
@Override
void clean() {
this.msgQueue = null;
this.subs.clear();
this.subs = null;
Continuation continuation = this.getContinuation();
//释放掉该链接的资源,关闭response
continuation.complete();
this.connectionManager.closeCometConnection(this.getAppkey());
LOG.info("客户端连接["+this.getAppkey()+"]关闭,释放系统资源");
synchronized(this.connectionManager){
if(this.connectionManager.getConnectSize()<=0&&!this.connectionManager.isContainExit()){
LOG.info("所有链接已经成功关闭,通知容器退出");
this.connectionManager.setContainExit(true);
this.connectionManager.notifyAll();
}
}
}
}