UdpServer.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright (c) 2021 The ZLToolKit project authors. All Rights Reserved.
  3. *
  4. * This file is part of ZLToolKit(https://github.com/ZLMediaKit/ZLToolKit).
  5. *
  6. * Use of this source code is governed by MIT license that can be found in the
  7. * LICENSE file in the root of the source tree. All contributing project authors
  8. * may be found in the AUTHORS file in the root of the source tree.
  9. */
  10. #ifndef TOOLKIT_NETWORK_UDPSERVER_H
  11. #define TOOLKIT_NETWORK_UDPSERVER_H
  12. #include "Server.h"
  13. #include "Session.h"
  14. namespace toolkit {
  15. class UdpServer : public Server {
  16. public:
  17. using Ptr = std::shared_ptr<UdpServer>;
  18. using PeerIdType = std::string;
  19. using onCreateSocket = std::function<Socket::Ptr(const EventPoller::Ptr &, const Buffer::Ptr &, struct sockaddr *, int)>;
  20. explicit UdpServer(const EventPoller::Ptr &poller = nullptr);
  21. ~UdpServer() override;
  22. /**
  23. * @brief 开始监听服务器
  24. */
  25. template<typename SessionType>
  26. void start(uint16_t port, const std::string &host = "::") {
  27. static std::string cls_name = toolkit::demangle(typeid(SessionType).name());
  28. // Session 创建器, 通过它创建不同类型的服务器
  29. _session_alloc = [](const UdpServer::Ptr &server, const Socket::Ptr &sock) {
  30. auto session = std::shared_ptr<SessionType>(new SessionType(sock), [](SessionType * ptr) {
  31. TraceP(static_cast<Session *>(ptr)) << "~" << cls_name;
  32. delete ptr;
  33. });
  34. TraceP(static_cast<Session *>(session.get())) << cls_name;
  35. auto sock_creator = server->_on_create_socket;
  36. session->setOnCreateSocket([sock_creator](const EventPoller::Ptr &poller) {
  37. return sock_creator(poller, nullptr, nullptr, 0);
  38. });
  39. return std::make_shared<SessionHelper>(server, std::move(session), cls_name);
  40. };
  41. start_l(port, host);
  42. }
  43. /**
  44. * @brief 获取服务器监听端口号, 服务器可以选择监听随机端口
  45. */
  46. uint16_t getPort();
  47. /**
  48. * @brief 自定义socket构建行为
  49. */
  50. void setOnCreateSocket(onCreateSocket cb);
  51. protected:
  52. virtual Ptr onCreatServer(const EventPoller::Ptr &poller);
  53. virtual void cloneFrom(const UdpServer &that);
  54. private:
  55. /**
  56. * @brief 开始udp server
  57. * @param port 本机端口,0则随机
  58. * @param host 监听网卡ip
  59. */
  60. void start_l(uint16_t port, const std::string &host = "::");
  61. /**
  62. * @brief 定时管理 Session, UDP 会话需要根据需要处理超时
  63. */
  64. void onManagerSession();
  65. void onRead(const Buffer::Ptr &buf, struct sockaddr *addr, int addr_len);
  66. /**
  67. * @brief 接收到数据,可能来自server fd,也可能来自peer fd
  68. * @param is_server_fd 时候为server fd
  69. * @param id 客户端id
  70. * @param buf 数据
  71. * @param addr 客户端地址
  72. * @param addr_len 客户端地址长度
  73. */
  74. void onRead_l(bool is_server_fd, const PeerIdType &id, const Buffer::Ptr &buf, struct sockaddr *addr, int addr_len);
  75. /**
  76. * @brief 根据对端信息获取或创建一个会话
  77. */
  78. Session::Ptr getOrCreateSession(const PeerIdType &id, const Buffer::Ptr &buf, struct sockaddr *addr, int addr_len, bool &is_new);
  79. /**
  80. * @brief 创建一个会话, 同时进行必要的设置
  81. */
  82. Session::Ptr createSession(const PeerIdType &id, const Buffer::Ptr &buf, struct sockaddr *addr, int addr_len);
  83. /**
  84. * @brief 创建socket
  85. */
  86. Socket::Ptr createSocket(const EventPoller::Ptr &poller, const Buffer::Ptr &buf = nullptr, struct sockaddr *addr = nullptr, int addr_len = 0);
  87. void setupEvent();
  88. private:
  89. bool _cloned = false;
  90. Socket::Ptr _socket;
  91. std::shared_ptr<Timer> _timer;
  92. onCreateSocket _on_create_socket;
  93. //cloned server共享主server的session map,防止数据在不同server间漂移
  94. std::shared_ptr<std::recursive_mutex> _session_mutex;
  95. std::shared_ptr<std::unordered_map<PeerIdType, SessionHelper::Ptr> > _session_map;
  96. //主server持有cloned server的引用
  97. std::unordered_map<EventPoller *, Ptr> _cloned_server;
  98. std::function<SessionHelper::Ptr(const UdpServer::Ptr &, const Socket::Ptr &)> _session_alloc;
  99. // 对象个数统计
  100. ObjectStatistic<UdpServer> _statistic;
  101. };
  102. } // namespace toolkit
  103. #endif // TOOLKIT_NETWORK_UDPSERVER_H