AzeorthCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Socket< T > Class Template Referenceabstract

#include "Socket.h"

Inheritance diagram for Socket< T >:

Public Member Functions

 Socket (tcp::socket &&socket)
 
virtual ~Socket ()
 
virtual void Start ()=0
 
virtual bool Update ()
 
boost::asio::ip::address GetRemoteIpAddress () const
 
uint16 GetRemotePort () const
 
void AsyncRead ()
 
void AsyncReadWithCallback (void(T::*callback)(boost::system::error_code, std::size_t))
 
void QueuePacket (MessageBuffer &&buffer)
 
bool IsOpen () const
 
void CloseSocket ()
 
void DelayedCloseSocket ()
 Marks the socket for closing after write buffer becomes empty. More...
 
MessageBufferGetReadBuffer ()
 

Protected Member Functions

virtual void OnClose ()
 
virtual void ReadHandler ()=0
 
bool AsyncProcessQueue ()
 
void SetNoDelay (bool enable)
 

Private Member Functions

void ReadHandlerInternal (boost::system::error_code error, size_t transferredBytes)
 
void WriteHandlerWrapper (boost::system::error_code, std::size_t)
 
bool HandleQueue ()
 

Private Attributes

tcp::socket _socket
 
boost::asio::ip::address _remoteAddress
 
uint16 _remotePort
 
MessageBuffer _readBuffer
 
std::queue< MessageBuffer_writeQueue
 
std::atomic< bool > _closed
 
std::atomic< bool > _closing
 
bool _isWritingAsync
 

Detailed Description

template<class T>
class Socket< T >

Constructor & Destructor Documentation

◆ Socket()

template<class T >
Socket< T >::Socket ( tcp::socket &&  socket)
inlineexplicit
41 : _socket(std::move(socket)), _remoteAddress(_socket.remote_endpoint().address()),
42 _remotePort(_socket.remote_endpoint().port()), _readBuffer(), _closed(false), _closing(false), _isWritingAsync(false)
43 {
45 }
#define READ_BLOCK_SIZE
Definition: Socket.h:32
void Resize(size_type bytes)
Definition: MessageBuffer.h:52
uint16 _remotePort
Definition: Socket.h:277
std::atomic< bool > _closing
Definition: Socket.h:283
std::atomic< bool > _closed
Definition: Socket.h:282
boost::asio::ip::address _remoteAddress
Definition: Socket.h:276
tcp::socket _socket
Definition: Socket.h:274
MessageBuffer _readBuffer
Definition: Socket.h:279
bool _isWritingAsync
Definition: Socket.h:285

References Socket< T >::_readBuffer, READ_BLOCK_SIZE, and MessageBuffer::Resize().

◆ ~Socket()

template<class T >
virtual Socket< T >::~Socket ( )
inlinevirtual
48 {
49 _closed = true;
50 boost::system::error_code error;
51 _socket.close(error);
52 }

References Socket< T >::_closed, and Socket< T >::_socket.

Member Function Documentation

◆ AsyncProcessQueue()

template<class T >
bool Socket< T >::AsyncProcessQueue ( )
inlineprotected
150 {
151 if (_isWritingAsync)
152 return false;
153
154 _isWritingAsync = true;
155
156#ifdef AC_SOCKET_USE_IOCP
157 MessageBuffer& buffer = _writeQueue.front();
158 _socket.async_write_some(boost::asio::buffer(buffer.GetReadPointer(), buffer.GetActiveSize()), std::bind(&Socket<T>::WriteHandler,
159 this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
160#else
161 _socket.async_write_some(boost::asio::null_buffers(), std::bind(&Socket<T>::WriteHandlerWrapper,
162 this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
163#endif
164 return false;
165 }
Definition: MessageBuffer.h:26
uint8 * GetReadPointer()
Definition: MessageBuffer.h:58
size_type GetActiveSize() const
Definition: MessageBuffer.h:64
Definition: Socket.h:39
std::queue< MessageBuffer > _writeQueue
Definition: Socket.h:280

References Socket< T >::_isWritingAsync, Socket< T >::_socket, Socket< T >::_writeQueue, MessageBuffer::GetActiveSize(), and MessageBuffer::GetReadPointer().

Referenced by Socket< T >::HandleQueue(), and Socket< T >::QueuePacket().

◆ AsyncRead()

template<class T >
void Socket< T >::AsyncRead ( )
inline
87 {
88 if (!IsOpen())
89 {
90 return;
91 }
92
95
96 _socket.async_read_some(boost::asio::buffer(_readBuffer.GetWritePointer(), _readBuffer.GetRemainingSpace()),
97 std::bind(&Socket<T>::ReadHandlerInternal, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
98 }
size_type GetRemainingSpace() const
Definition: MessageBuffer.h:65
uint8 * GetWritePointer()
Definition: MessageBuffer.h:59
void EnsureFreeSpace()
Definition: MessageBuffer.h:84
void Normalize()
Definition: MessageBuffer.h:69
bool IsOpen() const
Definition: Socket.h:123

References Socket< T >::_readBuffer, Socket< T >::_socket, MessageBuffer::EnsureFreeSpace(), MessageBuffer::GetRemainingSpace(), MessageBuffer::GetWritePointer(), Socket< T >::IsOpen(), and MessageBuffer::Normalize().

◆ AsyncReadWithCallback()

template<class T >
void Socket< T >::AsyncReadWithCallback ( void(T::*)(boost::system::error_code, std::size_t)  callback)
inline
101 {
102 if (!IsOpen())
103 {
104 return;
105 }
106
109
110 _socket.async_read_some(boost::asio::buffer(_readBuffer.GetWritePointer(), _readBuffer.GetRemainingSpace()),
111 std::bind(callback, this->shared_from_this(), std::placeholders::_1, std::placeholders::_2));
112 }

References Socket< T >::_readBuffer, Socket< T >::_socket, MessageBuffer::EnsureFreeSpace(), MessageBuffer::GetRemainingSpace(), MessageBuffer::GetWritePointer(), Socket< T >::IsOpen(), and MessageBuffer::Normalize().

◆ CloseSocket()

template<class T >
void Socket< T >::CloseSocket ( )
inline
126 {
127 if (_closed.exchange(true))
128 return;
129
130 boost::system::error_code shutdownError;
131 _socket.shutdown(boost::asio::socket_base::shutdown_send, shutdownError);
132
133 if (shutdownError)
134 LOG_DEBUG("network", "Socket::CloseSocket: {} errored when shutting down socket: {} ({})", GetRemoteIpAddress().to_string(),
135 shutdownError.value(), shutdownError.message());
136
137 OnClose();
138 }
#define LOG_DEBUG(filterType__,...)
Definition: Log.h:171
boost::asio::ip::address GetRemoteIpAddress() const
Definition: Socket.h:76
virtual void OnClose()
Definition: Socket.h:146

References Socket< T >::_closed, Socket< T >::_socket, Socket< T >::GetRemoteIpAddress(), LOG_DEBUG, and Socket< T >::OnClose().

Referenced by Socket< T >::HandleQueue(), and Socket< T >::ReadHandlerInternal().

◆ DelayedCloseSocket()

template<class T >
void Socket< T >::DelayedCloseSocket ( )
inline

Marks the socket for closing after write buffer becomes empty.

141{ _closing = true; }

References Socket< T >::_closing.

◆ GetReadBuffer()

template<class T >
MessageBuffer & Socket< T >::GetReadBuffer ( )
inline
143{ return _readBuffer; }

References Socket< T >::_readBuffer.

◆ GetRemoteIpAddress()

template<class T >
boost::asio::ip::address Socket< T >::GetRemoteIpAddress ( ) const
inline

◆ GetRemotePort()

template<class T >
uint16 Socket< T >::GetRemotePort ( ) const
inline
82 {
83 return _remotePort;
84 }

References Socket< T >::_remotePort.

◆ HandleQueue()

template<class T >
bool Socket< T >::HandleQueue ( )
inlineprivate
219 {
220 if (_writeQueue.empty())
221 return false;
222
223 MessageBuffer& queuedMessage = _writeQueue.front();
224
225 std::size_t bytesToSend = queuedMessage.GetActiveSize();
226
227 boost::system::error_code error;
228 std::size_t bytesSent = _socket.write_some(boost::asio::buffer(queuedMessage.GetReadPointer(), bytesToSend), error);
229
230 if (error)
231 {
232 if (error == boost::asio::error::would_block || error == boost::asio::error::try_again)
233 {
234 return AsyncProcessQueue();
235 }
236
237 _writeQueue.pop();
238
239 if (_closing && _writeQueue.empty())
240 {
241 CloseSocket();
242 }
243
244 return false;
245 }
246 else if (bytesSent == 0)
247 {
248 _writeQueue.pop();
249
250 if (_closing && _writeQueue.empty())
251 {
252 CloseSocket();
253 }
254
255 return false;
256 }
257 else if (bytesSent < bytesToSend) // now n > 0
258 {
259 queuedMessage.ReadCompleted(bytesSent);
260 return AsyncProcessQueue();
261 }
262
263 _writeQueue.pop();
264
265 if (_closing && _writeQueue.empty())
266 {
267 CloseSocket();
268 }
269
270 return !_writeQueue.empty();
271 }
void ReadCompleted(size_type bytes)
Definition: MessageBuffer.h:61
bool AsyncProcessQueue()
Definition: Socket.h:149
void CloseSocket()
Definition: Socket.h:125

References Socket< T >::_closing, Socket< T >::_socket, Socket< T >::_writeQueue, Socket< T >::AsyncProcessQueue(), Socket< T >::CloseSocket(), MessageBuffer::GetActiveSize(), MessageBuffer::GetReadPointer(), and MessageBuffer::ReadCompleted().

Referenced by Socket< T >::Update(), and Socket< T >::WriteHandlerWrapper().

◆ IsOpen()

template<class T >
bool Socket< T >::IsOpen ( ) const
inline

◆ OnClose()

template<class T >
virtual void Socket< T >::OnClose ( )
inlineprotectedvirtual

Reimplemented in WorldSocket.

146{ }

Referenced by Socket< T >::CloseSocket().

◆ QueuePacket()

template<class T >
void Socket< T >::QueuePacket ( MessageBuffer &&  buffer)
inline
115 {
116 _writeQueue.push(std::move(buffer));
117
118#ifdef AC_SOCKET_USE_IOCP
120#endif
121 }

References Socket< T >::_writeQueue, and Socket< T >::AsyncProcessQueue().

◆ ReadHandler()

template<class T >
virtual void Socket< T >::ReadHandler ( )
protectedpure virtual

Implemented in AuthSession, and WorldSocket.

Referenced by Socket< T >::ReadHandlerInternal().

◆ ReadHandlerInternal()

template<class T >
void Socket< T >::ReadHandlerInternal ( boost::system::error_code  error,
size_t  transferredBytes 
)
inlineprivate
179 {
180 if (error)
181 {
182 CloseSocket();
183 return;
184 }
185
186 _readBuffer.WriteCompleted(transferredBytes);
187 ReadHandler();
188 }
void WriteCompleted(size_type bytes)
Definition: MessageBuffer.h:62
virtual void ReadHandler()=0

References Socket< T >::_readBuffer, Socket< T >::CloseSocket(), Socket< T >::ReadHandler(), and MessageBuffer::WriteCompleted().

◆ SetNoDelay()

template<class T >
void Socket< T >::SetNoDelay ( bool  enable)
inlineprotected
168 {
169 boost::system::error_code err;
170 _socket.set_option(tcp::no_delay(enable), err);
171
172 if (err)
173 LOG_DEBUG("network", "Socket::SetNoDelay: failed to set_option(boost::asio::ip::tcp::no_delay) for {} - {} ({})",
174 GetRemoteIpAddress().to_string(), err.value(), err.message());
175 }

References Socket< T >::_socket, Socket< T >::GetRemoteIpAddress(), and LOG_DEBUG.

◆ Start()

template<class T >
virtual void Socket< T >::Start ( )
pure virtual

Implemented in AuthSession, and WorldSocket.

◆ Update()

template<class T >
virtual bool Socket< T >::Update ( )
inlinevirtual

Reimplemented in AuthSession, and WorldSocket.

57 {
58 if (_closed)
59 {
60 return false;
61 }
62
63#ifndef AC_SOCKET_USE_IOCP
64 if (_isWritingAsync || (_writeQueue.empty() && !_closing))
65 {
66 return true;
67 }
68
69 for (; HandleQueue();)
70 ;
71#endif
72
73 return true;
74 }
bool HandleQueue()
Definition: Socket.h:218

References Socket< T >::_closed, Socket< T >::_closing, Socket< T >::_isWritingAsync, Socket< T >::_writeQueue, and Socket< T >::HandleQueue().

◆ WriteHandlerWrapper()

template<class T >
void Socket< T >::WriteHandlerWrapper ( boost::system::error_code  ,
std::size_t   
)
inlineprivate
213 {
214 _isWritingAsync = false;
215 HandleQueue();
216 }

References Socket< T >::_isWritingAsync, and Socket< T >::HandleQueue().

Member Data Documentation

◆ _closed

template<class T >
std::atomic<bool> Socket< T >::_closed
private

◆ _closing

template<class T >
std::atomic<bool> Socket< T >::_closing
private

◆ _isWritingAsync

template<class T >
bool Socket< T >::_isWritingAsync
private

◆ _readBuffer

◆ _remoteAddress

template<class T >
boost::asio::ip::address Socket< T >::_remoteAddress
private

◆ _remotePort

template<class T >
uint16 Socket< T >::_remotePort
private

◆ _socket

◆ _writeQueue

template<class T >
std::queue<MessageBuffer> Socket< T >::_writeQueue
private