⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 servicebroker.cpp

📁 基于dialogic语音卡的IVR系统源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

#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 + -