Skip to content

Commit

Permalink
Add C++17 UDPServer ID handling (#260)
Browse files Browse the repository at this point in the history
  • Loading branch information
PioLing authored Jan 12, 2025
1 parent 8df4a64 commit 8c2a2f2
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 7 deletions.
8 changes: 3 additions & 5 deletions src/Network/UdpServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ static UdpServer::PeerIdType makeSockId(sockaddr *addr, int) {
UdpServer::PeerIdType ret;
switch (addr->sa_family) {
case AF_INET : {
ret.resize(18);
ret[0] = ((struct sockaddr_in *) addr)->sin_port >> 8;
ret[1] = ((struct sockaddr_in *) addr)->sin_port & 0xFF;
//ipv4地址统一转换为ipv6方式处理 [AUTO-TRANSLATED:ad7cf8c3]
Expand All @@ -35,13 +34,12 @@ static UdpServer::PeerIdType makeSockId(sockaddr *addr, int) {
return ret;
}
case AF_INET6 : {
ret.resize(18);
ret[0] = ((struct sockaddr_in6 *) addr)->sin6_port >> 8;
ret[1] = ((struct sockaddr_in6 *) addr)->sin6_port & 0xFF;
memcpy(&ret[2], &(((struct sockaddr_in6 *)addr)->sin6_addr), 16);
return ret;
}
default: assert(0); return "";
default: throw std::invalid_argument("invalid sockaddr address");
}
}

Expand Down Expand Up @@ -78,7 +76,7 @@ void UdpServer::start_l(uint16_t port, const std::string &host) {
//主server才创建session map,其他cloned server共享之 [AUTO-TRANSLATED:113cf4fd]
//Only the main server creates a session map, other cloned servers share it
_session_mutex = std::make_shared<std::recursive_mutex>();
_session_map = std::make_shared<std::unordered_map<PeerIdType, SessionHelper::Ptr> >();
_session_map = std::make_shared<SessionMapType>();

// 新建一个定时器定时管理这些 udp 会话,这些对象只由主server做超时管理,cloned server不管理 [AUTO-TRANSLATED:d20478a2]
//Create a timer to manage these udp sessions periodically, these objects are only managed by the main server, cloned servers do not manage them
Expand Down Expand Up @@ -207,7 +205,7 @@ void UdpServer::onManagerSession() {
std::lock_guard<std::recursive_mutex> lock(*_session_mutex);
//拷贝map,防止遍历时移除对象 [AUTO-TRANSLATED:ebbc7595]
//Copy the map to prevent objects from being removed during traversal
copy_map = std::make_shared<std::unordered_map<PeerIdType, SessionHelper::Ptr> >(*_session_map);
copy_map = std::make_shared<SessionMapType>(*_session_map);
}
auto lam = [copy_map]() {
for (auto &pr : *copy_map) {
Expand Down
40 changes: 38 additions & 2 deletions src/Network/UdpServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,42 @@
#ifndef TOOLKIT_NETWORK_UDPSERVER_H
#define TOOLKIT_NETWORK_UDPSERVER_H

#if __cplusplus >= 201703L
#include <array>
#include <string_view>
#endif
#include "Server.h"
#include "Session.h"

namespace toolkit {

class UdpServer : public Server {
public:
#if __cplusplus >= 201703L
class PeerIdType : public std::array<char, 18> {
#else
class PeerIdType : public std::string {
#endif
public:
#if __cplusplus < 201703L
PeerIdType() {
resize(18);
}
#endif
bool operator==(const PeerIdType &that) const {
return as<uint64_t>(0) == that.as<uint64_t>(0) &&
as<uint64_t>(8) == that.as<uint64_t>(8) &&
as<uint16_t>(16) == that.as<uint16_t>(16);
}

private:
template <class T>
const T& as(size_t offset) const {
return *(reinterpret_cast<const T *>(data() + offset));
}
};

using Ptr = std::shared_ptr<UdpServer>;
using PeerIdType = std::string;
using onCreateSocket = std::function<Socket::Ptr(const EventPoller::Ptr &, const Buffer::Ptr &, struct sockaddr *, int)>;

explicit UdpServer(const EventPoller::Ptr &poller = nullptr);
Expand Down Expand Up @@ -75,6 +102,15 @@ class UdpServer : public Server {
virtual void cloneFrom(const UdpServer &that);

private:
struct PeerIdHash {
#if __cplusplus >= 201703L
size_t operator()(const PeerIdType &v) const noexcept { return std::hash<std::string_view> {}(std::string_view(v.data(), v.size())); }
#else
size_t operator()(const PeerIdType &v) const noexcept { return std::hash<std::string> {}(v); }
#endif
};
using SessionMapType = std::unordered_map<PeerIdType, SessionHelper::Ptr, PeerIdHash>;

/**
* @brief 开始udp server
* @param port 本机端口,0则随机
Expand Down Expand Up @@ -150,7 +186,7 @@ class UdpServer : public Server {
//cloned server共享主server的session map,防止数据在不同server间漂移 [AUTO-TRANSLATED:9a149e52]
//Cloned server shares the session map with the main server, preventing data drift between different servers
std::shared_ptr<std::recursive_mutex> _session_mutex;
std::shared_ptr<std::unordered_map<PeerIdType, SessionHelper::Ptr> > _session_map;
std::shared_ptr<SessionMapType> _session_map;
//主server持有cloned server的引用 [AUTO-TRANSLATED:04a6403a]
//Main server holds a reference to the cloned server
std::unordered_map<EventPoller *, Ptr> _cloned_server;
Expand Down

0 comments on commit 8c2a2f2

Please sign in to comment.