Implemented primitive server "heartbeat" logic, which sends server info from server to client without being connected.

This commit is contained in:
stiffly
2016-02-17 15:51:26 +01:00
parent 4432891437
commit fdc8f753cb
8 changed files with 61 additions and 4 deletions
+3
View File
@@ -14,6 +14,7 @@
#include "Network/MessageType.h" #include "Network/MessageType.h"
#include "Network/PlayerDefinition.h" #include "Network/PlayerDefinition.h"
#include "Network/UDPClient.h" #include "Network/UDPClient.h"
#include "Network/UDPServer.h" //LOL
#include "Network/TCPClient.h" #include "Network/TCPClient.h"
#include "Network/SnapshotDefinitions.h" #include "Network/SnapshotDefinitions.h"
#include "Core/World.h" #include "Core/World.h"
@@ -82,6 +83,7 @@ public:
void parseTCPConnect(Packet& packet); void parseTCPConnect(Packet& packet);
void parsePlayerConnected(Packet& packet); void parsePlayerConnected(Packet& packet);
void parsePing(); void parsePing();
void parseHeartbeat(Packet& packet);
void parseKick(); void parseKick();
void parsePlayersSpawned(Packet& packet); void parsePlayersSpawned(Packet& packet);
void parseEntityDeletion(Packet& packet); void parseEntityDeletion(Packet& packet);
@@ -112,6 +114,7 @@ public:
void parsePlayerDamage(Packet& packet); void parsePlayerDamage(Packet& packet);
private: private:
UDPClient m_Unreliable; UDPClient m_Unreliable;
UDPServer m_Heartbeat;
TCPClient m_Reliable; TCPClient m_Reliable;
}; };
+1
View File
@@ -19,6 +19,7 @@ enum class MessageType
EntityDeleted, EntityDeleted,
ComponentDeleted, ComponentDeleted,
PlayerTransform, PlayerTransform,
Heartbeat,
Invalid Invalid
}; };
+5
View File
@@ -8,6 +8,7 @@
#include "Network/TCPServer.h" #include "Network/TCPServer.h"
#include "Network/UDPServer.h" #include "Network/UDPServer.h"
#include "Network/UDPClient.h" //LOL
#include "Network/MessageType.h" #include "Network/MessageType.h"
#include "Network/PlayerDefinition.h" #include "Network/PlayerDefinition.h"
#include "Core/World.h" #include "Core/World.h"
@@ -32,6 +33,7 @@ private:
// Network channels // Network channels
TCPServer m_Reliable; TCPServer m_Reliable;
UDPServer m_Unreliable; UDPServer m_Unreliable;
UDPClient m_Heartbeat;
// dont forget to set these in the childrens receive logic // dont forget to set these in the childrens receive logic
boost::asio::ip::address m_Address; boost::asio::ip::address m_Address;
int m_Port = 27666; int m_Port = 27666;
@@ -44,11 +46,13 @@ private:
// time for previouse message // time for previouse message
std::clock_t previousePingMessage = std::clock(); std::clock_t previousePingMessage = std::clock();
std::clock_t previousSnapshotMessage = std::clock(); std::clock_t previousSnapshotMessage = std::clock();
std::clock_t previousHeartbeat = std::clock();
std::clock_t timOutTimer = std::clock(); std::clock_t timOutTimer = std::clock();
// How often we send messages (milliseconds) // How often we send messages (milliseconds)
float pingIntervalMs; float pingIntervalMs;
float snapshotInterval; float snapshotInterval;
float heartbeatInterval = 5000;
int checkTimeOutInterval = 100; int checkTimeOutInterval = 100;
int m_NextPlayerID = 0; int m_NextPlayerID = 0;
std::vector<Events::InputCommand> m_InputCommandsToBroadcast; std::vector<Events::InputCommand> m_InputCommandsToBroadcast;
@@ -67,6 +71,7 @@ private:
void addChildrenToPacket(Packet& packet, EntityID entityID); void addChildrenToPacket(Packet& packet, EntityID entityID);
void addInputCommandsToPacket(Packet& packet); void addInputCommandsToPacket(Packet& packet);
void sendPing(); void sendPing();
void sendHeartBeat();
void checkForTimeOuts(); void checkForTimeOuts();
void disconnect(PlayerID playerID); void disconnect(PlayerID playerID);
void parseMessageType(Packet& packet); void parseMessageType(Packet& packet);
+1
View File
@@ -8,6 +8,7 @@ class UDPServer : public NetworkServer
{ {
public: public:
UDPServer(); UDPServer();
UDPServer(int port);
~UDPServer(); ~UDPServer();
void AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers); void AcceptNewConnections(int& nextPlayerID, std::map<PlayerID, PlayerDefinition>& connectedPlayers);
void Receive(Packet & packet, PlayerDefinition & playerDefinition); void Receive(Packet & packet, PlayerDefinition & playerDefinition);
+25 -1
View File
@@ -3,6 +3,7 @@ using namespace boost::asio::ip;
Client::Client(World* world, EventBroker* eventBroker) Client::Client(World* world, EventBroker* eventBroker)
: Network(world, eventBroker) : Network(world, eventBroker)
, m_Heartbeat(13)
{ {
// Asumes root node is EntityID_Invalid // Asumes root node is EntityID_Invalid
insertIntoServerClientMaps(EntityID_Invalid, EntityID_Invalid); insertIntoServerClientMaps(EntityID_Invalid, EntityID_Invalid);
@@ -65,7 +66,15 @@ void Client::Update()
} }
} }
while (m_Heartbeat.IsSocketAvailable()) {
Packet packet(MessageType::Invalid);
PlayerDefinition localArea;
localArea.Endpoint = boost::asio::ip::udp::endpoint(boost::asio::ip::address().from_string("127.0.0.1"), 13);
m_Heartbeat.Receive(packet, localArea);
if(packet.GetMessageType() == MessageType::Heartbeat) {
parseHeartbeat(packet);
}
}
if (m_IsConnected) { if (m_IsConnected) {
// Don't send 1 input in 1 packet, bunch em up. // Don't send 1 input in 1 packet, bunch em up.
if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) { if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) {
@@ -119,6 +128,9 @@ void Client::parseMessageType(Packet& packet)
case MessageType::ComponentDeleted: case MessageType::ComponentDeleted:
parseComponentDeletion(packet); parseComponentDeletion(packet);
break; break;
case MessageType::Heartbeat:
parseHeartbeat(packet);
break;
case MessageType::OnPlayerDamage: case MessageType::OnPlayerDamage:
parsePlayerDamage(packet); parsePlayerDamage(packet);
break; break;
@@ -173,6 +185,18 @@ void Client::parsePing()
m_Reliable.Send(packet); m_Reliable.Send(packet);
} }
void Client::parseHeartbeat(Packet& packet)
{
// Pop size, message type, and ID
packet.ReadPrimitive<int>();
packet.ReadPrimitive<int>();
packet.ReadPrimitive<int>();
std::string serverName = packet.ReadString();
int playersConnected = packet.ReadPrimitive<int>();
LOG_INFO("Serverlist\nName\tPlayers\n%s\t%i\n", serverName.c_str(), playersConnected);
}
void Client::parseKick() void Client::parseKick()
{ {
LOG_WARNING("You have been kicked from the server."); LOG_WARNING("You have been kicked from the server.");
+17 -1
View File
@@ -13,12 +13,13 @@ Server::Server(World* world, EventBroker* eventBroker, int port)
EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted); EVENT_SUBSCRIBE_MEMBER(m_EComponentDeleted, &Server::OnComponentDeleted);
EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Server::OnPlayerDamage); EVENT_SUBSCRIBE_MEMBER(m_EPlayerDamage, &Server::OnPlayerDamage);
// Bind // BindWW
if (port == 0) { if (port == 0) {
port = config->Get<float>("Networking.Port", 27666); port = config->Get<float>("Networking.Port", 27666);
} }
m_Port = port; m_Port = port;
LOG_INFO("Server initialized and bound to port %i", port); LOG_INFO("Server initialized and bound to port %i", port);
m_Heartbeat.Connect("Server", "127.0.0.1", 13);
} }
Server::~Server() Server::~Server()
@@ -58,6 +59,7 @@ void Server::Update()
parseMessageType(packet); parseMessageType(packet);
} }
} }
// Check if players have disconnected // Check if players have disconnected
for (int i = 0; i < m_PlayersToDisconnect.size(); i++) { for (int i = 0; i < m_PlayersToDisconnect.size(); i++) {
disconnect(m_PlayersToDisconnect.at(i)); disconnect(m_PlayersToDisconnect.at(i));
@@ -75,6 +77,11 @@ void Server::Update()
sendPing(); sendPing();
previousePingMessage = currentTime; previousePingMessage = currentTime;
} }
// Server heartbeat (display server list on clients)
if (heartbeatInterval < (1000 * (currentTime - previousHeartbeat) / (double)CLOCKS_PER_SEC)) {
sendHeartBeat();
previousHeartbeat = currentTime;
}
// Time out logic // Time out logic
if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) { if (checkTimeOutInterval < (1000 * (currentTime - timOutTimer) / (double)CLOCKS_PER_SEC)) {
checkForTimeOuts(); checkForTimeOuts();
@@ -230,6 +237,15 @@ void Server::sendPing()
reliableBroadcast(packet); reliableBroadcast(packet);
} }
void Server::sendHeartBeat()
{
Packet packet(MessageType::Heartbeat);
packet.WriteString("This is a servername"); // server name
packet.WritePrimitive<int>(m_ConnectedPlayers.size());
m_Heartbeat.Send(packet);
}
void Server::checkForTimeOuts() void Server::checkForTimeOuts()
{ {
double startPing = 1000 * m_StartPingTime double startPing = 1000 * m_StartPingTime
+7
View File
@@ -5,6 +5,11 @@ UDPServer::UDPServer()
m_Socket = std::unique_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666))); m_Socket = std::unique_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 27666)));
} }
UDPServer::UDPServer(int port)
{
m_Socket = std::unique_ptr<boost::asio::ip::udp::socket>(new boost::asio::ip::udp::socket(m_IOService, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), port)));
}
UDPServer::~UDPServer() UDPServer::~UDPServer()
{ } { }
@@ -31,6 +36,8 @@ void UDPServer::Send(Packet & packet)
0); 0);
} }
void UDPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition) void UDPServer::Receive(Packet & packet, PlayerDefinition & playerDefinition)
{ {
int bytesRead = readBuffer(m_ReadBuffer); int bytesRead = readBuffer(m_ReadBuffer);