📄 mtthread.cpp
字号:
// MtThread.cpp: implementation of the CMtThread class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MtThread.h"
#include "MtSocket.h"
#include "ServiceAction.h"
#include "VariantBufConvert.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define WAITCONNECTRSP 10000 //等待CmppConnectRsp5秒
#define WAITSUBMITRSP 10000 //等待SubmitRsp
#define WAITTERMITERRSP 5000 //等待UNBINDRSP
#define RECONNECTTIME 1000 //自动重连时间
#define ACTIVETSTTIME 20000 //20秒连路检测
#define WAITACTIVETESTRSP 10000 //等待ActiveTestRasp时间10秒
#define KEEPACTIVE 60000 //保持空闲连接时间60秒
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMtThread::CMtThread(CString OutQueuePath,CString ReportQueuePath,CServiceAction* pParentAction,CString& csProvince)
{
::CoInitializeEx(
NULL, //always NULL
COINIT_APARTMENTTHREADED //see book about threading models
);
m_QueuePtr=NULL;
m_QueueInfoPtr=NULL;
m_MessagePtr=NULL;
m_OutQueuePath=OutQueuePath;
m_ReportQueuePath=ReportQueuePath;
m_pParentAction=pParentAction;
m_pMtSocket=NULL;
m_ReconnectEvent=0; //自动重连事件
m_EventNotReceiveConnectRsp=0; //没收到CmppConnectRsp;
m_EventNotReceiveSubmitRsp=0; //没收到SubmitRsp;
m_EventNotReceiveTerminalRsp=0;//没收到TerminalRsp;
m_EventKeepActive=0;
m_ActiveTest=0; //连路检测
m_SubmitMsgs=0;
m_BinaryOutLen=0;
m_bBeginReadQueue=FALSE;//是否读队列标志
m_ReSend=FALSE;
m_ResendTimes=0;//重发次数
m_ReconnectTimes=0;//自动重连次数
m_WaitLongSubmitRsp=0;
m_ConnectStatus=0; //连接状态参量
//0表示未连接,1表示连接正常,2表示自动重连
m_bSavereport=FALSE;
m_Province=csProvince;
m_NotWaitActiveRsp=0;
m_ProvinceIndex=0;
}
CMtThread::~CMtThread()
{
if(m_pMtSocket!=NULL)
{
m_pMtSocket->Close();
delete m_pMtSocket;
}
}
//出错时可调用,报告错误,父类出错时也调用该函数
void CMtThread::ReportError(CString &csErrorInfo)
{
CString MsgType="02";
CString ChildType="03";
m_pParentAction->SaveStatusInfo(MsgType,ChildType,csErrorInfo,m_ProvinceIndex);
}
//循环读取对列
void CMtThread::SingleStep()
{
if(m_bBeginReadQueue==FALSE || m_QueuePtr==NULL)
return;
try
{
VARIANT TimeOut;
TimeOut.vt=VT_I4;
TimeOut.lVal=1;
m_MessagePtr=m_QueuePtr->Receive(&vtMissing,&vtMissing,&vtMissing,&TimeOut);
if (m_MessagePtr==NULL)
return;
m_TempLabel=(char*)m_MessagePtr->Label;
CString csType=GetSubString(m_TempLabel,0);
m_SendPackage.m_csSendType = csType;
if(csType=="01")
{
m_SendPackage.m_Contype=3;//说明是SMC话单
m_SendPackage.m_csDestPhone=GetSubString(m_TempLabel,2);
m_SendPackage.m_csServiceType=GetSubString(m_TempLabel,3);
m_SendPackage.m_csFeetype=GetSubString(m_TempLabel,4);
m_SendPackage.m_csFeeCode=GetSubString(m_TempLabel,5);
m_SendPackage.m_csFeePhone=GetSubString(m_TempLabel,6);//得到付费手机号
m_SendPackage.m_csContent="计费";//无内容
if(m_SendPackage.m_csFeePhone=="no") //说明无付费手机,由中端付费
m_SendPackage.m_csFeePhone=m_SendPackage.m_csDestPhone;
m_SendPackage.m_csGameID=GetSubString(m_TempLabel,7);//得到游戏ID
m_SendPackage.m_MsgFmt=15;
}
else if(csType=="GIVE")//赠送话单
{
m_SendPackage.m_Contype=4;//说明是赠送话单
m_SendPackage.m_csDestPhone=GetSubString(m_TempLabel,2);
m_SendPackage.m_csServiceType=GetSubString(m_TempLabel,3);
m_SendPackage.m_csFeetype=GetSubString(m_TempLabel,4);
m_SendPackage.m_csFeeCode=GetSubString(m_TempLabel,5);
m_SendPackage.m_csFeePhone=GetSubString(m_TempLabel,6);//得到付费手机号
m_SendPackage.m_csContent=m_MessagePtr->Body.bstrVal ;
if(m_SendPackage.m_csFeePhone=="no") //说明无付费手机,由中端付费
m_SendPackage.m_csFeePhone=m_SendPackage.m_csDestPhone;
m_SendPackage.m_csGameID=GetSubString(m_TempLabel,7);//得到游戏ID
m_SendPackage.m_GivenValue= GetSubString(m_TempLabel,8);//得到赠送话费
m_SendPackage.m_MsgFmt=15;
}
else //00
{
m_SendPackage.m_csDestPhone=GetSubString(m_TempLabel,2);//目的手机
m_SendPackage.m_csServiceType=GetSubString(m_TempLabel,3);//业务代码
m_SendPackage.m_csFeetype=GetSubString(m_TempLabel,4);
if(m_SendPackage.m_csFeetype.GetLength()>2)
{
m_bBeginReadQueue=TRUE;
SaveWrongPackage();
return;
}
m_SendPackage.m_csFeeCode=GetSubString(m_TempLabel,5);
m_SendPackage.m_csFeePhone=GetSubString(m_TempLabel,6);//得到付费手机号
if(m_SendPackage.m_csFeePhone=="no") //说明无付费手机,由中端付费
m_SendPackage.m_csFeePhone=m_SendPackage.m_csDestPhone;
m_SendPackage.m_csGameID=GetSubString(m_TempLabel,7);//得到业务ID
m_SendPackage.m_csChildNum =GetSubString(m_TempLabel,8);//得到业务子号
CString csFmt=GetSubString(m_TempLabel,9); //得到发送的数据格式
CString Tppid=GetSubString(m_TempLabel,10);
CString Tpudhi=GetSubString(m_TempLabel,11);
m_SendPackage.m_csAreaCode = GetSubString(m_TempLabel,13); //地区号
m_SendPackage.m_csUserType = GetSubString(m_TempLabel,14); //卡类型
m_SendPackage.m_LinkId=GetSubString(m_TempLabel,15);
m_SendPackage.m_MoToMtFlag = GetSubString(m_TempLabel,16); //0表示有上行才下行,1表示点播非第一条下行,2表示SP主动下行
if((m_SendPackage.m_MoToMtFlag == "") || ((atoi(m_SendPackage.m_MoToMtFlag)< 0) && (atoi(m_SendPackage.m_MoToMtFlag) > 2))) m_SendPackage.m_MoToMtFlag = "0";
m_SendPackage.m_RegistDeliver = GetSubString(m_TempLabel,17);
if((m_SendPackage.m_RegistDeliver == "") || ((atoi(m_SendPackage.m_MoToMtFlag)< 0) && (atoi(m_SendPackage.m_MoToMtFlag) > 1))) m_SendPackage.m_RegistDeliver = "1";
if(m_MessagePtr->Body.vt!=VT_BSTR)//二进值
{
BOOL SuccessConver=CVariantBufConvert::VariantToBuf(m_MessagePtr->Body,m_SendPackage.m_BinaryBuf,2000,(long&)(m_SendPackage.m_SendLength));
m_SendPackage.m_Contype=1;
m_SendPackage.m_PkTotal=m_SendPackage.m_SendLength/140+1;
m_SendPackage.m_PkNumber=1;
if(SuccessConver==FALSE)
{
CString Error="Convert Variant to Binary Error:";
ReportError(Error);
return;
}
m_SendPackage.m_csContent="二进值数据";
if(Tppid=="" ||Tppid=="no")
m_SendPackage.m_Tppid=0;
else
m_SendPackage.m_Tppid=atoi(Tppid);
if(Tpudhi=="" || Tpudhi=="no")
m_SendPackage.m_Tpudhi=0;
else
m_SendPackage.m_Tpudhi=atoi(Tpudhi);
if(csFmt=="")
m_SendPackage.m_MsgFmt=4;
else if(csFmt.GetLength()>2)
m_SendPackage.m_MsgFmt=4;
else
{
m_SendPackage.m_MsgFmt=atoi(csFmt);
}
}
else //文本
{
m_TempBody=m_MessagePtr->Body;
m_SendPackage.m_csContent=m_TempBody.bstrVal;
m_SendPackage.m_SendLength=m_SendPackage.m_csContent.GetLength();
if(m_SendPackage.m_SendLength==0)
{
m_bBeginReadQueue=TRUE;
CString ErrorInfo;
ErrorInfo.Format("Send an empty package!");
ReportError(ErrorInfo);
SaveWrongPackage();
return;
}
m_SendPackage.m_Contype=0;
//得到发送格式
if(csFmt=="")
m_SendPackage.m_MsgFmt=15;
else if(csFmt.GetLength()>2)
m_SendPackage.m_MsgFmt=15;
else
{
m_SendPackage.m_MsgFmt=atoi(csFmt);
if(m_SendPackage.m_MsgFmt==0&&csFmt!="00")
m_SendPackage.m_MsgFmt=15;
}
}
}
CString str;
str.Format("Send package to :%s Content:%s",m_SendPackage.m_csServiceType,m_SendPackage.m_csContent);
ReportError(str);
BeginSubmit();
}
catch(_com_error& e)
{
CMsmqerr errtemp;
CString ErrorInfo;
ErrorInfo.Format("Read queue--%s--error:%s",m_OutQueuePath,errtemp.GetErrText(e));
ReportError(ErrorInfo);
m_bBeginReadQueue=TRUE;
}
}
//自身初始化
void CMtThread::InitChildClass()
{
InitQueue();//初始化队列
CString csTemp;
m_bBeginReadQueue=TRUE;
}
void CMtThread::OnTimer(UINT EventID)
{
CString csErrorInfo;
if(m_ReconnectEvent==EventID)//自动重连
{
KillThreadTimer(m_ReconnectEvent);
KillThreadTimer(m_EventNotReceiveTerminalRsp);
ConnectIsmg();
m_ReconnectTimes++;
}
if(EventID==m_EventNotReceiveConnectRsp)//指定时间未收到ConnectRsp//丢弃不重发
{
csErrorInfo="NOT RECEIVE ConnectRsp!Begin Reconnect!";
ReportError(csErrorInfo);
KillThreadTimer(m_EventNotReceiveConnectRsp);
Reconnect();//自动重连
return;
}
if(m_WaitLongSubmitRsp==EventID)////指定时间未收到长包的SubmitRsp
{
csErrorInfo="NOT RECEIVE Long SubmitRsp!Begin Reconnect!";
ReportError(csErrorInfo);
KillThreadTimer(m_WaitLongSubmitRsp);
Reconnect();//自动重连
return;
}
if(EventID==m_EventNotReceiveSubmitRsp)//指定时间未收到SubmitRsp
{
csErrorInfo="NOT RECEIVE SubmitRsp!Begin Reconnect!";
ReportError(csErrorInfo);
m_ReSend=TRUE;//重发
KillThreadTimer(m_EventNotReceiveSubmitRsp);
Reconnect();//自动重连
return;
}
if(EventID==m_EventNotReceiveTerminalRsp)//指定时间未收到terminalRspRsp
{
csErrorInfo="NOT RECEIVE UnBindRsp,close socket!";
ReportError(csErrorInfo);
KillThreadTimer(m_EventNotReceiveTerminalRsp);
DeleteSocket(); //关闭Socket
if(!m_ReSend)
{
m_ConnectStatus=0;
m_bBeginReadQueue=TRUE;
}
else
{
m_ConnectStatus=2;
m_bBeginReadQueue=FALSE;
}
return;
}
if(EventID==m_EventKeepActive)//超时自动断开连接
{
csErrorInfo="Connection time out,close the connection!";
ReportError(csErrorInfo);
m_ConnectStatus=0;
DisConnect();
return;
}
}
//线程退出时操作
void CMtThread::ExitThread()
{
if(m_QueuePtr!=NULL)
m_QueuePtr->Close();
DisConnect();//断开
::Sleep(100);
DeleteSocket();
}
BOOL CMtThread::InitQueue()
{
::CoInitializeEx(
NULL, //always NULL
COINIT_APARTMENTTHREADED //see book about threading models
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -