#include "StdAfx.h" #include "LNAcceptor.h" #include "LNBuffer.h" #include "AppService.h" string g_strLocalIp; CLNAcceptor::CLNAcceptor(CProtocolHandler * pHandler) { m_pHandler = pHandler; } CLNAcceptor::~CLNAcceptor(void) { } CLNContext* CLNAcceptor::make_handler() { CLNContext* pContext = new CLNContext(); if(pContext) { CLNBuffer* pBuffer = new CLNBuffer(); pContext->SetBuffer(pBuffer); pContext->SetProtocolHandler(m_pHandler); cs.Lock(); m_lstClientContext.push_back(pContext); cs.Unlock(); } return pContext; } BOOL CLNAcceptor::Start() { Stop(); m_bWork = true; m_pThread = new std::thread(ThreadProc, (DWORD_PTR)this); return TRUE; } void CLNAcceptor::Stop() { m_bWork = false; if (m_pThread) { m_pThread->join(); delete m_pThread; m_pThread = nullptr; } } void CLNAcceptor::OnClearContext() { Lock(); list::iterator it = m_lstClientContext.begin(); for(; it != m_lstClientContext.end(); ) { CLNContext* pContext = *it; if(pContext == NULL) { it = m_lstClientContext.erase(it); continue; } UINT nIdleTime = pContext->GetIdleTime2(); if((nIdleTime > 180) || pContext->IsInactive(INFINITE)) { auto strAddr = pContext->GetIPAdressNew(); SPDLOG_ERROR("心跳超时.{} ", strAddr); //删除会话 if(pContext->Delete()) { SPDLOG_ERROR("删除链接.{} ", strAddr); it = m_lstClientContext.erase(it); continue; } } it++; } Unlock(); } void CLNAcceptor::ClearAllContexts() { int nRepeatNum = 20; while(true) { TRACE("nRepeatNum = %d\n", nRepeatNum); if(nRepeatNum < 0) break; BOOL bForced = (nRepeatNum == 0) ? TRUE : FALSE; Lock(); if(m_lstClientContext.empty()) { Unlock(); return; } list::iterator it = m_lstClientContext.begin(); for(; it != m_lstClientContext.end(); ) { CLNContext* pContext = *it; if((pContext == NULL) || pContext->Delete(bForced)) it = m_lstClientContext.erase(it); else it++; } Unlock(); Sleep(100); nRepeatNum--; } Lock(); m_lstClientContext.clear(); Unlock(); } int CLNAcceptor::GetContextNum() { Lock(); int nNum = (int)m_lstClientContext.size(); Unlock(); return nNum; } CLNContext* CLNAcceptor::FindContext(DWORD_PTR pContext) { CLNContext* pFind = nullptr; Lock(); for (auto it : m_lstClientContext) { if (pContext == (DWORD_PTR)it) { pFind = (CLNContext*)it->GetSharedPointer(); break; } } Unlock(); return pFind; } void CLNAcceptor::SendDataAllContexts(uint8_t* data, size_t len) { Lock(); for (auto it : m_lstClientContext) { auto pContext = (CLNContext*)it; pContext->Send(data, len); } Unlock(); } void CLNAcceptor::ThreadProc(DWORD_PTR wparam) { CLNAcceptor* pThis = (CLNAcceptor*)wparam; SPDLOG_WARN("10090 心跳线程启动"); Sleep(2000); uint8_t bSend[100] = { 0 }; int len = CHjDataConver::conver_sendpack(bSend, nullptr, 0, 0, 0, E_ZL_PROTOCAL::ZL_KEEP, OR_DATA_INFO(0, 0, 1, 3, OPT_TYPE::OPT_SYNC)); time_t tmNow; while (pThis->m_bWork) { for (size_t i = 0; i < 10; i++) { Sleep(500); if (pThis->m_bWork == false) break; } //发送心跳 time(&tmNow); if (tmNow - pThis->m_tmLastKeep > 30) { pThis->SendDataAllContexts(bSend, len); pThis->m_tmLastKeep = tmNow; } if (pThis->m_lstClientContext.size() == 0) { if (pThis->m_tmLastZero == 0) pThis->m_tmLastZero = tmNow; else if (tmNow - pThis->m_tmLastZero > 60) { bool bRet = false; if (bRet) { SPDLOG_ERROR("关闭{}端口", 10090); pThis->close(); SPDLOG_ERROR("监听{}端口", 10090); if (pThis->listen(10090) == -1) SPDLOG_CRITICAL("端口{} tcp 监听失败", 10090); pThis->m_tmLastZero = tmNow; } } } else if (!pThis->m_tmLastZero) pThis->m_tmLastZero = 0; //清除链接 pThis->OnClearContext(); } SPDLOG_WARN("10090 心跳线程退出"); }