From 5bef6675058bcea81cef46e97d302b4ba5d7be21 Mon Sep 17 00:00:00 2001 From: waken Date: Fri, 17 Nov 2023 17:10:39 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8DUdp=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=B7=B2=E5=85=B3=E9=97=AD=E6=B5=81=EF=BC=8C=E7=94=B1=E4=BA=8E?= =?UTF-8?q?=E6=9C=80=E5=90=8E=E5=87=A0=E5=B8=A7=E6=95=B0=E6=8D=AE=E4=BC=A0?= =?UTF-8?q?=E5=85=A5=E5=8F=88=E9=87=8D=E6=96=B0=E5=88=9B=E5=BB=BAsession?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Network/UdpServer.cpp | 16 ++++++++++++++++ src/Network/UdpServer.h | 2 ++ 2 files changed, 18 insertions(+) diff --git a/src/Network/UdpServer.cpp b/src/Network/UdpServer.cpp index 2a027d1e4..7717a4127 100644 --- a/src/Network/UdpServer.cpp +++ b/src/Network/UdpServer.cpp @@ -74,6 +74,7 @@ void UdpServer::start_l(uint16_t port, const std::string &host) { //主server才创建session map,其他cloned server共享之 _session_mutex = std::make_shared(); _session_map = std::make_shared >(); + _session_erase_map = std::make_shared>>(); // 新建一个定时器定时管理这些 udp 会话,这些对象只由主server做超时管理,cloned server不管理 std::weak_ptr weak_self = std::static_pointer_cast(shared_from_this()); @@ -154,6 +155,13 @@ static void emitSessionRecv(const Session::Ptr &session, const Buffer::Ptr &buf) void UdpServer::onRead_l(bool is_server_fd, const UdpServer::PeerIdType &id, const Buffer::Ptr &buf, sockaddr *addr, int addr_len) { // udp server fd收到数据时触发此函数;大部分情况下数据应该在peer fd触发,此函数应该不是热点函数 + //避免重复创建 + { + std::lock_guard lock(*_session_mutex); + if (_session_erase_map->find(id) != _session_erase_map->end()) { + return; + } + } bool is_new = false; if (auto session = getOrCreateSession(id, buf, addr, addr_len, is_new)) { if (session->getPoller()->isCurrentThread()) { @@ -286,6 +294,14 @@ Session::Ptr UdpServer::createSession(const PeerIdType &id, const Buffer::Ptr &b //从共享map中移除本session对象 lock_guard lck(*strong_self->_session_mutex); strong_self->_session_map->erase(id); + //0.5s后自动删除 + strong_self->_session_erase_map->emplace(id,std::make_unique(0.5f, + [weak_self,id]() -> bool { + auto strong_self = weak_self.lock(); + strong_self->_session_erase_map->erase(id); + return false; + }, + _poller)); }); // 获取会话强应用 diff --git a/src/Network/UdpServer.h b/src/Network/UdpServer.h index e416ad60e..08b744aba 100644 --- a/src/Network/UdpServer.h +++ b/src/Network/UdpServer.h @@ -111,6 +111,8 @@ class UdpServer : public Server { //cloned server共享主server的session map,防止数据在不同server间漂移 std::shared_ptr _session_mutex; std::shared_ptr > _session_map; + //避免关闭流时由于最后几帧数据导致再次重新创建session + std::shared_ptr>> _session_erase_map; //主server持有cloned server的引用 std::unordered_map _cloned_server; std::function _session_alloc; From 6d64d97001e06cc7dd717c553969245890417443 Mon Sep 17 00:00:00 2001 From: waken Date: Fri, 17 Nov 2023 17:17:48 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E5=87=8F=E5=B0=91=E4=B8=80=E6=AC=A1lock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Network/UdpServer.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Network/UdpServer.cpp b/src/Network/UdpServer.cpp index 7717a4127..718c67a10 100644 --- a/src/Network/UdpServer.cpp +++ b/src/Network/UdpServer.cpp @@ -155,13 +155,6 @@ static void emitSessionRecv(const Session::Ptr &session, const Buffer::Ptr &buf) void UdpServer::onRead_l(bool is_server_fd, const UdpServer::PeerIdType &id, const Buffer::Ptr &buf, sockaddr *addr, int addr_len) { // udp server fd收到数据时触发此函数;大部分情况下数据应该在peer fd触发,此函数应该不是热点函数 - //避免重复创建 - { - std::lock_guard lock(*_session_mutex); - if (_session_erase_map->find(id) != _session_erase_map->end()) { - return; - } - } bool is_new = false; if (auto session = getOrCreateSession(id, buf, addr, addr_len, is_new)) { if (session->getPoller()->isCurrentThread()) { @@ -223,6 +216,10 @@ Session::Ptr UdpServer::getOrCreateSession(const UdpServer::PeerIdType &id, cons if (it != _session_map->end()) { return it->second->session(); } + //避免重复创建 + if (_session_erase_map->find(id) != _session_erase_map->end()) { + return nullptr; + } } is_new = true; return createSession(id, buf, addr, addr_len); From dec28a48efb8f7d67c3513dc9519b82a1497ed9b Mon Sep 17 00:00:00 2001 From: waken Date: Fri, 17 Nov 2023 17:24:09 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E5=88=87=E6=8D=A2=E4=B8=BAC++11=20?= =?UTF-8?q?=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Network/UdpServer.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Network/UdpServer.cpp b/src/Network/UdpServer.cpp index 718c67a10..dfae0eccd 100644 --- a/src/Network/UdpServer.cpp +++ b/src/Network/UdpServer.cpp @@ -292,13 +292,16 @@ Session::Ptr UdpServer::createSession(const PeerIdType &id, const Buffer::Ptr &b lock_guard lck(*strong_self->_session_mutex); strong_self->_session_map->erase(id); //0.5s后自动删除 - strong_self->_session_erase_map->emplace(id,std::make_unique(0.5f, + strong_self->_session_erase_map->emplace( + id, + std::unique_ptr(std::move(new Timer( + 0.5f, [weak_self,id]() -> bool { auto strong_self = weak_self.lock(); strong_self->_session_erase_map->erase(id); return false; }, - _poller)); + _poller)))); }); // 获取会话强应用 From 903c51308c1095d56a10be8b5ef8a0c5dfe1e8a4 Mon Sep 17 00:00:00 2001 From: waken Date: Fri, 17 Nov 2023 17:25:14 +0800 Subject: [PATCH 4/4] # --- src/Network/UdpServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Network/UdpServer.cpp b/src/Network/UdpServer.cpp index dfae0eccd..5a8062895 100644 --- a/src/Network/UdpServer.cpp +++ b/src/Network/UdpServer.cpp @@ -278,7 +278,7 @@ Session::Ptr UdpServer::createSession(const PeerIdType &id, const Buffer::Ptr &b //收到非本peer fd的数据,让server去派发此数据到合适的session对象 strong_self->onRead_l(false, id, buf, addr, addr_len); }); - socket->setOnErr([weak_self, weak_session, id, cls](const SockException &err) { + socket->setOnErr([weak_self, weak_session, id, cls,this](const SockException &err) { // 在本函数作用域结束时移除会话对象 // 目的是确保移除会话前执行其 onError 函数 // 同时避免其 onError 函数抛异常时没有移除会话对象