12 template <
class TServer,
class TSession>
18 _messages_received(0),
22 assert((
service !=
nullptr) &&
"ASIO service is invalid!");
24 throw CppCommon::ArgumentException(
"ASIO service is invalid!");
29 _endpoint = asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port);
32 _endpoint = asio::ip::tcp::endpoint(asio::ip::tcp::v6(), port);
39 template <
class TServer,
class TSession>
45 _messages_received(0),
49 assert((
service !=
nullptr) &&
"ASIO service is invalid!");
51 throw CppCommon::ArgumentException(
"ASIO service is invalid!");
53 _endpoint = asio::ip::tcp::endpoint(asio::ip::address::from_string(address), port);
58 template <
class TServer,
class TSession>
65 _messages_received(0),
69 assert((
service !=
nullptr) &&
"ASIO service is invalid!");
71 throw CppCommon::ArgumentException(
"ASIO service is invalid!");
76 template <
class TServer,
class TSession>
79 assert(!_initialized &&
"Asio is already initialed!");
84 websocketpp::lib::error_code ec;
85 _core.init_asio(_service->service().get(), ec);
95 template <
class TServer,
class TSession>
98 assert(_initialized &&
"Asio is not initialed!");
102 assert(!IsStarted() &&
"WebSocket server is already started!");
107 auto self(this->shared_from_this());
108 _service->service()->post([
this,
self]()
110 websocketpp::lib::error_code ec;
113 _core.set_access_channels(websocketpp::log::alevel::none);
114 _core.set_error_channels(websocketpp::log::elevel::none);
117 _core.set_open_handler([
this](websocketpp::connection_hdl connection) { RegisterSession(connection); });
118 _core.set_close_handler([
this](websocketpp::connection_hdl connection) { UnregisterSession(connection); });
121 _core.listen(_endpoint, ec);
131 _messages_received = 0;
142 _core.start_accept(ec);
154 template <
class TServer,
class TSession>
157 assert(IsStarted() &&
"WebSocket server is not started!");
162 auto self(this->shared_from_this());
163 _service->service()->post([
this,
self]()
166 websocketpp::lib::error_code ec;
167 _core.stop_listening(ec);
187 template <
class TServer,
class TSession>
194 CppCommon::Thread::Yield();
199 template <
class TServer,
class TSession>
202 assert((buffer !=
nullptr) &&
"Pointer to the buffer should not be equal to 'nullptr'!");
203 assert((size > 0) &&
"Buffer size should be greater than zero!");
204 if ((buffer ==
nullptr) || (size == 0))
211 std::lock_guard<std::mutex> locker(_multicast_lock);
214 std::vector<uint8_t> message((
const uint8_t*)buffer, ((
const uint8_t*)buffer) + size);
215 _multicast_buffer.emplace_back(std::make_tuple(message, opcode));
222 template <
class TServer,
class TSession>
229 std::lock_guard<std::mutex> locker(_multicast_lock);
232 _multicast_text.emplace_back(std::make_tuple(text, opcode));
239 template <
class TServer,
class TSession>
246 std::lock_guard<std::mutex> locker(_multicast_lock);
249 _multicast_messages.push_back(message);
256 template <
class TServer,
class TSession>
260 auto self(this->shared_from_this());
261 _service->Dispatch([
this,
self]()
263 std::lock_guard<std::mutex> locker(_multicast_lock);
266 for (
auto& session : _sessions)
268 for (
auto& message : _multicast_buffer)
269 session.second->Send(std::get<0>(message).data(), std::get<0>(message).size(), std::get<1>(message));
270 for (
auto& text : _multicast_text)
271 session.second->Send(std::get<0>(text), std::get<1>(text));
272 for (
auto& message : _multicast_messages)
273 session.second->Send(message);
277 _multicast_buffer.clear();
278 _multicast_text.clear();
279 _multicast_messages.clear();
283 template <
class TServer,
class TSession>
290 auto self(this->shared_from_this());
291 _service->Dispatch([
this,
self]()
294 for (
auto& session : _sessions)
295 session.second->Disconnect();
301 template <
class TServer,
class TSession>
305 auto self(this->shared_from_this());
306 auto session = std::make_shared<TSession>(
self);
307 _connections.insert(std::make_pair(connection, session));
308 _sessions.insert(std::make_pair(session->id(), session));
311 session->Connect(connection);
314 onConnected(session);
319 template <
class TServer,
class TSession>
320 inline void WebSocketServer<TServer, TSession>::UnregisterSession(websocketpp::connection_hdl connection)
323 auto it = _connections.find(connection);
324 if (it != _connections.end())
327 it->second->Disconnected();
331 template <
class TServer,
class TSession>
332 inline void WebSocketServer<TServer, TSession>::UnregisterSession(
const CppCommon::UUID&
id)
335 auto it = _sessions.find(
id);
336 if (it != _sessions.end())
339 onDisconnected(it->second);
342 _connections.erase(_connections.find(it->second->connection()));
349 template <
class TServer,
class TSession>
350 inline void WebSocketServer<TServer, TSession>::ClearBuffers()
352 std::lock_guard<std::mutex> locker(_multicast_lock);
354 _multicast_buffer.clear();
355 _multicast_text.clear();
356 _multicast_messages.clear();
359 template <
class TServer,
class TSession>
360 inline void WebSocketServer<TServer, TSession>::SendError(std::error_code ec)
362 onError(ec.value(), ec.category().name(), ec.message());
bool Restart()
Restart the server.
bool DisconnectAll()
Disconnect all connected sessions.
bool Multicast(const void *buffer, size_t size, websocketpp::frame::opcode::value opcode=websocketpp::frame::opcode::binary)
Multicast data to all connected sessions.
InternetProtocol
Internet protocol.
std::shared_ptr< Service > & service() noexcept
Get the Asio service.
Internet Protocol version 4.
C++ Server project definitions.
bool Start()
Start the server.
bool Stop()
Stop the server.
WebSocketServer(std::shared_ptr< Service > service, InternetProtocol protocol, int port)
Initialize WebSocket server with a given Asio service, protocol and port number.
WebSocketConnection::message_ptr WebSocketMessage
WebSocket message.
Internet Protocol version 6.