📄 acdx.cpp
字号:
CString callerAlias,
CString callerIp)
{
Agent agent;
if (distribution == ACDConfig::FIRST_FIT) {
agent = firstFitRouter(queue);//give the call to the first suited agent that is
//found (unfair, but fast)
} else if (distribution == ACDConfig::ROUND_ROBIN) {
agent = roundRobinRouter(queue);//give work to the next agent who is suited (fair)
} else if (distribution == ACDConfig::LONGEST_IDLE) {
agent = longestIdleRouter(queue);//choose an agent who is suited for this group, and
//has been without a call the longest (fair)
}
// agent is not in list obj???--
if (agent.isOK) {
std::list<Agent>::iterator agentElement;
Agent _agent;
for(agentElement = aliasList.begin(); agentElement != aliasList.end(); agentElement++)
{
_agent = *agentElement;
//here use point to set list state is very important
if (agent.getAlias() == _agent.getAlias()) {
if (g_lock.lock())
{
(agentElement)->setState(Alias::TALKING);
(agentElement)->setLastCall();
(agentElement)->setLastTime();
g_lock.unlock();
}
//agent.setState(Agent::TALKING);
//agent.setLastCall();
}
}
Logger::log("Routing call for " + queue + " to " + agent.getAlias());
gkclient->routeToAlias(agent.getAlias(), callerEndId, callRef);
} else
{
int queueingMode = config->getQueueingMode(queue);
CString wqName;
char qch[4];
itoa(queueingMode,qch,10);
Logger::log("No agent available for call to " + queue + " (" + CString(qch) + ")");
if ( (queueingMode == ACDConfig::QUEUEING_MODE_RINGING) ||
(queueingMode == ACDConfig::QUEUEING_MODE_RINGANDTALK) )
{
// store the request in the backlog, in case an agent becomes available before timeout
backlog->store(queue, callerEndId, callRef, callerAlias, callerIp, PendingRequest::RINGING);
} else if ( (queueingMode == ACDConfig::QUEUEING_MODE_TALKING) &&
((wqName = getWaitQueue(queue)) != "") )
{
Logger::debug("*---acdx routecall-waiting queue name "+wqName);//test wqueue name
gkclient->routeToAlias(wqName, callerEndId, callRef);
// store the request in the backlog, in case an agent becomes available before timeout
backlog->store(queue, callerEndId, callRef, callerAlias, callerIp, PendingRequest::TALKING);
} else
{
// reject the call right away
gkclient->routeReject(callerEndId, callRef);
}
}
}
//##ModelId=42198D1803D3
/**
* Find available wait queue for this queue.
* @param queue name of called queue
* @return alias of wait queue agent or null if noe is found
*/
//##ModelId=424BB6470075
CString ACDX::getWaitQueue(CString queue)
{
std::list<Agent>::iterator aliasElement;
Agent agent;
for(aliasElement = aliasList.begin(); aliasElement != aliasList.end(); ++aliasElement )
{
agent = *aliasElement;
if ( (agent.getAlias().Find(queue + "_wq_")==0) &&
(agent.getState() == Endpoint::AVAILABLE) )
{
return agent.getAlias();
}
}
return "";
}
//##ModelId=42198D190049
// Algo: first-fit (unfair)
//##ModelId=424BB6470103
Agent ACDX::firstFitRouter(CString queue)
{
return firstFitRouter(0, queue);
}
//##ModelId=42198D190057
// Algo: first-fit (unfair)
//##ModelId=424BB6470112
Agent ACDX::firstFitRouter(int start, CString queue)
{
if (start > aliasList.size())
{
start = 0;
}
std::list<Agent>::iterator aliasElement;
Agent agent;
for(aliasElement = aliasList.begin(); aliasElement != aliasList.end(); ++aliasElement )
{
agent = *aliasElement;// look state and blocked
if (agent.isAvailable(queue))
{
agent.isOK = TRUE;
return agent;
}
}
agent.isOK = FALSE;
return agent;
}
//##ModelId=42198D19003C
// Algo: round-robin (fair)
//##ModelId=424BB6470101
Agent ACDX::roundRobinRouter(CString queue)
{
std::list<Agent>::iterator aliasElement;
Agent agent;
int i = 0;
if (lastPick.isOK) {
for(aliasElement = aliasList.begin(); aliasElement != aliasList.end(); ++aliasElement )
{
i++;
// compare address of class
if (&lastPick == &(*aliasElement))
{
// find the next available agent (position to list end)
agent = firstFitRouter(i + 1, queue);
break;
}
}
}
if (!agent.isOK) {
// go around to the start and look again
agent = firstFitRouter(0, queue);
}
lastPick = agent;
lastPick.isOK = TRUE;
return agent;
}
//##ModelId=42198D19003A]
// Algo: longest-idle (fair)
//##ModelId=424BB64700F3
Agent ACDX::longestIdleRouter(CString queue)
{
// pick the first available agent
Agent longestIdle = firstFitRouter(0, queue);
// see if we can find anyone that has been idle longer
if (longestIdle.isOK)
{ // no need to look if everybody is talking
std::list<Agent>::iterator aliasElement;
Agent agent;
for(aliasElement = aliasList.begin(); aliasElement != aliasList.end(); ++aliasElement )
{
agent = *aliasElement;
if (agent.isAvailable(queue) &&
(agent.getLastCall() < longestIdle.getLastCall()))
{
longestIdle = agent;
longestIdle.isOK = TRUE;
}
}//for
}// if
return longestIdle;
}
//##ModelId=42198D1803C6
/**
* agent is not available for ACD work.
* @param agent
*/
//##ModelId=424BB6470067
void ACDX::logout(CString agent)
{
std::list<Agent>::iterator aliasElement;
Agent ag;
for(aliasElement = aliasList.begin(); aliasElement != aliasList.end(); ++aliasElement )
{
ag = *aliasElement;
if (agent==(H323Utils::extractAliasName(ag.getAlias())))
{
if (g_lock.lock()) {
aliasElement->setBlocked(TRUE);
Logger::log("Logout agent " + agent);
g_lock.unlock();
}// lock
}// ==
}// for
}
//##ModelId=42198D1803C4
/**
* set agent to be available for ACD work again.
* @param agent
*/
//##ModelId=424BB6470065
void ACDX::login(CString agent)
{
std::list<Agent>::iterator aliasElement;
Agent ag;
for(aliasElement = aliasList.begin(); aliasElement != aliasList.end(); ++aliasElement )
{
ag = *aliasElement;
if (agent==(H323Utils::extractAliasName(ag.getAlias())))
{
if (g_lock.lock()) {
aliasElement->setBlocked(FALSE);
Logger::log("Login agent " + agent);
g_lock.unlock();
}//lock
}// ==
}// for
}
//##ModelId=42198D1803C3
/**
* Dump the list of agents with their current state.
* @return formatted list
*/
//##ModelId=424BB6470058
CString ACDX::dumpAgentStates()
{
//SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
//SYSTEMTIME systemtime;
CString result = "Agent list\n";
std::list<Agent>::iterator aliasElement;
Agent ag;
for(aliasElement = aliasList.begin(); aliasElement != aliasList.end(); ++aliasElement )
{
ag = *aliasElement;
//systemtime.wMilliseconds = ag.getLastCall();//? here to h m s maybe case error
struct tm * t = (struct tm *)ag.getLastTime();
//t->tm_mon+1
t->tm_hour;
t->tm_min;
t->tm_sec;
char c_hour[sizeof(int)];
char c_min[sizeof(int)];
char c_sec[sizeof(int)];
itoa(t->tm_hour,c_hour,10);
itoa(t->tm_min,c_min,10);
itoa(t->tm_sec,c_sec,10);
// agent last call time
CString cs_time = CString(c_hour)+":"+CString(c_min)+":"+CString(c_sec);
//t->tm_mon+1;
//CTime t(systemtime);
if (ag.isAgent()) {
// agent list contains all GK registration, only list configured agents
result += ag.getAlias() + " (" + ag.getEpid() + "):\t" +
(ag.isBlocked() ? "NOT logged in" : " logged in") +
"\tstate: " + (ag.getState()==0 ? "AVAILABLE" : "TALKING " ) +
//"\tlast call: " + t.Format("%H:%M:%S") +
"\tlast call: " + cs_time +
"\n<br>";
}
}
return result;
}
//##ModelId=42198D1803C2
/**
* Dumnp list of pending calls.
* @return formatted list
*/
//##ModelId=424BB6470057
CString ACDX::dumpPendingList()
{
return backlog->dumpPendingList();
//return "";
}
//===============================================================================================
void initNetwork()
{
#ifdef WIN32
WORD wVersionRequested = MAKEWORD( 2, 2 );
WSADATA wsaData;
int err;
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
// could not find a usable WinSock DLL
//cerr << "Could not load winsock" << endl;
assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work
exit(1);
}
/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 )
{
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup( );
//cerr << "Bad winsock verion" << endl;
assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work
exit(1);
}
#endif
}
/*
* main entry
*/
int main(int argc, char* argv[])
{
if (argc > 1) {
printf("usage: acdx\n");
exit(1);
}
initNetwork();
printf("Welcome to ACDX system!\n");
// new acd instance start work thread
ACDX::getInstance()->Start();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -