?? agentcrbtnetconnecthandler.java
字號:
/**
* AgentCrbtNetConnectHandler.java
* @版權(quán): Copyright (C) 2007
* @公司:北京漢銘信通科技有限公司
* @url: www.aceway.com.cn
*/
package com.aceway.vas.xjcrgw.ws.handler;
import com.aceway.vas.commons.tcp.TcpClient;
import com.aceway.vas.commons.tcp.Util;
import com.aceway.vas.commons.util.logger.AcewayLogger;
import com.aceway.vas.sjcraw.cbgp201.Msg;
import com.aceway.vas.sjcraw.cbgp201.MsgBindRc;
import com.aceway.vas.sjcraw.cbgp201.MsgBindRcRsp;
import com.aceway.vas.sjcraw.cbgp201.MsgBindSr;
import com.aceway.vas.sjcraw.cbgp201.MsgBindSrRsp;
import com.aceway.vas.sjcraw.cbgp201.MsgEnquireLink;
import com.aceway.vas.sjcraw.cbgp201.MsgHead;
import com.aceway.vas.sjcraw.cbgp201.common.ConfigFileOper;
import com.aceway.vas.sjcraw.cbgp201.common.Md5Check;
import com.aceway.vas.sjcraw.cbgp201.common.MsgInfo;
/**
* 此類是 CRBT_AGENT 模塊處理與華為彩鈴平臺通訊相關(guān)的網(wǎng)絡(luò)連接類 模塊CBGP請求/應(yīng)答的通訊模型,此類定時(shí)負(fù)責(zé)發(fā)送鏈路檢測包以維護(hù)網(wǎng)絡(luò)的正常連接
* CBGP協(xié)議采用請求/應(yīng)答的通訊模型實(shí)現(xiàn)。通信雙方以客戶-服務(wù)器方式建立TCP連接,用于雙方信息的相互提交。當(dāng)信道上沒有數(shù)據(jù)傳輸時(shí),通信雙方應(yīng)每隔時(shí)間C發(fā)送鏈路檢測包以維持此連接,當(dāng)鏈路檢測包發(fā)出超過時(shí)間T后未收到響應(yīng),應(yīng)立即再發(fā)送鏈路檢測包,再連續(xù)發(fā)送N-1次后仍未得到響應(yīng)則斷開此連接。
* 參數(shù)C、T、N原則上應(yīng)可配置,現(xiàn)階段建議取值為:C=3分鐘,T=60秒,N=3。
* 通信雙方之間的消息如果不能成功發(fā)送,應(yīng)隔時(shí)間R進(jìn)行重發(fā),再連續(xù)發(fā)送N-1次后仍未發(fā)送成功則停發(fā)。現(xiàn)階段建議取值為:R=60秒,N=3。
* 通信雙方采用一問一答的通訊機(jī)制,即一次請求對應(yīng)于一次應(yīng)答。
* 通信雙方之間的消息發(fā)送后等待T秒后未收到響應(yīng),應(yīng)立即重發(fā),再連續(xù)發(fā)送N-1次后仍未得到響應(yīng)則停發(fā)。現(xiàn)階段建議取值為:T=60秒,N=3。
* 消息采用并發(fā)方式發(fā)送,加以滑動(dòng)窗口流量控制,窗口大小參數(shù)W可配置,現(xiàn)階段建議為16,即接收方在應(yīng)答前一次收到的消息最多不超過16條。
*
* @see MsgReceiveAdapter.java
* @author zhou tao
*/
public class AgentCrbtNetConnectHandler extends MsgReceiveAdapter {
/**
* 唯一實(shí)例
*/
private static AgentCrbtNetConnectHandler netConnHandler = new AgentCrbtNetConnectHandler();
private AcewayLogger acewayLogger = (AcewayLogger) AcewayLogger
.getLogger("CrbtAgentLogger");
/**
* 通信鏈路檢測內(nèi)部類對象
*/
private EnquireLinkThread enquireLinkThread;
/**
* 連接允許標(biāo)志
*/
private static boolean isConnRun;
/**
* TCP客戶端實(shí)例
*/
private TcpClient tcpClient = Util.getClient();
/**
* seqno獲取
*/
private AgentCrbtWSHandler agentCrbtWSHander = AgentCrbtWSHandler
.getInstance();
/**
*
*/
private AgentCrbtNetConnectHandler() {
enquireLinkThread = new EnquireLinkThread();
}
public static AgentCrbtNetConnectHandler getInstance() {
return netConnHandler;
}
/**
* 接收連接已建立消息,再與華為彩鈴平臺建立連接后,發(fā)送綁定認(rèn)證消息
* 綁定操作是通信的雙方在建立連接后,其中一方向?qū)Ψ桨l(fā)起的認(rèn)證過程。通過認(rèn)證,認(rèn)證方可以確信對方的身份并給予相應(yīng)的權(quán)利
*
* @param ip
* @param port
*/
public void receiveonConnectedMsg(String ip, int port) {
acewayLogger.info("連接已建立");
isConnRun = true; // 已建立連接
acewayLogger.info("開始綁定認(rèn)證過程,第一步:發(fā)送CRBT_bind_rc請求!");
String seqNo = agentCrbtWSHander.genSeqNo() + "";
String linkId = agentCrbtWSHander.genLinkId() + "";
int authMethod = 0x01;// 綁定采用的認(rèn)證方法MD5
int version = 0x02;// CRBT協(xié)議的版本號
Msg msgBindRc = new MsgBindRc(seqNo, linkId, authMethod, version);
int result = tcpClient.send(msgBindRc.getMsg());
if (result != 0) {
acewayLogger.error("第一步認(rèn)證請求CRBT_bind_rc發(fā)送失敗,即斷開連接!");
tcpClient.disconnect();
}
}
/**
* 接收連接已斷開消息
*/
public void receiveonDisConnectedMsg() {
acewayLogger.info("連接已斷開");
isConnRun = false;
}
/**
* 接收網(wǎng)絡(luò)連接請求消息
*/
public void receiveNetConnReqMsg(byte[] msg) {
MsgHead msghead = new MsgHead(msg);
int opCode = msghead.getOpcode();
if (opCode == 0x0202) {// 查詢連接請求
// 回送查詢連接響應(yīng)
msghead.setSubCommand(MsgInfo.SUB_COMMAND_RESPONSE);
tcpClient.send(msghead.getHeadBuffer().array());
} else if (opCode == 0x0401) {// 解除綁定請求
// 回送取消綁定響應(yīng)
msghead.setSubCommand(MsgInfo.SUB_COMMAND_RESPONSE);
tcpClient.send(msghead.getHeadBuffer().array());
tcpClient.disconnect();
}
}
/**
* 接收網(wǎng)絡(luò)連接請求應(yīng)答消息
*/
public void receiveNetConnRespMsg(byte[] msg) {
MsgHead msghead = new MsgHead(msg);
int opCode = msghead.getOpcode();
if (opCode == 0x0201) {// 通用錯(cuò)誤請求應(yīng)答
String commandStatus = msghead.getCommandStatus();
acewayLogger.error("通用錯(cuò)誤請求應(yīng)答,請檢查消息格式!commandStatus == "
+ commandStatus);
} else if (opCode == 0x0101) {// 綁定-隨機(jī)數(shù)CRBT_bind_rc_rsp應(yīng)答
acewayLogger.info("綁定認(rèn)證過程,第二步:接收CRBT_bind_rc_rsp響應(yīng)!");
MsgBindRcRsp msgBindRcResp = new MsgBindRcRsp(msg);
String commandStatus = msgBindRcResp.getMsgHead()
.getCommandStatus();
if (commandStatus.equals("0000")) {
acewayLogger.info("綁定認(rèn)證過程,第三步:發(fā)送CRBT_bind_sr請求!");
// MD5對隨機(jī)數(shù)加密
Md5Check md5t = new Md5Check();
String response = md5t.MD5(ConfigFileOper.getProperty("COM_PASSWORD") + msgBindRcResp.getRandom());
String seqNo = agentCrbtWSHander.genSeqNo() + "";
String linkId = agentCrbtWSHander.genLinkId() + "";
MsgBindSr msgBindSr = new MsgBindSr(seqNo, linkId, "client_id", response.length(), response);
int result = tcpClient.send(msgBindSr.getMsg());
if (result != 0) {
acewayLogger.error("第三步認(rèn)證請求CRBT_bind_sr發(fā)送失敗,即斷開連接!");
tcpClient.disconnect();
}
} else {
acewayLogger.info("綁定認(rèn)證過程,第二步:接收CRBT_bind_rc_rsp響應(yīng)失敗,即斷開連接!"
+ "失敗原因:" + ConfigFileOper.getProperty(commandStatus));
tcpClient.disconnect();
}
} else if (opCode == 0x0401) {// 取消綁定操作應(yīng)答
acewayLogger.info("接受到取消綁定應(yīng)答CRBT_unbind_rsp!");
tcpClient.disconnect();
} else if (opCode == 0x0103) {// 綁定-隨機(jī)數(shù)CRBT_bind_sr_rsp應(yīng)答
acewayLogger.info("綁定認(rèn)證過程,第四步:接收CRBT_bind_sr_rsp響應(yīng)!");
MsgBindSrRsp msgBindRcResp = new MsgBindSrRsp(msg);
String commandStatus = msgBindRcResp.getMsgHead()
.getCommandStatus();
if (commandStatus.equals("0000")) {
acewayLogger.info("綁定認(rèn)證過程成功,準(zhǔn)備發(fā)送業(yè)務(wù)請求,開始通信鏈路檢測");
enquireLinkThread.start();
} else {
acewayLogger.info("綁定認(rèn)證過程,第四步:接收CRBT_bind_sr_rsp響應(yīng)失敗,即斷開連接!"
+ "失敗原因:" + ConfigFileOper.getProperty(commandStatus));
tcpClient.disconnect();
}
}
}
/**
* 接收消息已發(fā)送消息
*
* @param msg
*/
public void receiveOnSendMsg(byte[] msg) {
}
/**
* 鏈路檢測線程,定時(shí)檢測信道上得數(shù)據(jù)傳輸 EnquireLinkThread.java
*
*/
class EnquireLinkThread extends Thread {
public void run() {
while (isConnRun) {
long currentTime = System.currentTimeMillis();
// 三分鐘沒有數(shù)據(jù)數(shù)據(jù)傳輸了
if ((currentTime - AgentCrbtClientHandler
.getLastDataTransTime()) >= MsgInfo.checkInterval * 60 * 1000) {
for (int i = 0; i < MsgInfo.checkDegree; i++) {
sendLinkSendMsg();
long temp = AgentCrbtClientHandler
.getLastDataTransTime();
try {
super.sleep(MsgInfo.checkWait * 60 * 1000);
} catch (Exception e) {
e.printStackTrace();
}
// 一分鐘后沒有收到響應(yīng),重發(fā)
if (temp == AgentCrbtClientHandler
.getLastDataTransTime()) {
if (i == MsgInfo.checkDegree - 1) {// 最后一次發(fā)送后還是沒有收到任何響應(yīng),斷開與服務(wù)器連接
boolean isDisConnSuccess = tcpClient.disconnect();
if (!isDisConnSuccess) {
} else {
isConnRun = false;
}
} else {
continue;
}
} else {
break;
}
}
}
}
}
public void sendLinkSendMsg() {
String seqNo = agentCrbtWSHander.genSeqNo() + "";
String linkId = agentCrbtWSHander.genLinkId() + "";
Msg msgEnquireLink = new MsgEnquireLink(seqNo, linkId);
// 發(fā)送鏈路檢測包
tcpClient.send(msgEnquireLink.getMsg());
}
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -