package com.ll.smsbeans;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
import java.util.logging.Logger;
import com.ll.smsbeans.cmpp3.CmppActiveTestBuilder;
import com.ll.smsbeans.cmpp3.CmppActiveTestRespBuilder;
import com.ll.smsbeans.cmpp3.CmppConnectBuilder;
import com.ll.smsbeans.cmpp3.CmppConnectResp;
import com.ll.smsbeans.cmpp3.CmppPacket;
import com.ll.smsbeans.cmpp3.CmppPacketCommon;
import com.ll.smsbeans.cmpp3.CmppTerminateBuilder;
import com.ll.smsbeans.cmpp3.CmppTerminateRespBuilder;
import com.ll.smsbeans.log.LogCommon;
/**
* ConnectionBean 是smsbeans中主要的bean.
* <p>
* ConnectionBean 主要是和服务器建立认证连接,所有其它的bean都是通过它和服务器通信的。
* <p>
* ConnectionBean提供一些“标准”的于服务器通信的接口,例如send方法,同时在内部自动处理一些服务
* 器端的消息的回服例如ActiveTest等,并且,在运行过程中处理数据包的发送失败,保持链路联结。
* <p>
* 所有其它的beans通过ConnectionBean发送数据,和通过监听由ConnectionBean发布的received消息接收过滤数据
* <p>
* @see MessengerBean
* @see IQBean
* @see RosterBean
*
*
* @author listlike <a href="mailto:listlike@hotmail.com">
* <i><listlike@hotmail.com></i></a>
* @version $Revision: 1.0 $
*/
public class ConnectionBean implements Serializable, PacketListenerRegistrar
{
/**
*
* Timer为定时器类
* 为ConnectBean提供定时服务,通过定时调用 主要用于回复包的时间记数,以及保持链路测试包的定时发送。
* 有两个定时器:
* 1 秒定时器
* 用于回复包的时间记数,每秒激活一次ConnectionBean.onTimer.
* 2 保持链路测试包定时器
* 用于保持链路测试包的记时,根据常数ACTIVETIME的值激活ConnectBeantion.onActiveConnect。
*
* @see com.ll.smsbeans.ConnectionBean#onTimer()
* @see ConnectionBean#onActiveConnect()
* @see ConnectionBean#ACTIVETIME
*<p>
* @author listlike <a href="mailto:listlike@hotmail.com">
* <i><listlike@hotmail.com></i></a>
*
*/
public class Timer extends Thread
{
// 保持链路测试包的记时
private long activeSec = 0;
//定时器是否有效
private boolean enableTimer = true;
//保持链路测试的定时器是否有效
private boolean enableActiveTimer = true;
private boolean timerRun = true;
/**
* 保持链路测试的定时器复位
*/
public void resetActiveTime()
{
activeSec = System.currentTimeMillis();
}
/**
* @see java.lang.Runnable#run()
*/
public void run()
{
while (timerRun)
{
try
{
sleep(1000);
if (enableTimer)
ConnectionBean.this.onTimer();
if (System.currentTimeMillis() - activeSec
>= ACTIVETIME * 1000)
{
resetActiveTime();
if (enableActiveTimer)
ConnectionBean.this.onActiveConnect();
}
} catch (InterruptedException e)
{
return;
} catch (Exception e)
{
return;
}
}
}
/**
* 定时器状态
* @return 定时器状态
*/
public boolean isEnableActiveTimer()
{
return enableActiveTimer;
}
/**
* 保持链路测试的定时器状态
* @return 保持链路测试的定时器状态
*/
public boolean isEnableTimer()
{
return enableTimer;
}
/**
* 设置保持链路测试的定时器状态
* @param enable 设置保持链路测试的定时器状态
*/
public void setEnableActiveTimer(boolean enable)
{
enableActiveTimer = enable;
}
/**
* 设置定时器状态
* @param enable 设置定时器状态
*/
public void setEnableTimer(boolean enable)
{
enableTimer = enable;
}
/* (非 Javadoc)
* @see java.lang.Thread#interrupt()
*/
public void interrupt()
{
timerRun = false;
super.interrupt();
}
/* (非 Javadoc)
* @see java.lang.Thread#start()
*/
public synchronized void start()
{
reset();
super.start();
}
private void reset()
{
enableTimer = true;
enableActiveTimer = true;
timerRun = true;
resetActiveTime();
}
}
/**
*PacketStreamMonitor 通过响应数据报发送和接收事件,维护ConnectionBean的连接。
*
*
* @author listlike <a href="mailto:listlike@hotmail.com">
* <i><listlike@hotmail.com></i></a>
*
*/
public class PacketStreamMonitor implements PacketListener
{
/**
* 主要工作:
* 1、 将接收到的回复包从发送队列移出。
* 2、 判断是否登陆成功。
* 3、 自动处理中断包和中断回复包。
* 4、 处理链路测试包。
* @see com.ll.smsbeans.PacketListener#receivedPacket(com.ll.smsbeans.PacketEvent)
*/
public void receivedPacket(PacketEvent pe)
{
_log.info(pe.getPacket().toString());
if (((CmppPacket) pe.getPacket()).isResponse())
{
SendPacketState sps = sendPacketList.get(pe.getPacket());
if (sps != null)
{
sps.setState(SendPacketState.STATE_RESPONSED);
sps.setRespPacket(pe.getPacket());
}
//sendPacketList.remove( pe.getPacket());
}
if (status.getValue() == ConnectionEvent.EState.CONNECTING)
{
Packet p = pe.getPacket();
if (p != null)
{
if (p instanceof CmppPacket)
{
CmppPacket cp = (CmppPacket) p;
if (cp.getCommandId()
== CmppPacketCommon.ID_CMPP_CONNECT_RESP)
// 0x80000001
{
sendPacketList.remove(cp);
CmppConnectResp ccr = (CmppConnectResp) cp;
if (ccr.getStatus() == 0)
{
setConnectionState(
ConnectionEvent.STATE_CONNECTED,
ConnectionEvent.REASON_CLIENT_INITIATED);
mTimer = new Timer();
mTimer.start();
} else
{
disconnected(
ConnectionEvent.REASON_SERVER_INITIATED);
}
}
}
}
return;
}
if (status.getValue() == ConnectionEvent.EState.CONNECTED)
{
Packet p = pe.getPacket();
if (p != null)
{
if (p instanceof CmppPacket)
{
CmppPacket cp = (CmppPacket) p;
switch (cp.getCommandId())
{
case CmppPacketCommon.ID_CMPP_TERMINATE_RESP :
//0x80000002
sendPacketList.remove(pe.getPacket());
disconnected(
ConnectionEvent.REASON_CLIENT_INITIATED);
break;
case CmppPacketCommon.ID_CMPP_TERMINATE :
//0x00000002
CmppTerminateRespBuilder ctrb =
new CmppTerminateRespBuilder();
ctrb.setSequenceId(cp.getSequenceId());
send(ctrb.builder());
break;
case CmppPacketCommon.ID_CMPP_ACTIVE_TEST :
//0x00000008
CmppActiveTestRespBuilder catrb =
new CmppActiveTestRespBuilder();
catrb.setSequenceId(cp.getSequenceId());
send(catrb.builder());
mTimer.resetActiveTime();
break;
case CmppPacketCommon.ID_CMPP_ACTIVE_TEST_RESP :
//0x80000008
sendPacketList.remove(cp);
break;
default :
break;
}
}
}
}
_log.log(
LogCommon.DEBUG_LEVEL,
"sendPacketList=" + sendPacketList.size());
}
/**
* 主要工作:处理服务器端发送来的中断包。
*
* @see com.ll.smsbeans.PacketListener#sentPacket(com.ll.smsbeans.PacketEvent)
*/
public void sentPacket(PacketEvent pe)
{
_log.info(pe.getPacket().toString());
if (status.getValue() == ConnectionEvent.EState.CONNECTED)
{
Packet p = pe.getPacket();
if (p != null)
{
if (p instanceof CmppPacket)
{
CmppPacket cp = (CmppPacket) p;
if (cp.getCommandId()
== CmppPacketCommon.ID_CMPP_TERMINATE_RESP)
//0x80000002
disconnected(
ConnectionEvent.REASON_SERVER_INITIATED);
}
}
}
}