|
@@ -58,13 +58,20 @@ bool RTPServer::thread_task(int port)
|
|
|
m_localIP = SysConfig.getBaseConfigSrc().strServerIP;
|
|
|
if(m_localIP.isEmpty())
|
|
|
{
|
|
|
- SPDLOG_LOGGER_ERROR(m_logger, "未设置服务器出口IP,无法监听客户端连接");
|
|
|
+ SPDLOG_LOGGER_ERROR(m_logger, "未设置服务器监听IP,无法监听客户端连接");
|
|
|
}
|
|
|
-
|
|
|
- /* 开启事件循环 */
|
|
|
connect(m_tcpServer, &QTcpServer::newConnection, this, &RTPServer::do_newConnection);
|
|
|
connect(m_tcpServer, &QTcpServer::acceptError, this, &RTPServer::do_error);
|
|
|
|
|
|
+ /* 开启心跳定时器 */
|
|
|
+ m_timerHeartbeat.setTimerType(Qt::PreciseTimer);
|
|
|
+ m_timerHeartbeat.setSingleShot(false);
|
|
|
+ m_timerHeartbeat.setInterval(1000);
|
|
|
+ connect(&m_timerHeartbeat, &QTimer::timeout, this, &RTPServer::do_heartbeatTimeout);
|
|
|
+
|
|
|
+ m_timerHeartbeat.start();
|
|
|
+
|
|
|
+ /* 开启事件循环 */
|
|
|
m_isStoped.store(false);
|
|
|
m_eventLoop.exec();
|
|
|
m_isStoped.store(true);
|
|
@@ -148,10 +155,9 @@ void RTPServer::do_receiveMessage()
|
|
|
// QString(data).toStdString());
|
|
|
// return;
|
|
|
|
|
|
- if(static_cast<unsigned long>(data.size()) < sizeof(RtpRecvClientInfo_t))
|
|
|
+ if(static_cast<unsigned long>(data.size()) != sizeof(RtpRecvClientInfo_t))
|
|
|
{
|
|
|
- SPDLOG_LOGGER_WARN(m_logger, "从客户端接收到的数据大小: {} 低于应有的大小 {}",
|
|
|
- data.size(), sizeof(RtpRecvClientInfo_t));
|
|
|
+ SPDLOG_LOGGER_WARN(m_logger, "从客户端接收到的数据大小: {} 不等于应有的大小 {}", data.size(), sizeof(RtpRecvClientInfo_t));
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -165,20 +171,20 @@ void RTPServer::do_receiveMessage()
|
|
|
SPDLOG_LOGGER_DEBUG(m_logger, " 客户端端口: {}", recvInfo->clientPort);
|
|
|
SPDLOG_LOGGER_DEBUG(m_logger, " 对比项ID: {}", recvInfo->compareItemID);
|
|
|
SPDLOG_LOGGER_DEBUG(m_logger, " 对比项通道号: {}", recvInfo->compareItemRoadNum);
|
|
|
- SPDLOG_LOGGER_DEBUG(m_logger, " 客户端名称: {}", recvInfo->sessionName);
|
|
|
SPDLOG_LOGGER_DEBUG(m_logger, " 包类型: {}", recvInfo->type);
|
|
|
|
|
|
+
|
|
|
/* 解析客户端发送的信息 */
|
|
|
sendInfo.clientIP = recvInfo->clientIP;
|
|
|
sendInfo.clientPort = recvInfo->clientPort;
|
|
|
- sendInfo.compareItemID = recvInfo->compareItemID;
|
|
|
- sendInfo.compareItemRoadNum = recvInfo->compareItemRoadNum;
|
|
|
+ // sendInfo.compareItemID = recvInfo->compareItemID;
|
|
|
+ // sendInfo.compareItemRoadNum = recvInfo->compareItemRoadNum;
|
|
|
/* 根据对比项ID和通道编号查找到使用到的声卡通道编号 */
|
|
|
- SoundCardRoadInfo_t roadInfo = CompareItemManager.getSoundCardRoadInfo(sendInfo.compareItemID, sendInfo.compareItemRoadNum);
|
|
|
+ SoundCardRoadInfo_t roadInfo = CompareItemManager.getSoundCardRoadInfo(recvInfo->compareItemID, recvInfo->compareItemRoadNum);
|
|
|
if(roadInfo.nSoundCardNum < 0 || roadInfo.roadInfo.nRoadNum < 0)
|
|
|
{
|
|
|
SPDLOG_LOGGER_ERROR(m_logger, "无法获取对比项 {} 通道 {} 的声卡信息",
|
|
|
- sendInfo.compareItemID, sendInfo.compareItemRoadNum);
|
|
|
+ recvInfo->compareItemID, recvInfo->compareItemRoadNum);
|
|
|
return;
|
|
|
}
|
|
|
sendInfo.SoundCardNum = roadInfo.nSoundCardNum;
|
|
@@ -201,23 +207,51 @@ void RTPServer::do_receiveMessage()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* 接收到释放端口的信号 */
|
|
|
-void RTPServer::do_udpClosed(int soundCardNum, int roadNum, int localPort)
|
|
|
+/* 一个通道UDP关闭的信号 */
|
|
|
+void RTPServer::do_udpClosed(int soundCardNum, int roadNum)
|
|
|
{
|
|
|
- SPDLOG_LOGGER_DEBUG(m_logger, "接收到释放本地端口的信号: 声卡编号: {}, 通道编号: {}, 本地端口: {}",
|
|
|
- soundCardNum, roadNum, localPort);
|
|
|
+ SPDLOG_LOGGER_DEBUG(m_logger, "接收到释放本地端口的信号: 声卡编号: {}, 通道编号: {}",
|
|
|
+ soundCardNum, roadNum);
|
|
|
+
|
|
|
+ // for(auto it = m_mapSoundCardRoadPorts.begin(); it != m_mapSoundCardRoadPorts.end(); ++it)
|
|
|
+ // {
|
|
|
+ // if(it.key().nSoundCardNum == soundCardNum && it.key().nRoadNum == roadNum)
|
|
|
+ // {
|
|
|
+ // // SPDLOG_LOGGER_DEBUG(m_logger, "从声卡通道列表中删除: 声卡编号: {}, 通道编号: {}, 本地端口: {}",
|
|
|
+ // // soundCardNum, roadNum, localPort);
|
|
|
+ // m_mapSoundCardRoadPorts.remove(it.key());
|
|
|
+ // break;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
|
|
|
- for(auto it = m_mapSoundCardRoadPorts.begin(); it != m_mapSoundCardRoadPorts.end(); ++it)
|
|
|
+}
|
|
|
+
|
|
|
+/* 处理心跳超时 */
|
|
|
+void RTPServer::do_heartbeatTimeout()
|
|
|
+{
|
|
|
+ const QDateTime currentTime = QDateTime::currentDateTime();
|
|
|
+ QList<RtpClientKey_t> keysToRemove;
|
|
|
+
|
|
|
+ for (auto it = m_mapClientHeartbeats.begin(); it != m_mapClientHeartbeats.end(); ++it)
|
|
|
{
|
|
|
- if(it.key().nSoundCardNum == soundCardNum && it.key().nRoadNum == roadNum)
|
|
|
+ if (it.value().secsTo(currentTime) > 20) // 超过30秒未收到心跳
|
|
|
{
|
|
|
- // SPDLOG_LOGGER_DEBUG(m_logger, "从声卡通道列表中删除: 声卡编号: {}, 通道编号: {}, 本地端口: {}",
|
|
|
- // soundCardNum, roadNum, localPort);
|
|
|
- m_mapSoundCardRoadPorts.remove(it.key());
|
|
|
- break;
|
|
|
+ SPDLOG_LOGGER_WARN(m_logger, "客户端 {}:{} 心跳超时,准备移除",
|
|
|
+ it.key().clientIP.toStdString(), it.key().clientPort);
|
|
|
+ keysToRemove.append(it.key());
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ /* 注销超时的会话 */
|
|
|
+ for (const auto& key : keysToRemove)
|
|
|
+ {
|
|
|
+ RtpSendClientInfo_t clientInfo;
|
|
|
+ clientInfo.clientIP = key.clientIP;
|
|
|
+ clientInfo.clientPort = key.clientPort;
|
|
|
+ clientInfo.SoundCardNum = key.SoundCardNum;
|
|
|
+ clientInfo.SoundCardRoadNum = key.SoundCardRoadNum;
|
|
|
+ handleLogout(clientInfo);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* 处理登录请求 */
|
|
@@ -225,7 +259,7 @@ void RTPServer::handleLogin(RtpSendClientInfo_t& clientInfo)
|
|
|
{
|
|
|
SPDLOG_LOGGER_TRACE(m_logger, "处理登录请求: {}:{}", clientInfo.clientIP.toStdString(), clientInfo.clientPort);
|
|
|
/* 查找本地可用的UDP端口,这里先使用10010测试 */
|
|
|
- clientInfo.localPort = 10010;
|
|
|
+ // clientInfo.localPort = 10010;
|
|
|
clientInfo.localIP = m_localIP;
|
|
|
/* 查找RTP发送线程 */
|
|
|
auto pThread = ThreadMan.getRtpSendThread(clientInfo.SoundCardNum, clientInfo.SoundCardRoadNum);
|
|
@@ -241,25 +275,30 @@ void RTPServer::handleLogin(RtpSendClientInfo_t& clientInfo)
|
|
|
return;
|
|
|
}
|
|
|
connect(pThread, &RTPOneRoadThread::signal_udpClosed, this, &RTPServer::do_udpClosed);
|
|
|
- /* 将本地端口添加到声卡通道列表中 */
|
|
|
- for(auto it = m_mapSoundCardRoadPorts.begin(); it != m_mapSoundCardRoadPorts.end(); ++it)
|
|
|
- {
|
|
|
- if(it.key().nSoundCardNum == clientInfo.SoundCardNum && it.key().nRoadNum == clientInfo.SoundCardRoadNum)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- SoundCardRoadKey_t roadInfo;
|
|
|
- roadInfo.nSoundCardNum = clientInfo.SoundCardNum;
|
|
|
- roadInfo.nRoadNum = clientInfo.SoundCardRoadNum;
|
|
|
- m_mapSoundCardRoadPorts.insert(roadInfo, clientInfo.localPort);
|
|
|
+ /* 将本地端口添加到心跳列表中 */
|
|
|
+ RtpClientKey_t clientKey;
|
|
|
+ clientKey.clientIP = clientInfo.clientIP;
|
|
|
+ clientKey.clientPort = clientInfo.clientPort;
|
|
|
+ clientKey.SoundCardNum = clientInfo.SoundCardNum;
|
|
|
+ clientKey.SoundCardRoadNum = clientInfo.SoundCardRoadNum;
|
|
|
+ m_mapClientHeartbeats[clientKey] = QDateTime::currentDateTime();
|
|
|
}
|
|
|
|
|
|
/* 处理心跳请求 */
|
|
|
void RTPServer::handleHeartbeat(RtpSendClientInfo_t& clientInfo)
|
|
|
{
|
|
|
SPDLOG_LOGGER_TRACE(m_logger, "处理心跳请求: {}:{}", clientInfo.clientIP.toStdString(), clientInfo.clientPort);
|
|
|
-
|
|
|
+ RtpClientKey_t clientKey;
|
|
|
+ clientKey.clientIP = clientInfo.clientIP;
|
|
|
+ clientKey.clientPort = clientInfo.clientPort;
|
|
|
+ clientKey.SoundCardNum = clientInfo.SoundCardNum;
|
|
|
+ clientKey.SoundCardRoadNum = clientInfo.SoundCardRoadNum;
|
|
|
+ /* 更新心跳时间 */
|
|
|
+ if(m_mapClientHeartbeats.contains(clientKey))
|
|
|
+ {
|
|
|
+ m_mapClientHeartbeats[clientKey] = QDateTime::currentDateTime();
|
|
|
+ SPDLOG_LOGGER_TRACE(m_logger, "更新心跳时间: {}:{}", clientInfo.clientIP.toStdString(), clientInfo.clientPort);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/* 处理注销请求 */
|
|
@@ -281,6 +320,19 @@ void RTPServer::handleLogout(RtpSendClientInfo_t& clientInfo)
|
|
|
SPDLOG_LOGGER_ERROR(m_logger, "删除UDP会话失败: {}:{}", clientInfo.clientIP.toStdString(), clientInfo.clientPort);
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
+ /* 将客户端信息从心跳列表中移除 */
|
|
|
+ RtpClientKey_t clientKey;
|
|
|
+ clientKey.clientIP = clientInfo.clientIP;
|
|
|
+ clientKey.clientPort = clientInfo.clientPort;
|
|
|
+ clientKey.SoundCardNum = clientInfo.SoundCardNum;
|
|
|
+ clientKey.SoundCardRoadNum = clientInfo.SoundCardRoadNum;
|
|
|
+ if(m_mapClientHeartbeats.contains(clientKey))
|
|
|
+ {
|
|
|
+ m_mapClientHeartbeats.remove(clientKey);
|
|
|
+ SPDLOG_LOGGER_DEBUG(m_logger, "从心跳列表中移除客户端: {}:{}",
|
|
|
+ clientInfo.clientIP.toStdString(), clientInfo.clientPort);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|