15 : _id(CppCommon::UUID::Sequential()),
17 _io_service(_service->GetAsioService()),
18 _strand(*_io_service),
19 _strand_required(_service->IsStrandRequired()),
22 _acceptor(*_io_service),
27 _option_keep_alive(false),
28 _option_no_delay(false),
29 _option_reuse_address(false),
30 _option_reuse_port(false)
32 assert((
service !=
nullptr) &&
"Asio service is invalid!");
34 throw CppCommon::ArgumentException(
"Asio service is invalid!");
36 assert((
context !=
nullptr) &&
"SSL context is invalid!");
38 throw CppCommon::ArgumentException(
"SSL context is invalid!");
44 _endpoint = asio::ip::tcp::endpoint(asio::ip::tcp::v4(), (
unsigned short)
port);
47 _endpoint = asio::ip::tcp::endpoint(asio::ip::tcp::v6(), (
unsigned short)
port);
52 SSLServer::SSLServer(
const std::shared_ptr<Service>& service,
const std::shared_ptr<SSLContext>& context,
const std::string& address,
int port)
53 : _id(CppCommon::UUID::Sequential()),
55 _io_service(_service->GetAsioService()),
56 _strand(*_io_service),
57 _strand_required(_service->IsStrandRequired()),
61 _acceptor(*_io_service),
66 _option_keep_alive(false),
67 _option_no_delay(false),
68 _option_reuse_address(false),
69 _option_reuse_port(false)
71 assert((
service !=
nullptr) &&
"Asio service is invalid!");
73 throw CppCommon::ArgumentException(
"Asio service is invalid!");
75 assert((
context !=
nullptr) &&
"SSL context is invalid!");
77 throw CppCommon::ArgumentException(
"SSL context is invalid!");
80 _endpoint = asio::ip::tcp::endpoint(asio::ip::make_address(
address), (
unsigned short)
port);
83 SSLServer::SSLServer(
const std::shared_ptr<Service>& service,
const std::shared_ptr<SSLContext>& context,
const asio::ip::tcp::endpoint& endpoint)
84 : _id(CppCommon::UUID::Sequential()),
86 _io_service(_service->GetAsioService()),
87 _strand(*_io_service),
88 _strand_required(_service->IsStrandRequired()),
89 _address(endpoint.address().to_string()),
90 _port(endpoint.port()),
93 _acceptor(*_io_service),
98 _option_keep_alive(false),
99 _option_no_delay(false),
100 _option_reuse_address(false),
101 _option_reuse_port(false)
103 assert((
service !=
nullptr) &&
"Asio service is invalid!");
105 throw CppCommon::ArgumentException(
"Asio service is invalid!");
107 assert((
context !=
nullptr) &&
"SSL context is invalid!");
109 throw CppCommon::ArgumentException(
"SSL context is invalid!");
114 assert(!
IsStarted() &&
"SSL server is already started!");
119 auto self(this->shared_from_this());
120 auto start_handler = [
this,
self]()
126 _acceptor = asio::ip::tcp::acceptor(*_io_service);
127 _acceptor.open(_endpoint.protocol());
129 _acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(
true));
130 #if (defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)) && !defined(__CYGWIN__)
133 typedef asio::detail::socket_option::boolean<SOL_SOCKET, SO_REUSEPORT> reuse_port;
134 _acceptor.set_option(reuse_port(
true));
137 _acceptor.bind(_endpoint);
154 if (_strand_required)
155 _strand.post(start_handler);
157 _io_service->post(start_handler);
164 assert(
IsStarted() &&
"SSL server is not started!");
169 auto self(this->shared_from_this());
170 auto stop_handler = [
this,
self]()
179 _session->ResetServer();
193 if (_strand_required)
194 _strand.post(stop_handler);
196 _io_service->post(stop_handler);
207 CppCommon::Thread::Yield();
212 void SSLServer::Accept()
218 auto self(this->shared_from_this());
227 auto async_accept_handler =
make_alloc_handler(_acceptor_storage, [
this,
self](std::error_code ec)
242 if (_strand_required)
243 _acceptor.async_accept(_session->socket(), bind_executor(_strand, async_accept_handler));
245 _acceptor.async_accept(_session->socket(), async_accept_handler);
247 if (_strand_required)
248 _strand.dispatch(accept_handler);
250 _io_service->dispatch(accept_handler);
261 assert((buffer !=
nullptr) &&
"Pointer to the buffer should not be null!");
262 if (buffer ==
nullptr)
269 session.second->SendAsync(buffer, size);
280 auto self(this->shared_from_this());
281 auto disconnect_all_handler = [
this,
self]()
290 session.second->Disconnect();
292 if (_strand_required)
293 _strand.dispatch(disconnect_all_handler);
295 _io_service->dispatch(disconnect_all_handler);
306 return (it !=
_sessions.end()) ? it->second :
nullptr;
309 void SSLServer::RegisterSession()
314 _sessions.emplace(_session->id(), _session);
317 void SSLServer::UnregisterSession(
const CppCommon::UUID&
id)
330 void SSLServer::ClearBuffers()
336 void SSLServer::SendError(std::error_code ec)
339 if ((ec == asio::error::connection_aborted) ||
340 (ec == asio::error::connection_refused) ||
341 (ec == asio::error::connection_reset) ||
342 (ec == asio::error::eof) ||
343 (ec == asio::error::operation_aborted))
347 if (ec.value() == 995)
350 onError(ec.value(), ec.category().name(), ec.message());
bool IsStarted() const noexcept
Is the server started?
std::shared_mutex _sessions_lock
std::shared_ptr< SSLSession > FindSession(const CppCommon::UUID &id)
Find a session with a given Id.
virtual void onStopped()
Handle server stopped notification.
virtual bool Multicast(const void *buffer, size_t size)
Multicast data to all connected sessions.
virtual bool Stop()
Stop the server.
int port() const noexcept
Get the server port number.
std::map< CppCommon::UUID, std::shared_ptr< SSLSession > > _sessions
virtual bool DisconnectAll()
Disconnect all connected sessions.
virtual void onStarted()
Handle server started notification.
bool option_reuse_port() const noexcept
Get the option: reuse port.
std::shared_ptr< SSLContext > & context() noexcept
Get the server SSL context.
virtual void onError(int error, const std::string &category, const std::string &message)
Handle error notification.
const std::string & address() const noexcept
Get the server address.
SSLServer(const std::shared_ptr< Service > &service, const std::shared_ptr< SSLContext > &context, int port, InternetProtocol protocol=InternetProtocol::IPv4)
Initialize SSL server with a given Asio service, SSL context and port number.
virtual bool Restart()
Restart the server.
virtual std::shared_ptr< SSLSession > CreateSession(const std::shared_ptr< SSLServer > &server)
Create SSL session factory method.
std::shared_ptr< Service > & service() noexcept
Get the Asio service.
virtual bool Start()
Start the server.
bool option_reuse_address() const noexcept
Get the option: reuse address.
AllocateHandler< THandler > make_alloc_handler(HandlerStorage &storage, THandler handler)
Helper function to wrap a handler object to add custom allocation.
InternetProtocol
Internet protocol.
@ IPv4
Internet Protocol version 4.
@ IPv6
Internet Protocol version 6.
C++ Server project definitions.