TrinityCore
SocketMgr.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef SocketMgr_h__
19#define SocketMgr_h__
20
21#include "AsyncAcceptor.h"
22#include "Errors.h"
23#include "NetworkThread.h"
24#include <boost/asio/ip/tcp.hpp>
25#include <memory>
26
27template<class SocketType>
29{
30public:
31 virtual ~SocketMgr()
32 {
33 ASSERT(!_threads && !_acceptor && !_threadCount, "StopNetwork must be called prior to SocketMgr destruction");
34 }
35
36 virtual bool StartNetwork(Trinity::Asio::IoContext& ioContext, std::string const& bindIp, uint16 port, int threadCount)
37 {
38 ASSERT(threadCount > 0);
39
40 AsyncAcceptor* acceptor = nullptr;
41 try
42 {
43 acceptor = new AsyncAcceptor(ioContext, bindIp, port);
44 }
45 catch (boost::system::system_error const& err)
46 {
47 TC_LOG_ERROR("network", "Exception caught in SocketMgr.StartNetwork ({}:{}): {}", bindIp, port, err.what());
48 return false;
49 }
50
51 if (!acceptor->Bind())
52 {
53 TC_LOG_ERROR("network", "StartNetwork failed to bind socket acceptor");
54 delete acceptor;
55 return false;
56 }
57
58 _acceptor = acceptor;
59 _threadCount = threadCount;
61
63
64 for (int32 i = 0; i < _threadCount; ++i)
65 _threads[i].Start();
66
67 _acceptor->SetSocketFactory([this]() { return GetSocketForAccept(); });
68
69 return true;
70 }
71
72 virtual void StopNetwork()
73 {
75
76 if (_threadCount != 0)
77 for (int32 i = 0; i < _threadCount; ++i)
78 _threads[i].Stop();
79
80 Wait();
81
82 delete _acceptor;
83 _acceptor = nullptr;
84 delete[] _threads;
85 _threads = nullptr;
86 _threadCount = 0;
87 }
88
89 void Wait()
90 {
91 if (_threadCount != 0)
92 for (int32 i = 0; i < _threadCount; ++i)
93 _threads[i].Wait();
94 }
95
96 virtual void OnSocketOpen(boost::asio::ip::tcp::socket&& sock, uint32 threadIndex)
97 {
98 try
99 {
100 std::shared_ptr<SocketType> newSocket = std::make_shared<SocketType>(std::move(sock));
101 newSocket->Start();
102
103 _threads[threadIndex].AddSocket(newSocket);
104 }
105 catch (boost::system::system_error const& err)
106 {
107 TC_LOG_WARN("network", "Failed to retrieve client's remote address {}", err.what());
108 }
109 }
110
112
114 {
115 uint32 min = 0;
116
117 for (int32 i = 1; i < _threadCount; ++i)
118 if (_threads[i].GetConnectionCount() < _threads[min].GetConnectionCount())
119 min = i;
120
121 return min;
122 }
123
124 std::pair<boost::asio::ip::tcp::socket*, uint32> GetSocketForAccept()
125 {
127 return std::make_pair(_threads[threadIndex].GetSocketForAccept(), threadIndex);
128 }
129
130protected:
131 SocketMgr() : _acceptor(nullptr), _threads(nullptr), _threadCount(0)
132 {
133 }
134
136
140};
141
142#endif // SocketMgr_h__
int32_t int32
Definition: Define.h:138
uint16_t uint16
Definition: Define.h:143
uint32_t uint32
Definition: Define.h:142
#define ASSERT
Definition: Errors.h:68
#define TC_LOG_WARN(filterType__,...)
Definition: Log.h:162
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:165
void SetSocketFactory(std::function< std::pair< boost::asio::ip::tcp::socket *, uint32 >()> func)
AsyncAcceptor * _acceptor
Definition: SocketMgr.h:137
NetworkThread< SocketType > * _threads
Definition: SocketMgr.h:138
virtual bool StartNetwork(Trinity::Asio::IoContext &ioContext, std::string const &bindIp, uint16 port, int threadCount)
Definition: SocketMgr.h:36
virtual void OnSocketOpen(boost::asio::ip::tcp::socket &&sock, uint32 threadIndex)
Definition: SocketMgr.h:96
virtual void StopNetwork()
Definition: SocketMgr.h:72
virtual ~SocketMgr()
Definition: SocketMgr.h:31
std::pair< boost::asio::ip::tcp::socket *, uint32 > GetSocketForAccept()
Definition: SocketMgr.h:124
void Wait()
Definition: SocketMgr.h:89
int32 _threadCount
Definition: SocketMgr.h:139
uint32 SelectThreadWithMinConnections() const
Definition: SocketMgr.h:113
int32 GetNetworkThreadCount() const
Definition: SocketMgr.h:111
virtual NetworkThread< SocketType > * CreateThreads() const =0