Added network metrics logging and reactored code.

This commit is contained in:
Jocke
2016-01-22 10:32:54 +01:00
parent cd67253173
commit 6cd073c3c8
10 changed files with 176 additions and 45 deletions
+3 -3
View File
@@ -61,21 +61,21 @@ private:
SnapshotDefinitions m_NextSnapshot; SnapshotDefinitions m_NextSnapshot;
double m_DurationOfPingTime; double m_DurationOfPingTime;
std::clock_t m_StartPingTime; std::clock_t m_StartPingTime;
std::clock_t m_TimeSinceSentInputs;
unsigned int m_SendInputIntervalMs = 33;
std::vector<Events::InputCommand> m_InputCommandBuffer; std::vector<Events::InputCommand> m_InputCommandBuffer;
// Private member functions // Private member functions
void readFromServer(); void readFromServer();
int receive(char* data, size_t length); int receive(char* data);
void send(Packet& packet); void send(Packet& packet);
void connect(); void connect();
void disconnect(); void disconnect();
void ping();
void parseMessageType(Packet& packet); void parseMessageType(Packet& packet);
void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType); void updateFields(Packet& packet, const ComponentInfo& componentInfo, const EntityID& entityID, const std::string& componentType);
void parseConnect(Packet& packet); void parseConnect(Packet& packet);
void parsePlayerConnected(Packet& packet); void parsePlayerConnected(Packet& packet);
void parsePing(); void parsePing();
void parseServerPing();
void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType); void InterpolateFields(Packet & packet, const ComponentInfo & componentInfo, const EntityID & entityID, const std::string & componentType);
void parseSnapshot(Packet& packet); void parseSnapshot(Packet& packet);
void identifyPacketLoss(); void identifyPacketLoss();
+1 -2
View File
@@ -7,8 +7,7 @@ enum class MessageType
{ {
Connect, Connect,
Disconnect, Disconnect,
ClientPing, Ping,
ServerPing,
Message, Message,
Snapshot, Snapshot,
OnInputCommand, OnInputCommand,
+13
View File
@@ -1,9 +1,14 @@
#ifndef Network_h__ #ifndef Network_h__
#define Network_h__ #define Network_h__
#include <ctime>
#include "Core/World.h" #include "Core/World.h"
#include "Core/EventBroker.h" #include "Core/EventBroker.h"
#include "Network/Packet.h" #include "Network/Packet.h"
#include "Network/NetworkData.h"
#include <fstream>
#include <iostream>
#define MAXCONNECTIONS 8 #define MAXCONNECTIONS 8
#define INPUTSIZE 4097 #define INPUTSIZE 4097
@@ -15,6 +20,14 @@ public:
virtual ~Network() { }; virtual ~Network() { };
virtual void Start(World* m_world, EventBroker *eventBroker) = 0; virtual void Start(World* m_world, EventBroker *eventBroker) = 0;
virtual void Update() = 0; virtual void Update() = 0;
protected:
// For Debug
bool isReadingData = false;
NetworkData m_NetworkData;
unsigned int m_SaveDataIntervalMs = 1000;
std::clock_t m_SaveDataTimer;
void saveToFile();
void updateNetworkData();
}; };
#endif #endif
+18
View File
@@ -0,0 +1,18 @@
#ifndef NetworkData_h__
#define NetworkData_h__
#include <vector>
struct NetworkData {
unsigned int TotalTime = 0;
unsigned int TotalDataReceived = 0;
unsigned int TotalDataSent = 0;
unsigned int AmountOfMessagesReceived = 0;
unsigned int AmountOfMessagesSent = 0;
// Interval based
unsigned int DataReceivedThisInterval = 0;
unsigned int DataSentThisInterval = 0;
// pair: first=reveived, second=send
std::vector<std::pair<unsigned int, unsigned int>> BandwidthBytes;
};
#endif
+2
View File
@@ -55,12 +55,14 @@ public:
char* Data() { return m_Data; }; char* Data() { return m_Data; };
unsigned int DataReadSize() { return m_ReturnDataOffset; } unsigned int DataReadSize() { return m_ReturnDataOffset; }
unsigned int MaxSize() { return m_MaxPacketSize; } unsigned int MaxSize() { return m_MaxPacketSize; }
unsigned int HeaderSize() { return m_HeaderSize; }
private: private:
char* m_Data; char* m_Data;
unsigned int m_ReturnDataOffset = 0; unsigned int m_ReturnDataOffset = 0;
int m_Offset = 0; int m_Offset = 0;
unsigned int m_MaxPacketSize = 512; unsigned int m_MaxPacketSize = 512;
unsigned int m_HeaderSize = 0;
void resizeData(); void resizeData();
}; };
+2 -2
View File
@@ -54,7 +54,7 @@ private:
unsigned int m_PreviousPacketID = 0; unsigned int m_PreviousPacketID = 0;
// Private member functions // Private member functions
int receive(char* data, size_t length); int receive(char* data);
void readFromClients(); void readFromClients();
void send(Packet& packet, int playerID); void send(Packet& packet, int playerID);
void send(Packet& packet); void send(Packet& packet);
@@ -69,7 +69,7 @@ private:
void parseConnect(Packet& packet); void parseConnect(Packet& packet);
void parseDisconnect(); void parseDisconnect();
void parseClientPing(); void parseClientPing();
void parseServerPing(); void parsePing();
void identifyPacketLoss(); void identifyPacketLoss();
void createPlayer(); void createPlayer();
int GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint); int GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint);
+34 -23
View File
@@ -7,6 +7,8 @@ Client::Client(ConfigFile* config) : m_Socket(m_IOService)
{ {
// Asumes root node is EntityID 0 // Asumes root node is EntityID 0
insertIntoServerClientMaps(0, 0); insertIntoServerClientMaps(0, 0);
// Init timer
m_TimeSinceSentInputs = std::clock();
// Default is local host // Default is local host
std::string address = config->Get<std::string>("Networking.Address", "127.0.0.1"); std::string address = config->Get<std::string>("Networking.Address", "127.0.0.1");
int port = config->Get<int>("Networking.Port", 13); int port = config->Get<int>("Networking.Port", 13);
@@ -37,19 +39,24 @@ void Client::Update()
readFromServer(); readFromServer();
if (m_IsConnected) { if (m_IsConnected) {
hasServerTimedOut(); hasServerTimedOut();
// Don't sent 1 input in 1 packet, bunch em up.
if (m_SendInputIntervalMs < (1000 * (std::clock() - m_TimeSinceSentInputs) / (double)CLOCKS_PER_SEC)) {
sendInputCommands();
m_TimeSinceSentInputs = std::clock();
}
} }
Network::Update();
} }
void Client::readFromServer() void Client::readFromServer()
{ {
while (m_Socket.available()) { while (m_Socket.available()) {
bytesRead = receive(readBuf, INPUTSIZE); bytesRead = receive(readBuf);
if (bytesRead > 0) { if (bytesRead > 0) {
Packet packet(readBuf, bytesRead); Packet packet(readBuf, bytesRead);
parseMessageType(packet); parseMessageType(packet);
} }
} }
sendInputCommands();
} }
void Client::parseMessageType(Packet& packet) void Client::parseMessageType(Packet& packet)
@@ -66,12 +73,9 @@ void Client::parseMessageType(Packet& packet)
case MessageType::Connect: case MessageType::Connect:
parseConnect(packet); parseConnect(packet);
break; break;
case MessageType::ClientPing: case MessageType::Ping:
parsePing(); parsePing();
break; break;
case MessageType::ServerPing:
parseServerPing();
break;
case MessageType::Message: case MessageType::Message:
break; break;
case MessageType::Snapshot: case MessageType::Snapshot:
@@ -99,11 +103,6 @@ void Client::parsePlayerConnected(Packet & packet)
} }
void Client::parsePing() void Client::parsePing()
{
}
void Client::parseServerPing()
{ {
// Might miss connect message so set it here instead. // Might miss connect message so set it here instead.
m_IsConnected = true; m_IsConnected = true;
@@ -112,7 +111,7 @@ void Client::parseServerPing()
LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime); LOG_INFO("%i: response time with ctime(ms): %f", m_PacketID, m_DurationOfPingTime);
m_StartPingTime = std::clock(); m_StartPingTime = std::clock();
Packet packet(MessageType::ServerPing, m_SendPacketID); Packet packet(MessageType::Ping, m_SendPacketID);
packet.WriteString("Ping recieved"); packet.WriteString("Ping recieved");
send(packet); send(packet);
} }
@@ -211,15 +210,20 @@ void Client::parseSnapshot(Packet& packet)
} }
} }
int Client::receive(char* data, size_t length) int Client::receive(char* data)
{ {
boost::system::error_code error; boost::system::error_code error;
int bytesReceived = m_Socket.receive_from(boost int bytesReceived = m_Socket.receive_from(boost
::asio::buffer((void*)data, length), ::asio::buffer((void*)data, INPUTSIZE),
m_ReceiverEndpoint, m_ReceiverEndpoint,
0, error); 0, error);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataReceived += bytesReceived;
m_NetworkData.DataReceivedThisInterval += bytesReceived;
m_NetworkData.AmountOfMessagesReceived++;
}
if (error) { if (error) {
//LOG_ERROR("receive: %s", error.message().c_str()); //LOG_ERROR("receive: %s", error.message().c_str());
} }
@@ -232,6 +236,12 @@ void Client::send(Packet& packet)
packet.Data(), packet.Data(),
packet.Size()), packet.Size()),
m_ReceiverEndpoint, 0); m_ReceiverEndpoint, 0);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataSent += packet.Size();
m_NetworkData.DataSentThisInterval += packet.Size();
m_NetworkData.AmountOfMessagesSent++;
}
} }
void Client::connect() void Client::connect()
@@ -250,14 +260,6 @@ void Client::disconnect()
send(packet); send(packet);
} }
void Client::ping()
{
//Packet packet(MessageType::Connect, m_SendPacketID);
//packet.WriteString("Ping");
//m_StartPingTime = std::clock();
//send(packet);
}
bool Client::OnInputCommand(const Events::InputCommand & e) bool Client::OnInputCommand(const Events::InputCommand & e)
{ {
if (e.Command == "ConnectToServer") { // Connect for now if (e.Command == "ConnectToServer") { // Connect for now
@@ -275,6 +277,15 @@ bool Client::OnInputCommand(const Events::InputCommand & e)
if (e.Value > 0) { if (e.Value > 0) {
becomePlayer(); becomePlayer();
} }
} else if (e.Command == "LogNetworkBandwidth") {
if (e.Value > 0) {
// Save to file if we no longer want to read data.
if (isReadingData) {
saveToFile();
}
isReadingData = !isReadingData;
m_SaveDataTimer = std::clock();
}
} else { } else {
m_InputCommandBuffer.push_back(e); m_InputCommandBuffer.push_back(e);
//LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); //LOG_DEBUG("Client::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
+61
View File
@@ -0,0 +1,61 @@
#include "Network/Network.h"
void Network::Update()
{
updateNetworkData();
}
void Network::saveToFile()
{
std::ofstream outfile;
time_t t = time(0);
// get time now
struct tm * now = localtime(&t);
// Get current time and date
std::string dateAndTime = "BandwidthData - " + std::to_string(now->tm_year + 1900) + '-'
+ std::to_string(now->tm_mon + 1) + '-'
+ std::to_string(now->tm_mday) + '_'
+ std::to_string(now->tm_hour) + "h."
+ std::to_string(now->tm_min) + "m."
+ std::to_string(now->tm_sec) + 's';
outfile.open(dateAndTime + ".csv");
outfile << "Total time," + std::to_string(m_NetworkData.TotalTime) + "\n";
outfile << "Total data received," + std::to_string(m_NetworkData.TotalDataReceived) + "\n";
outfile << "Total data sent," + std::to_string(m_NetworkData.TotalDataSent) + "\n";
outfile << "Total messages received," + std::to_string(m_NetworkData.AmountOfMessagesReceived) + "\n";
outfile << "Total messages sent," + std::to_string(m_NetworkData.AmountOfMessagesSent) + "\n";
float messagesReceivedPerSec = (float)m_NetworkData.AmountOfMessagesReceived / (m_NetworkData.TotalTime / 1000);
float messagesSentPerSec = (float)m_NetworkData.AmountOfMessagesSent / (m_NetworkData.TotalTime / 1000);
float dataReceivedPerSec = (float)m_NetworkData.TotalDataReceived / (m_NetworkData.TotalTime / 1000);
float dataSentPerSec = (float)m_NetworkData.TotalDataSent / (m_NetworkData.TotalTime / 1000);
outfile << "Avarage messages received / s: " + std::to_string(messagesReceivedPerSec) + "\n";
outfile << "Avarage messages sents / s: " + std::to_string(messagesSentPerSec) + "\n";
outfile << "Avarage data received B/s: " + std::to_string(dataReceivedPerSec) + "\n";
outfile << "Avarage data sents B/s: " + std::to_string(dataSentPerSec) + "\n";
outfile << "time, avg receive B, avg send B\n";
for (int i = 0; i < m_NetworkData.BandwidthBytes.size(); i++) {
outfile << std::to_string(i) + ",";
outfile << std::to_string(m_NetworkData.BandwidthBytes[i].first) + ",";
outfile << std::to_string(m_NetworkData.BandwidthBytes[i].second) + "\n";
}
outfile.close();
}
void Network::updateNetworkData()
{
std::clock_t currentTime = std::clock();
// Send snapshot
if (m_SaveDataIntervalMs < (1000 * (currentTime - m_SaveDataTimer) / (double)CLOCKS_PER_SEC)) {
// Set values
m_NetworkData.TotalTime += (1000 * (currentTime - m_SaveDataTimer) / (double)CLOCKS_PER_SEC);
m_NetworkData.BandwidthBytes.push_back(std::pair<unsigned int, unsigned int>(m_NetworkData.DataReceivedThisInterval, m_NetworkData.DataSentThisInterval));
// Reset interval stuff
m_SaveDataTimer = std::clock();
m_NetworkData.DataSentThisInterval = 0;
m_NetworkData.DataReceivedThisInterval = 0;
}
}
+1
View File
@@ -39,6 +39,7 @@ void Packet::Init(MessageType type, unsigned int & packetID)
Packet::WritePrimitive<int>(messageType); Packet::WritePrimitive<int>(messageType);
Packet::WritePrimitive<int>(packetID); Packet::WritePrimitive<int>(packetID);
packetID++; packetID++;
m_HeaderSize = m_Offset;
} }
void Packet::WriteString(const std::string& str) void Packet::WriteString(const std::string& str)
+40 -14
View File
@@ -24,14 +24,17 @@ void Server::Update()
{ {
readFromClients(); readFromClients();
m_EventBroker->Process<Server>(); m_EventBroker->Process<Server>();
} if (isReadingData) {
Network::Update();
}
}
void Server::readFromClients() void Server::readFromClients()
{ {
while (m_Socket.available()) { while (m_Socket.available()) {
try { try {
bytesRead = receive(readBuffer, INPUTSIZE); bytesRead = receive(readBuffer);
Packet packet(readBuffer, bytesRead); Packet packet(readBuffer, bytesRead);
parseMessageType(packet); parseMessageType(packet);
} catch (const std::exception& err) { } catch (const std::exception& err) {
@@ -70,11 +73,8 @@ void Server::parseMessageType(Packet& packet)
case MessageType::Connect: case MessageType::Connect:
parseConnect(packet); parseConnect(packet);
break; break;
case MessageType::ClientPing: case MessageType::Ping:
//parseClientPing(); parsePing();
break;
case MessageType::ServerPing:
parseServerPing();
break; break;
case MessageType::Message: case MessageType::Message:
break; break;
@@ -97,12 +97,18 @@ void Server::parseMessageType(Packet& packet)
} }
} }
int Server::receive(char * data, size_t length) int Server::receive(char * data)
{ {
length = m_Socket.receive_from( unsigned int length = m_Socket.receive_from(
boost::asio::buffer((void*)data boost::asio::buffer((void*)data
, length) , INPUTSIZE)
, m_ReceiverEndpoint, 0); , m_ReceiverEndpoint, 0);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataReceived += length;
m_NetworkData.DataReceivedThisInterval += length;
m_NetworkData.AmountOfMessagesReceived++;
}
return length; return length;
} }
@@ -112,6 +118,12 @@ void Server::send(Packet& packet, int userID)
boost::asio::buffer(packet.Data(), packet.Size()), boost::asio::buffer(packet.Data(), packet.Size()),
m_ConnectedUsers[userID].Endpoint, m_ConnectedUsers[userID].Endpoint,
0); 0);
// Network Debug data
if (isReadingData) {
m_NetworkData.TotalDataSent += packet.Size();
m_NetworkData.DataSentThisInterval += packet.Size();
m_NetworkData.AmountOfMessagesSent++;
}
} }
void Server::send(Packet & packet) void Server::send(Packet & packet)
@@ -122,6 +134,11 @@ void Server::send(Packet & packet)
packet.Size()), packet.Size()),
m_ReceiverEndpoint, m_ReceiverEndpoint,
0); 0);
if (isReadingData) {
// Network Debug data
m_NetworkData.TotalDataSent += packet.Size();
m_NetworkData.DataSentThisInterval += packet.Size();
}
} }
void Server::broadcast(Packet& packet) void Server::broadcast(Packet& packet)
@@ -160,7 +177,9 @@ void Server::sendSnapshot()
} }
} }
} }
broadcast(packet); if (packet.Size() > packet.HeaderSize() + componentInfo.Name.size()) {
broadcast(packet);
}
} }
} }
@@ -174,7 +193,7 @@ void Server::sendPing()
} }
} }
// Create ping message // Create ping message
Packet packet(MessageType::ServerPing); Packet packet(MessageType::Ping);
packet.WriteString("Ping from server"); packet.WriteString("Ping from server");
// Time message // Time message
m_StartPingTime = std::clock(); m_StartPingTime = std::clock();
@@ -298,12 +317,12 @@ void Server::parseClientPing()
return; return;
} }
// Return ping // Return ping
Packet packet(MessageType::ClientPing, m_PlayerDefinitions[playerID].PacketID); Packet packet(MessageType::Ping, m_PlayerDefinitions[playerID].PacketID);
packet.WriteString("Ping received"); packet.WriteString("Ping received");
send(packet); send(packet);
} }
void Server::parseServerPing() void Server::parsePing()
{ {
for (int i = 0; i < m_ConnectedUsers.size(); i++) { for (int i = 0; i < m_ConnectedUsers.size(); i++) {
if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) { if (m_ConnectedUsers[i].Endpoint.address() == m_ReceiverEndpoint.address()) {
@@ -373,5 +392,12 @@ int Server::GetPlayerIDFromEndpoint(boost::asio::ip::udp::endpoint endpoint)
bool Server::OnInputCommand(const Events::InputCommand & e) bool Server::OnInputCommand(const Events::InputCommand & e)
{ {
//LOG_DEBUG("Server::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID); //LOG_DEBUG("Server::OnInputCommand: Command is %s. Value is %f. PlayerID is %i.", e.Command.c_str(), e.Value, e.PlayerID);
if (e.Command == "LogNetworkBandwidth" && e.Value > 0) {
if (isReadingData) {
saveToFile();
}
isReadingData = !isReadingData;
m_SaveDataTimer = std::clock();
}
return true; return true;
} }