From ba9419b342918301fc1d521bd6ef9faa8b9fef69 Mon Sep 17 00:00:00 2001 From: Jocke Date: Mon, 8 Feb 2016 14:32:00 +0100 Subject: [PATCH] Moved UDP logic from Hybrid server/client to UDP server/client. fixed bug in Server::CheckForTimeOuts. --- include/Engine/Network/HybridClient.h | 16 +--- include/Engine/Network/HybridServer.h | 15 +--- include/Engine/Network/TCPClient.h | 3 +- include/Engine/Network/TCPServer.h | 6 +- include/Engine/Network/UDPClient.h | 24 +++++ include/Engine/Network/UDPServer.h | 25 ++++++ include/Game/Game.h | 5 ++ src/Engine/Network/Client.cpp | 3 +- src/Engine/Network/HybridClient.cpp | 66 +------------- src/Engine/Network/HybridServer.cpp | 117 +----------------------- src/Engine/Network/Server.cpp | 7 +- src/Engine/Network/TCPClient.cpp | 15 ++-- src/Engine/Network/TCPServer.cpp | 2 - src/Engine/Network/UDPClient.cpp | 66 ++++++++++++++ src/Engine/Network/UDPServer.cpp | 123 ++++++++++++++++++++++++++ src/Game/Game.cpp | 8 +- 16 files changed, 271 insertions(+), 230 deletions(-) create mode 100644 include/Engine/Network/UDPClient.h create mode 100644 include/Engine/Network/UDPServer.h create mode 100644 src/Engine/Network/UDPClient.cpp create mode 100644 src/Engine/Network/UDPServer.cpp diff --git a/include/Engine/Network/HybridClient.h b/include/Engine/Network/HybridClient.h index fb2777d4..8d96bf6e 100644 --- a/include/Engine/Network/HybridClient.h +++ b/include/Engine/Network/HybridClient.h @@ -1,25 +1,13 @@ #ifndef HybridClient_h__ #define HybridClient_h__ -#include "Client.h" - - -class HybridClient : public Client +class HybridClient { public: - HybridClient(ConfigFile* config); + HybridClient(); ~HybridClient(); - void Start(World* world, EventBroker* eventBroker); private: - // Assio UDP logic - boost::asio::ip::udp::endpoint m_ReceiverEndpoint; - boost::asio::io_service m_IOService; - boost::asio::ip::udp::socket m_Socket; - void connect(); - void readFromServer(); - int receive(char * data); - void send(Packet & packet); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/HybridServer.h b/include/Engine/Network/HybridServer.h index f12dc660..48d6fe63 100644 --- a/include/Engine/Network/HybridServer.h +++ b/include/Engine/Network/HybridServer.h @@ -1,25 +1,12 @@ #ifndef HybridServer_h__ #define HybridServer_h__ -#include "Server.h" -#include - -class HybridServer : public Server +class HybridServer { public: HybridServer(); ~HybridServer(); private: - // UDP logic - boost::asio::io_service m_IOService; - std::unique_ptr m_Socket; - boost::asio::ip::udp::endpoint m_ReceiverEndpoint; - - void readFromClients(); - void parseConnect(Packet & packet); - void send(Packet & packet, PlayerDefinition & playerDefinition); - void send(Packet & packet); - int receive(char * data); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/TCPClient.h b/include/Engine/Network/TCPClient.h index e90e049c..b16d541d 100644 --- a/include/Engine/Network/TCPClient.h +++ b/include/Engine/Network/TCPClient.h @@ -8,12 +8,11 @@ class TCPClient : public Client public: TCPClient(ConfigFile* config); ~TCPClient(); - void Start(World* world, EventBroker* eventBroker); private: // Assio TCP logic boost::asio::ip::tcp::endpoint m_Endpoint; boost::asio::io_service m_IOService; - boost::shared_ptr m_Socket; + std::unique_ptr m_Socket; void connect(); void readFromServer(); diff --git a/include/Engine/Network/TCPServer.h b/include/Engine/Network/TCPServer.h index 61e40639..6c52d10d 100644 --- a/include/Engine/Network/TCPServer.h +++ b/include/Engine/Network/TCPServer.h @@ -13,14 +13,14 @@ private: boost::asio::io_service m_IOService; std::unique_ptr acceptor; boost::shared_ptr lastReceivedSocket; - - void readFromClients(); + void acceptNewConnections(); void handle_accept(boost::shared_ptr socket, const boost::system::error_code & error); + void readFromClients(); + int receive(char * data, boost::asio::ip::tcp::socket& socket); void parseConnect(Packet & packet); void send(Packet & packet, PlayerDefinition & playerDefinition); void send(Packet & packet); - int receive(char * data, boost::asio::ip::tcp::socket& socket); }; #endif \ No newline at end of file diff --git a/include/Engine/Network/UDPClient.h b/include/Engine/Network/UDPClient.h new file mode 100644 index 00000000..abe34b3a --- /dev/null +++ b/include/Engine/Network/UDPClient.h @@ -0,0 +1,24 @@ +#ifndef UDPClient_h__ +#define UDPClient_h__ + +#include "Client.h" + + +class UDPClient : public Client +{ +public: + UDPClient(ConfigFile* config); + ~UDPClient(); +private: + // Assio UDP logic + boost::asio::io_service m_IOService; + boost::asio::ip::udp::endpoint m_ReceiverEndpoint; + boost::asio::ip::udp::socket m_Socket; + + void connect(); + void readFromServer(); + int receive(char * data); + void send(Packet & packet); +}; + +#endif \ No newline at end of file diff --git a/include/Engine/Network/UDPServer.h b/include/Engine/Network/UDPServer.h new file mode 100644 index 00000000..22c8c3e3 --- /dev/null +++ b/include/Engine/Network/UDPServer.h @@ -0,0 +1,25 @@ +#ifndef UDPServer_h__ +#define UDPServer_h__ + +#include "Server.h" +#include + +class UDPServer : public Server +{ +public: + UDPServer(); + ~UDPServer(); +private: + // UDP logic + boost::asio::io_service m_IOService; + boost::asio::ip::udp::endpoint m_ReceiverEndpoint; + std::unique_ptr m_Socket; + + void readFromClients(); + int receive(char * data); + void parseConnect(Packet & packet); + void send(Packet & packet, PlayerDefinition & playerDefinition); + void send(Packet & packet); +}; + +#endif \ No newline at end of file diff --git a/include/Game/Game.h b/include/Game/Game.h index 060f97f4..4faf6bbf 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -26,10 +26,15 @@ // Network #include #include "Network/Network.h" +// Hybrid #include "Network/HybridServer.h" #include "Network/HybridClient.h" +// TCP #include "Network/TCPClient.h" #include "Network/TCPServer.h" +// UDP +#include "Network/UDPServer.h" +#include "Network/UDPClient.h" // Sound #include "Sound/SoundSystem.h" diff --git a/src/Engine/Network/Client.cpp b/src/Engine/Network/Client.cpp index 13efad40..c7a8f0e6 100644 --- a/src/Engine/Network/Client.cpp +++ b/src/Engine/Network/Client.cpp @@ -17,7 +17,8 @@ Client::Client(ConfigFile* config) } Client::~Client() -{ } +{ +} void Client::Start(World* world, EventBroker* eventBroker) { diff --git a/src/Engine/Network/HybridClient.cpp b/src/Engine/Network/HybridClient.cpp index eabe109b..4200e8e3 100644 --- a/src/Engine/Network/HybridClient.cpp +++ b/src/Engine/Network/HybridClient.cpp @@ -1,72 +1,10 @@ #include "Network/HybridClient.h" -using namespace boost::asio::ip; -HybridClient::HybridClient(ConfigFile * config) : Client(config), m_Socket(m_IOService) -{ - m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); +HybridClient::HybridClient() +{ } HybridClient::~HybridClient() -{ - -} - -void HybridClient::Start(World* world, EventBroker* eventBroker) -{ - Client::Start(world, eventBroker); - m_Socket.connect(m_ReceiverEndpoint); -} - -void HybridClient::readFromServer() { - while (m_Socket.available()) { - bytesRead = receive(readBuffer); - if (bytesRead > 0) { - Packet packet(readBuffer, bytesRead); - parseMessageType(packet); - } - } -} - -int HybridClient::receive(char* data) -{ - boost::system::error_code error; - - int bytesReceived = m_Socket.receive_from(boost - ::asio::buffer((void*)data, BUFFERSIZE), - m_ReceiverEndpoint, - 0, error); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataReceived += bytesReceived; - m_NetworkData.DataReceivedThisInterval += bytesReceived; - m_NetworkData.AmountOfMessagesReceived++; - } - if (error) { - //LOG_ERROR("receive: %s", error.message().c_str()); - } - return bytesReceived; -} - -void HybridClient::send(Packet& packet) -{ - m_Socket.send_to(boost::asio::buffer( - packet.Data(), - packet.Size()), - m_ReceiverEndpoint, 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - m_NetworkData.AmountOfMessagesSent++; - } -} - -void HybridClient::connect() -{ - Packet packet(MessageType::Connect, m_SendPacketID); - packet.WriteString(m_PlayerName); - m_StartPingTime = std::clock(); - send(packet); } \ No newline at end of file diff --git a/src/Engine/Network/HybridServer.cpp b/src/Engine/Network/HybridServer.cpp index 6c22bab7..bfcdaee0 100644 --- a/src/Engine/Network/HybridServer.cpp +++ b/src/Engine/Network/HybridServer.cpp @@ -2,123 +2,8 @@ HybridServer::HybridServer() { - m_Socket = std::unique_ptr(new boost::asio::ip::udp::socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666))); - } HybridServer::~HybridServer() -{ } - - -void HybridServer::readFromClients() { - while (m_Socket->available()) { - try { - bytesRead = receive(readBuffer); - m_Address = m_ReceiverEndpoint.address(); - m_Port = m_ReceiverEndpoint.port(); - Packet packet(readBuffer, bytesRead); - parseMessageType(packet); - } catch (const std::exception& err) { - //LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what()); - } - } - std::clock_t currentTime = std::clock(); - // Send snapshot - if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { - sendSnapshot(); - previousSnapshotMessage = currentTime; - } - - // Send pings each - if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { - sendPing(); - previousePingMessage = currentTime; - } - - // Time out logic - if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { - checkForTimeOuts(); - timOutTimer = currentTime; - } -} - -void HybridServer::parseConnect(Packet& packet) -{ - LOG_INFO("Parsing connections"); - // Check if player is already connected - if (GetPlayerIDFromEndpoint() != -1) { - return; - } - // Create a new player - PlayerDefinition pd; - pd.EntityID = 0; // Overlook this - pd.Endpoint = m_ReceiverEndpoint; - pd.Address = m_ReceiverEndpoint.address(); - pd.Port = m_ReceiverEndpoint.port(); - pd.Name = packet.ReadString(); - pd.PacketID = 0; - pd.StopTime = std::clock(); - m_ConnectedPlayers[m_NextPlayerID++] = pd; - LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str()); - - // Send a message to the player that connected - Packet connnectPacket(MessageType::Connect, pd.PacketID); - send(connnectPacket); - - // Send notification that a player has connected - Packet notificationPacket(MessageType::PlayerConnected); - broadcast(notificationPacket); -} - -void HybridServer::send(Packet& packet, PlayerDefinition & playerDefinition) -{ - try { - int bytesSent = m_Socket->send_to( - boost::asio::buffer(packet.Data(), packet.Size()), - playerDefinition.Endpoint, - 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - m_NetworkData.AmountOfMessagesSent++; - } - } catch (const boost::system::system_error& e) { - // TODO: Clean up invalid endpoints out of m_ConnectedPlayers later - playerDefinition.Endpoint = boost::asio::ip::udp::endpoint(); - } -} -// Send back to endpoint of received packet -void HybridServer::send(Packet & packet) -{ - m_Socket->send_to( - boost::asio::buffer( - packet.Data(), - packet.Size()), - m_ReceiverEndpoint, - 0); - if (isReadingData) { - // Network Debug data - m_NetworkData.TotalDataSent += packet.Size(); - m_NetworkData.DataSentThisInterval += packet.Size(); - } -} - - -int HybridServer::receive(char * data) -{ - unsigned int length = m_Socket->receive_from( - boost::asio::buffer((void*)data - , BUFFERSIZE) - , m_ReceiverEndpoint, 0); - // Network Debug data - if (isReadingData) { - m_NetworkData.TotalDataReceived += length; - m_NetworkData.DataReceivedThisInterval += length; - m_NetworkData.AmountOfMessagesReceived++; - } - return length; -} - - +} \ No newline at end of file diff --git a/src/Engine/Network/Server.cpp b/src/Engine/Network/Server.cpp index 55f59a03..344efba6 100644 --- a/src/Engine/Network/Server.cpp +++ b/src/Engine/Network/Server.cpp @@ -9,7 +9,6 @@ Server::Server() } Server::~Server() { - } void Server::Start(World* world, EventBroker* eventBroker) { @@ -154,16 +153,20 @@ void Server::checkForTimeOuts() int startPing = 1000 * m_StartPingTime / static_cast(CLOCKS_PER_SEC); + std::vector playersToRemove; for (auto& kv : m_ConnectedPlayers) { if (kv.second.Address != boost::asio::ip::address()) { int stopPing = 1000 * kv.second.StopTime / static_cast(CLOCKS_PER_SEC); if (startPing > stopPing + m_TimeoutMs) { LOG_INFO("User %i timed out!", kv.second.Name); - disconnect(kv.first); + playersToRemove.push_back(kv.first); } } } + for (size_t i = 0; i < playersToRemove.size(); i++) { + disconnect(playersToRemove.at(i)); + } } void Server::parseDisconnect() diff --git a/src/Engine/Network/TCPClient.cpp b/src/Engine/Network/TCPClient.cpp index 3d7261b7..545db491 100644 --- a/src/Engine/Network/TCPClient.cpp +++ b/src/Engine/Network/TCPClient.cpp @@ -5,7 +5,7 @@ using namespace boost::asio::ip; TCPClient::TCPClient(ConfigFile * config) : Client(config) { m_Endpoint = tcp::endpoint(boost::asio::ip::address::from_string(address), port); - m_Socket = boost::shared_ptr(new tcp::socket(m_IOService, m_Endpoint)); + m_Socket = std::unique_ptr(new tcp::socket(m_IOService, m_Endpoint)); tcp::no_delay option(true); m_Socket->set_option(option); } @@ -15,10 +15,6 @@ TCPClient::~TCPClient() } -void TCPClient::Start(World * world, EventBroker * eventBroker) -{ - Client::Start(world, eventBroker); -} void TCPClient::connect() { if (!m_IsConnected) { @@ -34,7 +30,7 @@ void TCPClient::connect() } } } -// TODO FIX CRASH TCP CLIENT SEVER DISCONNECTS FIRST + void TCPClient::readFromServer() { while (m_Socket->available()) { @@ -50,14 +46,14 @@ int TCPClient::receive(char * data) // Read size of packet int bytesReceived = m_Socket->read_some(boost ::asio::buffer((void*)data, sizeof(int)), - error); + error); int sizeOfPacket = 0; memcpy(&sizeOfPacket, data, sizeof(int)); // Read the rest of the message bytesReceived += m_Socket->read_some(boost ::asio::buffer((void*)(data + bytesReceived), sizeOfPacket - bytesReceived), - error); + error); // Network Debug data if (isReadingData) { m_NetworkData.TotalDataReceived += bytesReceived; @@ -73,9 +69,10 @@ int TCPClient::receive(char * data) void TCPClient::send(Packet & packet) { packet.UpdateSize(); + boost::system::error_code error; m_Socket->send(boost::asio::buffer( packet.Data(), - packet.Size())); + packet.Size()), 0, error); // Network Debug data if (isReadingData) { m_NetworkData.TotalDataSent += packet.Size(); diff --git a/src/Engine/Network/TCPServer.cpp b/src/Engine/Network/TCPServer.cpp index caf37ee8..d523bf47 100644 --- a/src/Engine/Network/TCPServer.cpp +++ b/src/Engine/Network/TCPServer.cpp @@ -8,7 +8,6 @@ TCPServer::TCPServer() TCPServer::~TCPServer() { - } void TCPServer::readFromClients() @@ -135,7 +134,6 @@ void TCPServer::send(Packet & packet) } } -//boost::shared_ptr socket int TCPServer::receive(char * data, boost::asio::ip::tcp::socket& socket) { boost::system::error_code error; diff --git a/src/Engine/Network/UDPClient.cpp b/src/Engine/Network/UDPClient.cpp new file mode 100644 index 00000000..26e895d5 --- /dev/null +++ b/src/Engine/Network/UDPClient.cpp @@ -0,0 +1,66 @@ +#include "Network/UDPClient.h" + +using namespace boost::asio::ip; + +UDPClient::UDPClient(ConfigFile * config) : Client(config), m_Socket(m_IOService) +{ + m_ReceiverEndpoint = udp::endpoint(boost::asio::ip::address::from_string(address), port); + m_Socket.connect(m_ReceiverEndpoint); +} + +UDPClient::~UDPClient() +{ +} + +void UDPClient::readFromServer() +{ + while (m_Socket.available()) { + bytesRead = receive(readBuffer); + if (bytesRead > 0) { + Packet packet(readBuffer, bytesRead); + parseMessageType(packet); + } + } +} + +int UDPClient::receive(char* data) +{ + boost::system::error_code error; + + int bytesReceived = m_Socket.receive_from(boost + ::asio::buffer((void*)data, BUFFERSIZE), + m_ReceiverEndpoint, + 0, error); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataReceived += bytesReceived; + m_NetworkData.DataReceivedThisInterval += bytesReceived; + m_NetworkData.AmountOfMessagesReceived++; + } + if (error) { + //LOG_ERROR("receive: %s", error.message().c_str()); + } + return bytesReceived; +} + +void UDPClient::send(Packet& packet) +{ + m_Socket.send_to(boost::asio::buffer( + packet.Data(), + packet.Size()), + m_ReceiverEndpoint, 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } +} + +void UDPClient::connect() +{ + Packet packet(MessageType::Connect, m_SendPacketID); + packet.WriteString(m_PlayerName); + m_StartPingTime = std::clock(); + send(packet); +} \ No newline at end of file diff --git a/src/Engine/Network/UDPServer.cpp b/src/Engine/Network/UDPServer.cpp new file mode 100644 index 00000000..1e62c10a --- /dev/null +++ b/src/Engine/Network/UDPServer.cpp @@ -0,0 +1,123 @@ +#include "Network/UDPServer.h" + +UDPServer::UDPServer() +{ + m_Socket = std::unique_ptr(new boost::asio::ip::udp::socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666))); +} + +UDPServer::~UDPServer() +{ +} + +void UDPServer::readFromClients() +{ + while (m_Socket->available()) { + try { + bytesRead = receive(readBuffer); + m_Address = m_ReceiverEndpoint.address(); + m_Port = m_ReceiverEndpoint.port(); + Packet packet(readBuffer, bytesRead); + parseMessageType(packet); + } catch (const std::exception& err) { + //LOG_ERROR("%i: Read from client crashed %s", m_PacketID, err.what()); + } + } + std::clock_t currentTime = std::clock(); + // Send snapshot + if (snapshotInterval < (1000 * (currentTime - previousSnapshotMessage) / (double)CLOCKS_PER_SEC)) { + sendSnapshot(); + previousSnapshotMessage = currentTime; + } + + // Send pings each + if (pingIntervalMs < (1000 * (currentTime - previousePingMessage) / (double)CLOCKS_PER_SEC)) { + sendPing(); + previousePingMessage = currentTime; + } + + // Time out logic + if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { + checkForTimeOuts(); + timOutTimer = currentTime; + } +} + +void UDPServer::parseConnect(Packet& packet) +{ + LOG_INFO("Parsing connections"); + // Check if player is already connected + if (GetPlayerIDFromEndpoint() != -1) { + return; + } + // Create a new player + PlayerDefinition pd; + pd.EntityID = 0; // Overlook this + pd.Endpoint = m_ReceiverEndpoint; + pd.Address = m_ReceiverEndpoint.address(); + pd.Port = m_ReceiverEndpoint.port(); + pd.Name = packet.ReadString(); + pd.PacketID = 0; + pd.StopTime = std::clock(); + m_ConnectedPlayers[m_NextPlayerID++] = pd; + LOG_INFO("Spectator \"%s\" connected on IP: %s", pd.Name.c_str(), pd.Endpoint.address().to_string().c_str()); + + // Send a message to the player that connected + Packet connnectPacket(MessageType::Connect, pd.PacketID); + send(connnectPacket); + + // Send notification that a player has connected + Packet notificationPacket(MessageType::PlayerConnected); + broadcast(notificationPacket); +} + +void UDPServer::send(Packet& packet, PlayerDefinition & playerDefinition) +{ + try { + int bytesSent = m_Socket->send_to( + boost::asio::buffer(packet.Data(), packet.Size()), + playerDefinition.Endpoint, + 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + m_NetworkData.AmountOfMessagesSent++; + } + } catch (const boost::system::system_error& e) { + // TODO: Clean up invalid endpoints out of m_ConnectedPlayers later + playerDefinition.Endpoint = boost::asio::ip::udp::endpoint(); + } +} +// Send back to endpoint of received packet +void UDPServer::send(Packet & packet) +{ + m_Socket->send_to( + boost::asio::buffer( + packet.Data(), + packet.Size()), + m_ReceiverEndpoint, + 0); + if (isReadingData) { + // Network Debug data + m_NetworkData.TotalDataSent += packet.Size(); + m_NetworkData.DataSentThisInterval += packet.Size(); + } +} + + +int UDPServer::receive(char * data) +{ + unsigned int length = m_Socket->receive_from( + boost::asio::buffer((void*)data + , BUFFERSIZE) + , m_ReceiverEndpoint, 0); + // Network Debug data + if (isReadingData) { + m_NetworkData.TotalDataReceived += length; + m_NetworkData.DataReceivedThisInterval += length; + m_NetworkData.AmountOfMessagesReceived++; + } + return length; +} + + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index a2bde7cb..ccbf79c9 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -181,13 +181,15 @@ void Game::networkFunction() bool isServer = m_Config->Get("Networking.IsServer", false); if (!isServer) { m_IsClientOrServer = true; + m_ClientOrServer = new UDPClient(m_Config); //m_ClientOrServer = new TCPClient(m_Config); - m_ClientOrServer = new HybridClient(m_Config); + //m_ClientOrServer = new HybridClient(m_Config); } if (isServer) { m_IsClientOrServer = true; - //m_ClientOrServer = new TCPServer(); - m_ClientOrServer = new HybridServer(); + m_ClientOrServer = new UDPServer(); + // m_ClientOrServer = new TCPServer(); + //m_ClientOrServer = new HybridServer(); } m_ClientOrServer->Start(m_World, m_EventBroker);