📄 servicebroker.cpp
字号:
#include "stdafx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#define TIMER_EVENT_TIMEOUT 100 //用于设置某个请求的过期事件
#include "ServiceBroker.h"
//#include "VSInterpreter.h"
#include "ResultSet.h"
#include "ServiceDataQueue.h"
#include "ClientSock.h"
static UINT uiRandomID = 0;
extern CServiceDataQueue m_requestQueue_App, m_requestQueue_Voice;
extern CServiceDataQueue m_replyQueue;
//add by lj
extern CServiceDataQueue m_requestQueue_Db;
BOOL g_Connected = FALSE;
//add end
extern int wprintf(char *fmt, ...);
extern int wprintf_err(char *fmt, ...);
//extern void SendToVoice(int first, int second, ResultSet *three, char *four,...);
DWORD dwTCPThreadID = 0;
DWORD dwTCPThreadID_TSD = 0;
int iRequestWaitElapse = 0;
BOOL bLog = 0;
char aszPacketLogFile_Send[] = "PacketBuf_Send.bin";
char aszPacketLogFile_Recv[] = "PacketBuf_Recv.bin";
int iServiceType_TSD;
int iFuncNo_AnswerRequest;
//add at 2001/7/4 for check connect status
int isConnect = 0;
//add end
HINSTANCE hAI2002 = NULL;
pInitDB InitDB;
pExitDB ExitDB;
pSql_Query Sql_Query;
pSql_Insert Sql_Insert;
pSql_Delete Sql_Delete;
pSql_Update Sql_Update;
int LogBuffer(char *szLogFileName_NoPath, char *pbuf, int iSize)
{
/**************************************************************
将指定缓冲中的内容写到当前目录下的LOG目录下的指定文件中
**************************************************************/
char aszLogFilePath[100] = "\0";
static BOOL bLogPathCreated = FALSE;
if(bLogPathCreated == FALSE)
{
if(CreateDirectory(".\\Log", NULL) == FALSE)
{
if(GetLastError() != ERROR_ALREADY_EXISTS)
return -1;
else
bLogPathCreated = TRUE;
}
else
bLogPathCreated = TRUE;
}
strcpy(aszLogFilePath, ".\\Log\\");
strcat(aszLogFilePath, szLogFileName_NoPath);
FILE *logfile;
logfile = fopen(aszLogFilePath, "w");
fwrite(pbuf, sizeof(char), iSize, logfile);
fclose(logfile);
return 0;
}
int LogBuffer2(char *pbuf, int iSize, char *szSuffilx)
{
/**************************************************************
将指定缓冲中的内容写到当前目录下的LOG目录下,文件名由时间和文件后缀组成(一般用来记录出错数据)
**************************************************************/
char aszLogFilePath[100] = "\0";
static BOOL bLogPathCreated = FALSE;
if(bLogPathCreated == FALSE)
{
if(CreateDirectory(".\\Log", NULL) == FALSE)
{
if(GetLastError() != ERROR_ALREADY_EXISTS)
return -1;
else
bLogPathCreated = TRUE;
}
else
bLogPathCreated = TRUE;
}
//由时间和后缀生成文件名
CTime t = CTime::GetCurrentTime();
SYSTEMTIME systemtime;
t.GetAsSystemTime(systemtime);
char aszLogFileName[100] = "\0";
if(szSuffilx != NULL) //sprintf("%s")碰到NULL时会放入"(null)"
sprintf(aszLogFileName, "%4d%02d%02d %02d-%02d-%02d-%03d_%s.txt", systemtime.wYear, systemtime.wMonth, systemtime.wDay, systemtime.wHour, systemtime.wMinute, systemtime.wSecond, systemtime.wMilliseconds, szSuffilx);
else
sprintf(aszLogFileName, "%4d%02d%02d %02d-%02d-%02d-%03d_.txt", systemtime.wYear, systemtime.wMonth, systemtime.wDay, systemtime.wHour, systemtime.wMinute, systemtime.wSecond, systemtime.wMilliseconds);
strcpy(aszLogFilePath, ".\\Log\\");
strcat(aszLogFilePath, aszLogFileName);
FILE *logfile;
logfile = fopen(aszLogFilePath, "w");
fwrite(pbuf, sizeof(char), iSize, logfile);
fclose(logfile);
return 0;
}
UINT SendRequestThread(LPVOID pParam)
{
/**************************************************
发送服务请求线程(检查请求队列,并发送请求)
**************************************************/
struct SendRequestThreadParam *pThreadParam = (struct SendRequestThreadParam *)pParam;
struct ParamList *prequestParamList;
/*不需要,因为解释器初始化完毕才会创建此线程
//等待解释器初始化完毕,才能使用队列
HANDLE hVSI_Initialized = CreateEvent(NULL, FALSE, FALSE, NAME_VSI_INITIALIZED);
if(hVSI_Initialized == NULL)
return 2;
WaitForSingleObject(hVSI_Initialized, -1);
*/
//保存线程参数
// int iChannelCount;
// iChannelCount = pThreadParam->iChannelCount;
free(pParam);
//提取TSD的服务号和ANSWERREQUEST的FUNCNO(本应该从CONFIGFILE中取得)(给ANSWERREQUEST用)
iServiceType_TSD = 9;
iFuncNo_AnswerRequest = 2;
while(dwTCPThreadID == 0)
{
Sleep(100);
}
//初始化服务请求的超时时间(如果得不到就设为0--无限等待)
iRequestWaitElapse = 1000 * GetPrivateProfileInt("ServiceInterface", "TimeOut", 0, CONFIGFILE);
//检查请求队列,并发送请求的循环
while(1)
{
if(m_requestQueue_App.IsEmpty() == TRUE)
{
WaitForSingleObject(m_requestQueue_App.m_hEvent_Add, -1);
DWORD dwError = GetLastError();
continue;
}
//有应用服务请求
int iReturnCode = m_requestQueue_App.GetParamList(&prequestParamList);
if(prequestParamList == NULL)
{
Sleep(1);
continue;
}
/*
//***************************************
//为了检查某个BUG,增加以下代码
struct ParamList *preplyParamList;
CServiceDataQueue::CreateParamList(&preplyParamList, prequestParamList->iServiceType, prequestParamList->iServiceNo, prequestParamList->iChannelNo, prequestParamList->ISN);
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, 1);
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, -1);
m_replyQueue.AddParamList(preplyParamList);
continue;
//***************************************
*/
//将请求打包成字节流,准备交给TCP发送
char *pPacket;
int len = PacketRequest(prequestParamList, &pPacket);
if(len == -1)
continue;
TcpSend(prequestParamList, pPacket, len);
/* //判断请求是请求应用服务还是等待语音服务请求(wtrequest)
if(prequestParamList->bIsReply)
{
//等待电话服务的请求,发往TSD
TcpSend(prequestParamList, pPacket, len);
}
else
{
//应用服务的请求,发往VRD
TcpSend_TSD(prequestParamList, pPacket, len);
}
*/
}//end of while(1)
return 0;
}
UINT ProcessDbRequest(LPVOID pParam)
{
char szTemp[1024];
struct ParamList *prequestParamList;
//提取TSD的服务号和ANSWERREQUEST的FUNCNO(本应该从CONFIGFILE中取得)(给ANSWERREQUEST用)
iServiceType_TSD = 9;
iFuncNo_AnswerRequest = 2;
ResultSet* pResult = NULL;
char* pDest = NULL;
int nRtn = 0;
hAI2002 = LoadLibrary(".\\AI2002DB_DLL.dll");
if(hAI2002 == NULL)
{
AfxMessageBox("Load AI2002DB.dll Failed!");
return -1;
}
InitDB = (pInitDB)GetProcAddress(hAI2002,"InitDB");
ExitDB = (pExitDB)GetProcAddress(hAI2002,"ExitDB");
Sql_Query = (pSql_Query)GetProcAddress(hAI2002, "Sql_Query");
Sql_Insert = (pSql_Insert)GetProcAddress(hAI2002, "Sql_Insert");
Sql_Delete = (pSql_Delete)GetProcAddress(hAI2002, "Sql_Delete");
Sql_Update = (pSql_Update)GetProcAddress(hAI2002, "Sql_Update");
//初始化数据库连接
// InitDB();
int nTemp = 0;
while(( nTemp=InitDB() ) != 1)
{
//重连次数到,退出连接 add by lj 2003/10/17
if(nTemp == -2)
{
AfxMessageBox("数据库初始化连接失败!请稍后再试");
return -1;
}
Sleep(3000);
continue;
}
g_Connected = TRUE;
while(1)
{
if(m_requestQueue_Db.IsEmpty() == TRUE)
{
WaitForSingleObject(m_requestQueue_Db.m_hEvent_Add, -1);
DWORD dwError = GetLastError();
continue;
}
int iReturnCode = m_requestQueue_Db.GetParamList(&prequestParamList);
if(prequestParamList == NULL)
{
Sleep(5);
continue;
}
//SQL只有一个参数,取出SQL语句参数
memcpy(szTemp, (char*)prequestParamList->pParam[0].pParam, prequestParamList->pParam[0].iSize);
pDest = strchr(szTemp, '[');
while(pDest != NULL)
{
if(pDest!=NULL)
{
szTemp[pDest - szTemp] = '(';
}
pDest = strchr(szTemp, '[');
}
pDest = strchr(szTemp, ']');
while(pDest != NULL)
{
if(pDest!=NULL)
{
szTemp[pDest-szTemp] = ')';
}
pDest = strchr(szTemp, ']');
}
struct ParamList *preplyParamList;
CServiceDataQueue::CreateParamList(&preplyParamList, 0, 0, 0, 0);
//取功能号,判断sql操作类型
//方式二、每来一个请求在单独的线程里处理,在线程中做请求、应答处理。
//由于SQL语句中使用的"()"与脚本内部函数冲突,故SQL中的"()"一律用"[]"代替 lj
if(prequestParamList->iServiceNo == 5001) //select
{
//Sql_Query负责申请pResult的内存空间
pResult = Sql_Query(szTemp);
//Add replyparam1, replyparam2
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, 1);
if( pResult !=NULL )
{
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, 1);
CServiceDataQueue::AddParamListMember_ResultSet(preplyParamList, pResult);
}
else
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, -1);
}
if(prequestParamList->iServiceNo == 5002) //insert
{
nRtn = Sql_Insert(szTemp);
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, 1);
if( nRtn==1 )
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, 1);
else
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, -1);
}
if(prequestParamList->iServiceNo == 5003)//delete
{
nRtn = Sql_Delete(szTemp);
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, 1);
if( nRtn==1 )
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, 1);
else
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, -1);
}
if(prequestParamList->iServiceNo == 5004) //update
{
nRtn = Sql_Update(szTemp);
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, 1);
if( nRtn==1 )
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, 1);
else
CServiceDataQueue::AddParamListMember_Integer(preplyParamList, -1);
}
preplyParamList->bIsIVR = prequestParamList->bIsIVR;
preplyParamList->iChannelNo = prequestParamList->iChannelNo;
preplyParamList->iServiceNo = prequestParamList->iServiceNo;
preplyParamList->iServiceType = prequestParamList->iServiceType;
preplyParamList->ISN = prequestParamList->ISN;
//设置请求/应答类型
preplyParamList->bIsReply = TRUE;
m_replyQueue.AddParamList(preplyParamList);
Sleep(10);
}
return 0;
}
int PacketRequest(struct ParamList *prequestParamList, char **ppPacket)
{
/************************************************************
功能: 将服务请求的结构指针转化为字节流(内存块)
************************************************************/
int len;
char *pTableData;
int iTableLen = PacketTable(prequestParamList, &pTableData);
//形成路由信息头
struct Header_Route *pHeader_Route = (struct Header_Route *)malloc(sizeof(struct Header_Route));
////版本
(pHeader_Route->abyteVersion)[0] = 1;
(pHeader_Route->abyteVersion)[1] = 0;
(pHeader_Route->abyteVersion)[2] = 0;
(pHeader_Route->abyteVersion)[3] = 0;
////包类型(请求包)
pHeader_Route->byteType = PACKETTYPE_REQUEST;
////长度
pHeader_Route->uiLength = iTableLen;
////FUNCNO
char aszFuncNo[10] = "\0";
sprintf(aszFuncNo, "%04d", prequestParamList->iServiceNo);
memcpy(pHeader_Route->aszFuncNo, aszFuncNo, sizeof(pHeader_Route->aszFuncNo));
////取得目的地址(由服务类型和主机序号("0000")的字符串组成)
char aszDestination[10] = "\0";
sprintf(aszDestination, "%04d%04d", prequestParamList->iServiceType, 0);
memcpy(pHeader_Route->aszDestination, aszDestination, 8);
// memset((pHeader_Route->aszDestination) + 4, '0', 4);
// memcpy(pHeader_Route->aszDestination, aszDestination, 8);
////取得源地址(由服务类型和主机序号的字符串组成)
char aszMyServiceID[10] = "\0";
char aszMyHostSN[10] = "\0";
GetPrivateProfileString("Me", "ServiceID", "abc", aszMyServiceID, sizeof(aszMyServiceID), ".\\Setup.ini");
GetPrivateProfileString("Me", "HostSN", "abc", aszMyHostSN, sizeof(aszMyHostSN), ".\\Setup.ini");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -