Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Toggle main menu visibility
Loading...
Searching...
No Matches
WorldSocketMgr.cpp
Go to the documentation of this file.
1
/*
2
* This file is part of Project SkyFire https://www.projectskyfire.org.
3
* See LICENSE.md file for Copyright information
4
*/
5
10
11
#include "
WorldSocketMgr.h
"
12
13
#include <atomic>
14
#include <memory>
15
#include <set>
16
17
#include "
Common.h
"
18
#include "
Config.h
"
19
#include "
DatabaseEnv.h
"
20
#include "
Log.h
"
21
#include "
ScriptMgr.h
"
22
#include "
Threading/BoostAsioThreadGroup.h
"
23
#include "
WorldSocket.h
"
24
#include "
WorldSocketAcceptor.h
"
25
#include <boost/asio/socket_base.hpp>
26
#include <boost/system/error_code.hpp>
27
#include <vector>
28
34
class
ReactorRunnable
35
{
36
public
:
37
ReactorRunnable
() :
38
m_ThreadGroup
(),
39
m_Connections
(0),
40
m_Stopped
(false)
41
{
42
}
43
44
virtual
~ReactorRunnable
()
45
{
46
Stop
();
47
Wait
();
48
}
49
50
void
Stop
()
51
{
52
if
(
m_Stopped
.exchange(
true
))
53
return
;
54
55
std::vector<WorldSocket*> sockets;
56
57
{
58
std::lock_guard<std::mutex> guard(
m_SocketsLock
);
59
sockets.assign(
m_Sockets
.begin(),
m_Sockets
.end());
60
}
61
62
for
(
WorldSocket
* socket : sockets)
63
socket->CloseSocket();
64
65
m_ThreadGroup
.Drain();
66
}
67
68
int
Start
()
69
{
70
return
m_ThreadGroup
.Start(1,
71
[]
72
{
73
SF_LOG_DEBUG
(
"misc"
,
"Network Thread Starting"
);
74
},
75
[]
76
{
77
SF_LOG_DEBUG
(
"misc"
,
"Network Thread exits"
);
78
});
79
}
80
81
void
Wait
()
82
{
83
m_ThreadGroup
.Join();
84
}
85
86
long
Connections
()
87
{
88
return
m_Connections
.load();
89
}
90
91
boost::asio::io_context&
GetIoContext
()
92
{
93
return
m_ThreadGroup
.GetIoContext();
94
}
95
96
int
AddSocket
(
WorldSocket
* sock)
97
{
98
{
99
std::lock_guard<std::mutex> guard(
m_SocketsLock
);
100
101
if
(
m_Stopped
)
102
return
-1;
103
104
++
m_Connections
;
105
sock->
AddReference
();
106
m_Sockets
.insert(sock);
107
}
108
109
sScriptMgr
->OnSocketOpen(sock);
110
111
sock->
AddReference
();
112
sock->
Start
([
this
](
WorldSocket
* socket)
113
{
114
SocketClosed
(socket);
115
});
116
sock->
RemoveReference
();
117
118
return
0;
119
}
120
121
void
SocketClosed
(
WorldSocket
* sock)
122
{
123
bool
owned =
false
;
124
125
{
126
std::lock_guard<std::mutex> guard(
m_SocketsLock
);
127
SocketSet::iterator itr =
m_Sockets
.find(sock);
128
if
(itr !=
m_Sockets
.end())
129
{
130
m_Sockets
.erase(itr);
131
--
m_Connections
;
132
owned =
true
;
133
}
134
}
135
136
if
(!owned)
137
return
;
138
139
sScriptMgr
->OnSocketClose(sock,
false
);
140
sock->
RemoveReference
();
141
}
142
143
private
:
144
typedef
std::atomic<long>
AtomicInt
;
145
typedef
std::set<WorldSocket*>
SocketSet
;
146
147
Skyfire::Asio::IoContextThreadGroup
m_ThreadGroup
;
148
AtomicInt
m_Connections
;
149
std::atomic<bool>
m_Stopped
;
150
151
SocketSet
m_Sockets
;
152
std::mutex
m_SocketsLock
;
153
};
154
155
WorldSocketMgr::WorldSocketMgr
() :
156
m_NetThreads
(0),
157
m_NetThreadsCount
(0),
158
m_SockOutKBuff
(-1),
159
m_SockOutUBuff
(65536),
160
m_UseNoDelay
(true),
161
m_Acceptor
(0) { }
162
163
WorldSocketMgr::~WorldSocketMgr
()
164
{
165
delete
[]
m_NetThreads
;
166
delete
m_Acceptor
;
167
}
168
169
int
170
WorldSocketMgr::StartReactiveIO
(
uint16
port,
const
char
* address)
171
{
172
m_UseNoDelay
=
sConfigMgr
->GetBoolDefault(
"Network.TcpNodelay"
,
true
);
173
174
int
num_threads =
sConfigMgr
->GetIntDefault(
"Network.Threads"
, 1);
175
176
if
(num_threads <= 0)
177
{
178
SF_LOG_ERROR
(
"misc"
,
"Network.Threads is wrong in your config file"
);
179
return
-1;
180
}
181
182
m_NetThreadsCount
=
static_cast<
size_t
>
(num_threads);
183
184
m_NetThreads
=
new
ReactorRunnable
[
m_NetThreadsCount
];
185
186
// -1 means use default
187
m_SockOutKBuff
=
sConfigMgr
->GetIntDefault(
"Network.OutKBuff"
, -1);
188
189
m_SockOutUBuff
=
sConfigMgr
->GetIntDefault(
"Network.OutUBuff"
, 65536);
190
191
if
(
m_SockOutUBuff
<= 0)
192
{
193
SF_LOG_ERROR
(
"misc"
,
"Network.OutUBuff is wrong in your config file"
);
194
return
-1;
195
}
196
197
for
(
size_t
i = 0; i <
m_NetThreadsCount
; ++i)
198
{
199
if
(
m_NetThreads
[i].Start() == -1)
200
{
201
SF_LOG_ERROR
(
"misc"
,
"Failed to start network thread"
);
202
203
for
(
size_t
j = 0; j < i; ++j)
204
m_NetThreads
[j].Stop();
205
206
for
(
size_t
j = 0; j < i; ++j)
207
m_NetThreads
[j].
Wait
();
208
209
return
-1;
210
}
211
}
212
213
m_Acceptor
=
new
WorldSocketAcceptor
;
214
215
if
(!
m_Acceptor
->Open(port, address))
216
{
217
SF_LOG_ERROR
(
"misc"
,
"Failed to open acceptor, check if the port is free"
);
218
219
for
(
size_t
i = 0; i <
m_NetThreadsCount
; ++i)
220
m_NetThreads
[i].Stop();
221
222
for
(
size_t
i = 0; i <
m_NetThreadsCount
; ++i)
223
m_NetThreads
[i].
Wait
();
224
225
return
-1;
226
}
227
228
return
0;
229
}
230
231
int
232
WorldSocketMgr::StartNetwork
(
uint16
port,
const
char
* address)
233
{
234
if
(
StartReactiveIO
(port, address) == -1)
235
return
-1;
236
237
sScriptMgr
->OnNetworkStart();
238
239
return
0;
240
}
241
242
void
243
WorldSocketMgr::StopNetwork
()
244
{
245
if
(
m_Acceptor
)
246
{
247
m_Acceptor
->Close();
248
}
249
250
if
(
m_NetThreadsCount
!= 0)
251
{
252
for
(
size_t
i = 0; i <
m_NetThreadsCount
; ++i)
253
m_NetThreads
[i].Stop();
254
}
255
256
Wait
();
257
258
sScriptMgr
->OnNetworkStop();
259
}
260
261
void
262
WorldSocketMgr::Wait
()
263
{
264
if
(
m_NetThreadsCount
!= 0)
265
{
266
for
(
size_t
i = 0; i <
m_NetThreadsCount
; ++i)
267
m_NetThreads
[i].
Wait
();
268
}
269
}
270
271
int
272
WorldSocketMgr::OnSocketOpen
(
WorldSocket
* sock,
ReactorRunnable
* reactor)
273
{
274
// set some options here
275
if
(
m_SockOutKBuff
>= 0)
276
{
277
boost::system::error_code error;
278
sock->
m_Socket
->set_option(boost::asio::socket_base::send_buffer_size(
m_SockOutKBuff
), error);
279
if
(error)
280
{
281
SF_LOG_ERROR
(
"misc"
,
"WorldSocketMgr::OnSocketOpen set_option SO_SNDBUF error = %d"
, error.value());
282
return
-1;
283
}
284
}
285
286
// Set TCP_NODELAY.
287
if
(
m_UseNoDelay
)
288
{
289
boost::system::error_code error;
290
sock->
m_Socket
->set_option(boost::asio::ip::tcp::no_delay(
true
), error);
291
if
(error)
292
{
293
SF_LOG_ERROR
(
"misc"
,
"WorldSocketMgr::OnSocketOpen: set_option TCP_NODELAY error = %d"
, error.value());
294
return
-1;
295
}
296
}
297
298
sock->
m_OutBufferSize
=
static_cast<
size_t
>
(
m_SockOutUBuff
);
299
300
if
(sock->
Initialize
() == -1)
301
return
-1;
302
303
return
reactor->
AddSocket
(sock);
304
}
305
306
ReactorRunnable
*
307
WorldSocketMgr::SelectNetworkThread
()
308
{
309
ASSERT
(
m_NetThreadsCount
>= 1);
310
311
size_t
min = 0;
312
313
for
(
size_t
i = 1; i <
m_NetThreadsCount
; ++i)
314
if
(
m_NetThreads
[i].Connections() <
m_NetThreads
[min].Connections())
315
min = i;
316
317
return
&
m_NetThreads
[min];
318
}
319
320
boost::asio::io_context&
321
WorldSocketMgr::GetNetworkIoContext
(
ReactorRunnable
* reactor)
322
{
323
return
reactor->
GetIoContext
();
324
}
BoostAsioThreadGroup.h
Common.h
Config.h
sConfigMgr
#define sConfigMgr
Definition
Config.h:64
DatabaseEnv.h
uint16
std::uint16_t uint16
Definition
Define.h:78
ASSERT
#define ASSERT
Definition
Errors.h:29
Log.h
SF_LOG_DEBUG
#define SF_LOG_DEBUG(filterType__,...)
Definition
Log.h:134
SF_LOG_ERROR
#define SF_LOG_ERROR(filterType__,...)
Definition
Log.h:143
ScriptMgr.h
sScriptMgr
#define sScriptMgr
Definition
ScriptMgr.h:764
WorldSocket.h
WorldSocketAcceptor.h
WorldSocketMgr.h
ReactorRunnable
Definition
WorldSocketMgr.cpp:35
ReactorRunnable::Start
int Start()
Definition
WorldSocketMgr.cpp:68
ReactorRunnable::Stop
void Stop()
Definition
WorldSocketMgr.cpp:50
ReactorRunnable::~ReactorRunnable
virtual ~ReactorRunnable()
Definition
WorldSocketMgr.cpp:44
ReactorRunnable::GetIoContext
boost::asio::io_context & GetIoContext()
Definition
WorldSocketMgr.cpp:91
ReactorRunnable::AddSocket
int AddSocket(WorldSocket *sock)
Definition
WorldSocketMgr.cpp:96
ReactorRunnable::Wait
void Wait()
Definition
WorldSocketMgr.cpp:81
ReactorRunnable::m_ThreadGroup
Skyfire::Asio::IoContextThreadGroup m_ThreadGroup
Definition
WorldSocketMgr.cpp:147
ReactorRunnable::ReactorRunnable
ReactorRunnable()
Definition
WorldSocketMgr.cpp:37
ReactorRunnable::m_Connections
AtomicInt m_Connections
Definition
WorldSocketMgr.cpp:148
ReactorRunnable::m_Sockets
SocketSet m_Sockets
Definition
WorldSocketMgr.cpp:151
ReactorRunnable::SocketClosed
void SocketClosed(WorldSocket *sock)
Definition
WorldSocketMgr.cpp:121
ReactorRunnable::SocketSet
std::set< WorldSocket * > SocketSet
Definition
WorldSocketMgr.cpp:145
ReactorRunnable::m_Stopped
std::atomic< bool > m_Stopped
Definition
WorldSocketMgr.cpp:149
ReactorRunnable::Connections
long Connections()
Definition
WorldSocketMgr.cpp:86
ReactorRunnable::m_SocketsLock
std::mutex m_SocketsLock
Definition
WorldSocketMgr.cpp:152
ReactorRunnable::AtomicInt
std::atomic< long > AtomicInt
Definition
WorldSocketMgr.cpp:144
Skyfire::Asio::IoContextThreadGroup
Definition
BoostAsioThreadGroup.h:23
WorldSocket
Handler that can communicate over stream sockets.
Definition
WorldSocket.h:51
WorldSocket::m_OutBufferSize
size_t m_OutBufferSize
Configured output buffer size retained for network option compatibility.
Definition
WorldSocket.h:162
WorldSocket::RemoveReference
long RemoveReference(void)
Remove reference to this object.
Definition
WorldSocket.cpp:224
WorldSocket::m_Socket
std::unique_ptr< WorldSocketHandle > m_Socket
Definition
WorldSocket.h:168
WorldSocket::AddReference
long AddReference(void)
Add reference to this object.
Definition
WorldSocket.cpp:219
WorldSocket::Start
void Start(std::function< void(WorldSocket *)> closeHandler)
Starts asynchronous socket processing.
Definition
WorldSocket.cpp:246
WorldSocket::Initialize
int Initialize(void)
Called after socket accept and manager setup.
Definition
WorldSocket.cpp:233
WorldSocketMgr::WorldSocketAcceptor
friend class WorldSocketAcceptor
Definition
WorldSocketMgr.h:27
WorldSocketMgr::WorldSocket
friend class WorldSocket
Definition
WorldSocketMgr.h:26
WorldSocketMgr::m_SockOutKBuff
int m_SockOutKBuff
Definition
WorldSocketMgr.h:53
WorldSocketMgr::StartNetwork
int StartNetwork(uint16 port, const char *address)
Start network, listen at address:port .
Definition
WorldSocketMgr.cpp:232
WorldSocketMgr::GetNetworkIoContext
boost::asio::io_context & GetNetworkIoContext(ReactorRunnable *reactor)
Definition
WorldSocketMgr.cpp:321
WorldSocketMgr::m_NetThreadsCount
size_t m_NetThreadsCount
Definition
WorldSocketMgr.h:51
WorldSocketMgr::StartReactiveIO
int StartReactiveIO(uint16 port, const char *address)
Definition
WorldSocketMgr.cpp:170
WorldSocketMgr::SelectNetworkThread
ReactorRunnable * SelectNetworkThread()
Definition
WorldSocketMgr.cpp:307
WorldSocketMgr::WorldSocketMgr
WorldSocketMgr()
Definition
WorldSocketMgr.cpp:155
WorldSocketMgr::m_SockOutUBuff
int m_SockOutUBuff
Definition
WorldSocketMgr.h:54
WorldSocketMgr::OnSocketOpen
int OnSocketOpen(WorldSocket *sock, ReactorRunnable *reactor)
Definition
WorldSocketMgr.cpp:272
WorldSocketMgr::Wait
void Wait()
Wait untill all network threads have "joined" .
Definition
WorldSocketMgr.cpp:262
WorldSocketMgr::~WorldSocketMgr
virtual ~WorldSocketMgr()
Definition
WorldSocketMgr.cpp:163
WorldSocketMgr::m_NetThreads
ReactorRunnable * m_NetThreads
Definition
WorldSocketMgr.h:50
WorldSocketMgr::m_Acceptor
class WorldSocketAcceptor * m_Acceptor
Definition
WorldSocketMgr.h:57
WorldSocketMgr::StopNetwork
void StopNetwork()
Stops all network threads, It will wait for all running threads .
Definition
WorldSocketMgr.cpp:243
WorldSocketMgr::m_UseNoDelay
bool m_UseNoDelay
Definition
WorldSocketMgr.h:55
src
server
game
Server
WorldSocketMgr.cpp
Generated on
for Project SkyFire Core by
1.17.0