Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

修复Udp数据已关闭流,由于最后几帧数据传入又重新创建session对象 #191

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion src/Network/UdpServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::recursive_mutex>();
_session_map = std::make_shared<std::unordered_map<PeerIdType, SessionHelper::Ptr> >();
_session_erase_map = std::make_shared<std::unordered_map<PeerIdType, std::unique_ptr<Timer>>>();

// 新建一个定时器定时管理这些 udp 会话,这些对象只由主server做超时管理,cloned server不管理
std::weak_ptr<UdpServer> weak_self = std::static_pointer_cast<UdpServer>(shared_from_this());
Expand Down Expand Up @@ -215,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);
Expand Down Expand Up @@ -273,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 函数抛异常时没有移除会话对象
Expand All @@ -286,6 +291,17 @@ Session::Ptr UdpServer::createSession(const PeerIdType &id, const Buffer::Ptr &b
//从共享map中移除本session对象
lock_guard<std::recursive_mutex> lck(*strong_self->_session_mutex);
strong_self->_session_map->erase(id);
//0.5s后自动删除
strong_self->_session_erase_map->emplace(
id,
std::unique_ptr<Timer>(std::move(new Timer(
0.5f,
[weak_self,id]() -> bool {
auto strong_self = weak_self.lock();
strong_self->_session_erase_map->erase(id);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

而且这里也没判断strong_self是否有效

return false;
},
_poller))));
});

// 获取会话强应用
Expand Down
2 changes: 2 additions & 0 deletions src/Network/UdpServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ class UdpServer : public Server {
//cloned server共享主server的session map,防止数据在不同server间漂移
std::shared_ptr<std::recursive_mutex> _session_mutex;
std::shared_ptr<std::unordered_map<PeerIdType, SessionHelper::Ptr> > _session_map;
//避免关闭流时由于最后几帧数据导致再次重新创建session
std::shared_ptr<std::unordered_map<PeerIdType,std::unique_ptr<Timer>>> _session_erase_map;
//主server持有cloned server的引用
std::unordered_map<EventPoller *, Ptr> _cloned_server;
std::function<SessionHelper::Ptr(const UdpServer::Ptr &, const Socket::Ptr &)> _session_alloc;
Expand Down
Loading