/* * Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved. * * This file is part of ZLToolKit(https://github.com/ZLMediaKit/ZLToolKit). * * Use of this source code is governed by MIT license that can be found in the * LICENSE file in the root of the source tree. All contributing project authors * may be found in the AUTHORS file in the root of the source tree. */ #ifndef TCPSERVER_TCPSERVER_H #define TCPSERVER_TCPSERVER_H #include #include #include #include "Server.h" #include "Session.h" #include "Poller/Timer.h" #include "Util/util.h" namespace toolkit { //TCP服务器,可配置的;配置通过Session::attachServer方法传递给会话对象 class TcpServer : public Server { public: using Ptr = std::shared_ptr; /** * 创建tcp服务器,listen fd的accept事件会加入到所有的poller线程中监听 * 在调用TcpServer::start函数时,内部会创建多个子TcpServer对象, * 这些子TcpServer对象通过Socket对象克隆的方式在多个poller线程中监听同一个listen fd * 这样这个TCP服务器将会通过抢占式accept的方式把客户端均匀的分布到不同的poller线程 * 通过该方式能实现客户端负载均衡以及提高连接接收速度 */ explicit TcpServer(const EventPoller::Ptr &poller = nullptr); ~TcpServer() override; /** * @brief 开始tcp server * @param port 本机端口,0则随机 * @param host 监听网卡ip * @param backlog tcp listen backlog */ template void start(uint16_t port, const std::string &host = "::", uint32_t backlog = 1024, const std::function &)> &cb = nullptr) { static std::string cls_name = toolkit::demangle(typeid(SessionType).name()); // Session创建器,通过它创建不同类型的服务器 _session_alloc = [cb](const TcpServer::Ptr &server, const Socket::Ptr &sock) { auto session = std::shared_ptr(new SessionType(sock), [](SessionType *ptr) { TraceP(static_cast(ptr)) << "~" << cls_name; delete ptr; }); if (cb) { cb(session); } TraceP(static_cast(session.get())) << cls_name; session->setOnCreateSocket(server->_on_create_socket); return std::make_shared(server, std::move(session), cls_name); }; start_l(port, host, backlog); } /** * @brief 获取服务器监听端口号, 服务器可以选择监听随机端口 */ uint16_t getPort(); /** * @brief 自定义socket构建行为 */ void setOnCreateSocket(Socket::onCreateSocket cb); /** * 根据socket对象创建Session对象 * 需要确保在socket归属poller线程执行本函数 */ Session::Ptr createSession(const Socket::Ptr &socket); protected: virtual void cloneFrom(const TcpServer &that); virtual TcpServer::Ptr onCreatServer(const EventPoller::Ptr &poller); virtual Session::Ptr onAcceptConnection(const Socket::Ptr &sock); virtual Socket::Ptr onBeforeAcceptConnection(const EventPoller::Ptr &poller); private: void onManagerSession(); Socket::Ptr createSocket(const EventPoller::Ptr &poller); void start_l(uint16_t port, const std::string &host, uint32_t backlog); Ptr getServer(const EventPoller *) const; void setupEvent(); private: bool _multi_poller; bool _is_on_manager = false; bool _main_server = true; std::weak_ptr _parent; Socket::Ptr _socket; std::shared_ptr _timer; Socket::onCreateSocket _on_create_socket; std::unordered_map _session_map; std::function _session_alloc; std::unordered_map _cloned_server; //对象个数统计 ObjectStatistic _statistic; }; } /* namespace toolkit */ #endif /* TCPSERVER_TCPSERVER_H */