📄 agentcrbtnetconnecthandler.java
字号:
/**
* AgentCrbtNetConnectHandler.java
* @版权: 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 模块处理与华为彩铃平台通讯相关的网络连接类 模块CBGP请求/应答的通讯模型,此类定时负责发送链路检测包以维护网络的正常连接
* CBGP协议采用请求/应答的通讯模型实现。通信双方以客户-服务器方式建立TCP连接,用于双方信息的相互提交。当信道上没有数据传输时,通信双方应每隔时间C发送链路检测包以维持此连接,当链路检测包发出超过时间T后未收到响应,应立即再发送链路检测包,再连续发送N-1次后仍未得到响应则断开此连接。
* 参数C、T、N原则上应可配置,现阶段建议取值为:C=3分钟,T=60秒,N=3。
* 通信双方之间的消息如果不能成功发送,应隔时间R进行重发,再连续发送N-1次后仍未发送成功则停发。现阶段建议取值为:R=60秒,N=3。
* 通信双方采用一问一答的通讯机制,即一次请求对应于一次应答。
* 通信双方之间的消息发送后等待T秒后未收到响应,应立即重发,再连续发送N-1次后仍未得到响应则停发。现阶段建议取值为:T=60秒,N=3。
* 消息采用并发方式发送,加以滑动窗口流量控制,窗口大小参数W可配置,现阶段建议为16,即接收方在应答前一次收到的消息最多不超过16条。
*
* @see MsgReceiveAdapter.java
* @author zhou tao
*/
public class AgentCrbtNetConnectHandler extends MsgReceiveAdapter {
/**
* 唯一实例
*/
private static AgentCrbtNetConnectHandler netConnHandler = new AgentCrbtNetConnectHandler();
private AcewayLogger acewayLogger = (AcewayLogger) AcewayLogger
.getLogger("CrbtAgentLogger");
/**
* 通信链路检测内部类对象
*/
private EnquireLinkThread enquireLinkThread;
/**
* 连接允许标志
*/
private static boolean isConnRun;
/**
* TCP客户端实例
*/
private TcpClient tcpClient = Util.getClient();
/**
* seqno获取
*/
private AgentCrbtWSHandler agentCrbtWSHander = AgentCrbtWSHandler
.getInstance();
/**
*
*/
private AgentCrbtNetConnectHandler() {
enquireLinkThread = new EnquireLinkThread();
}
public static AgentCrbtNetConnectHandler getInstance() {
return netConnHandler;
}
/**
* 接收连接已建立消息,再与华为彩铃平台建立连接后,发送绑定认证消息
* 绑定操作是通信的双方在建立连接后,其中一方向对方发起的认证过程。通过认证,认证方可以确信对方的身份并给予相应的权利
*
* @param ip
* @param port
*/
public void receiveonConnectedMsg(String ip, int port) {
acewayLogger.info("连接已建立");
isConnRun = true; // 已建立连接
acewayLogger.info("开始绑定认证过程,第一步:发送CRBT_bind_rc请求!");
String seqNo = agentCrbtWSHander.genSeqNo() + "";
String linkId = agentCrbtWSHander.genLinkId() + "";
int authMethod = 0x01;// 绑定采用的认证方法MD5
int version = 0x02;// CRBT协议的版本号
Msg msgBindRc = new MsgBindRc(seqNo, linkId, authMethod, version);
int result = tcpClient.send(msgBindRc.getMsg());
if (result != 0) {
acewayLogger.error("第一步认证请求CRBT_bind_rc发送失败,即断开连接!");
tcpClient.disconnect();
}
}
/**
* 接收连接已断开消息
*/
public void receiveonDisConnectedMsg() {
acewayLogger.info("连接已断开");
isConnRun = false;
}
/**
* 接收网络连接请求消息
*/
public void receiveNetConnReqMsg(byte[] msg) {
MsgHead msghead = new MsgHead(msg);
int opCode = msghead.getOpcode();
if (opCode == 0x0202) {// 查询连接请求
// 回送查询连接响应
msghead.setSubCommand(MsgInfo.SUB_COMMAND_RESPONSE);
tcpClient.send(msghead.getHeadBuffer().array());
} else if (opCode == 0x0401) {// 解除绑定请求
// 回送取消绑定响应
msghead.setSubCommand(MsgInfo.SUB_COMMAND_RESPONSE);
tcpClient.send(msghead.getHeadBuffer().array());
tcpClient.disconnect();
}
}
/**
* 接收网络连接请求应答消息
*/
public void receiveNetConnRespMsg(byte[] msg) {
MsgHead msghead = new MsgHead(msg);
int opCode = msghead.getOpcode();
if (opCode == 0x0201) {// 通用错误请求应答
String commandStatus = msghead.getCommandStatus();
acewayLogger.error("通用错误请求应答,请检查消息格式!commandStatus == "
+ commandStatus);
} else if (opCode == 0x0101) {// 绑定-随机数CRBT_bind_rc_rsp应答
acewayLogger.info("绑定认证过程,第二步:接收CRBT_bind_rc_rsp响应!");
MsgBindRcRsp msgBindRcResp = new MsgBindRcRsp(msg);
String commandStatus = msgBindRcResp.getMsgHead()
.getCommandStatus();
if (commandStatus.equals("0000")) {
acewayLogger.info("绑定认证过程,第三步:发送CRBT_bind_sr请求!");
// MD5对随机数加密
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("第三步认证请求CRBT_bind_sr发送失败,即断开连接!");
tcpClient.disconnect();
}
} else {
acewayLogger.info("绑定认证过程,第二步:接收CRBT_bind_rc_rsp响应失败,即断开连接!"
+ "失败原因:" + ConfigFileOper.getProperty(commandStatus));
tcpClient.disconnect();
}
} else if (opCode == 0x0401) {// 取消绑定操作应答
acewayLogger.info("接受到取消绑定应答CRBT_unbind_rsp!");
tcpClient.disconnect();
} else if (opCode == 0x0103) {// 绑定-随机数CRBT_bind_sr_rsp应答
acewayLogger.info("绑定认证过程,第四步:接收CRBT_bind_sr_rsp响应!");
MsgBindSrRsp msgBindRcResp = new MsgBindSrRsp(msg);
String commandStatus = msgBindRcResp.getMsgHead()
.getCommandStatus();
if (commandStatus.equals("0000")) {
acewayLogger.info("绑定认证过程成功,准备发送业务请求,开始通信链路检测");
enquireLinkThread.start();
} else {
acewayLogger.info("绑定认证过程,第四步:接收CRBT_bind_sr_rsp响应失败,即断开连接!"
+ "失败原因:" + ConfigFileOper.getProperty(commandStatus));
tcpClient.disconnect();
}
}
}
/**
* 接收消息已发送消息
*
* @param msg
*/
public void receiveOnSendMsg(byte[] msg) {
}
/**
* 链路检测线程,定时检测信道上得数据传输 EnquireLinkThread.java
*
*/
class EnquireLinkThread extends Thread {
public void run() {
while (isConnRun) {
long currentTime = System.currentTimeMillis();
// 三分钟没有数据数据传输了
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();
}
// 一分钟后没有收到响应,重发
if (temp == AgentCrbtClientHandler
.getLastDataTransTime()) {
if (i == MsgInfo.checkDegree - 1) {// 最后一次发送后还是没有收到任何响应,断开与服务器连接
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);
// 发送链路检测包
tcpClient.send(msgEnquireLink.getMsg());
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -