Added and tested the network queue in the server
This is a reimplementation of the old network queue, but using a class. This still uses a separate thread, so that packets can wait if there's any lag. Really, thinking about it, I wonder how necessary this was. On the upside, no singletons this time. Which means that you can have several instances of UDPNetworkManager. That's unintentional, but good to know.
This commit is contained in:
@@ -68,6 +68,12 @@ union NetworkPacket {
|
|||||||
char name[PACKET_STRING_SIZE];
|
char name[PACKET_STRING_SIZE];
|
||||||
//TODO: player count
|
//TODO: player count
|
||||||
}serverInfo;
|
}serverInfo;
|
||||||
|
|
||||||
|
//defaults
|
||||||
|
NetworkPacket() {
|
||||||
|
meta.type = Type::NONE;
|
||||||
|
meta.srcAddress = {0,0};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
#include "network_queue.hpp"
|
||||||
|
|
||||||
|
#include "utility.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int networkQueueThread(void* ptr) {
|
||||||
|
NetworkQueue* netQueue = reinterpret_cast<NetworkQueue*>(ptr);
|
||||||
|
NetworkPacket packet;
|
||||||
|
|
||||||
|
while(netQueue->running) {
|
||||||
|
SDL_SemWait(netQueue->lock);
|
||||||
|
|
||||||
|
//suck in the waiting packets
|
||||||
|
while(netQueue->netUtil->Receive()) {
|
||||||
|
memcpy(&packet, netQueue->netUtil->GetInData(), sizeof(NetworkPacket));
|
||||||
|
//this is important: keep track of the source address
|
||||||
|
packet.meta.srcAddress = netQueue->netUtil->GetInPacket()->address;
|
||||||
|
netQueue->queue.push_back(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SemPost(netQueue->lock);
|
||||||
|
SDL_Delay(10);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkQueue::Init(UDPNetworkUtility* ptr) {
|
||||||
|
if (running) {
|
||||||
|
throw(std::runtime_error("Network Queue is already running"));
|
||||||
|
}
|
||||||
|
running = true;
|
||||||
|
netUtil = ptr;
|
||||||
|
lock = SDL_CreateSemaphore(1);
|
||||||
|
thread = SDL_CreateThread(networkQueueThread, this);
|
||||||
|
if (!thread) {
|
||||||
|
throw(std::runtime_error("Failed to create the network thread"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkQueue::Quit() {
|
||||||
|
if (!running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//end the thread
|
||||||
|
running = false;
|
||||||
|
int ret;
|
||||||
|
SDL_WaitThread(thread, &ret);
|
||||||
|
|
||||||
|
ResetMembers();
|
||||||
|
|
||||||
|
//handle the return
|
||||||
|
if (ret != 0) {
|
||||||
|
throw(std::runtime_error(std::string() + "Network thread returned error code: " + to_string_custom(ret)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkQueue::Kill() {
|
||||||
|
if (!running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
running = false;
|
||||||
|
SDL_KillThread(thread);
|
||||||
|
|
||||||
|
ResetMembers();
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkPacket NetworkQueue::Peek() {
|
||||||
|
NetworkPacket ret;
|
||||||
|
SDL_SemWait(lock);
|
||||||
|
if (queue.size() > 0) {
|
||||||
|
ret = queue[0];
|
||||||
|
}
|
||||||
|
SDL_SemPost(lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkPacket NetworkQueue::Pop() {
|
||||||
|
NetworkPacket ret;
|
||||||
|
SDL_SemWait(lock);
|
||||||
|
if (queue.size() > 0) {
|
||||||
|
ret = queue[0];
|
||||||
|
queue.pop_front();
|
||||||
|
}
|
||||||
|
SDL_SemPost(lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkQueue::Flush() {
|
||||||
|
SDL_SemWait(lock);
|
||||||
|
while(netUtil->Receive());
|
||||||
|
queue.clear();
|
||||||
|
SDL_SemPost(lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkQueue::ResetMembers() {
|
||||||
|
if (running) {
|
||||||
|
throw(std::logic_error("Cannon reset the queue while running"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//reset
|
||||||
|
netUtil = nullptr;
|
||||||
|
SDL_DestroySemaphore(lock);
|
||||||
|
lock = nullptr;
|
||||||
|
thread = nullptr;
|
||||||
|
queue.clear();
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef NETWORKQUEUE_HPP_
|
||||||
|
#define NETWORKQUEUE_HPP_
|
||||||
|
|
||||||
|
#include "udp_network_utility.hpp"
|
||||||
|
#include "network_packet.hpp"
|
||||||
|
|
||||||
|
#include "SDL/SDL_thread.h"
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
|
class NetworkQueue {
|
||||||
|
public:
|
||||||
|
NetworkQueue() = default;
|
||||||
|
~NetworkQueue() = default;
|
||||||
|
|
||||||
|
void Init(UDPNetworkUtility*);
|
||||||
|
void Quit();
|
||||||
|
void Kill();
|
||||||
|
|
||||||
|
NetworkPacket Peek();
|
||||||
|
NetworkPacket Pop();
|
||||||
|
void Flush();
|
||||||
|
private:
|
||||||
|
friend int networkQueueThread(void*);
|
||||||
|
void ResetMembers();
|
||||||
|
|
||||||
|
bool running = false;
|
||||||
|
|
||||||
|
UDPNetworkUtility* netUtil = nullptr;
|
||||||
|
SDL_sem* lock = nullptr;
|
||||||
|
SDL_Thread* thread = nullptr;
|
||||||
|
std::deque<NetworkPacket> queue;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -65,6 +65,7 @@ void ServerApplication::Init(int argc, char** argv) {
|
|||||||
std::cout << "SDL_net initialized" << std::endl;
|
std::cout << "SDL_net initialized" << std::endl;
|
||||||
}
|
}
|
||||||
networkUtil.Open(21795, 1024);
|
networkUtil.Open(21795, 1024);
|
||||||
|
networkQueue.Init(&networkUtil);
|
||||||
|
|
||||||
//Init SQL
|
//Init SQL
|
||||||
std::string dbname = (argc > 1) ? argv[1] : argv[0];
|
std::string dbname = (argc > 1) ? argv[1] : argv[0];
|
||||||
@@ -89,14 +90,35 @@ void ServerApplication::Init(int argc, char** argv) {
|
|||||||
is.close();
|
is.close();
|
||||||
|
|
||||||
sqlite3_exec(database, script.c_str(), nullptr, nullptr, nullptr);
|
sqlite3_exec(database, script.c_str(), nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
|
//debugging
|
||||||
|
//create the debug packets
|
||||||
|
NetworkPacket packet;
|
||||||
|
|
||||||
|
packet.meta.type = NetworkPacket::Type::PING;
|
||||||
|
strcpy(packet.serverInfo.name,"Foo");
|
||||||
|
networkUtil.Send("127.0.0.1", 21795, reinterpret_cast<void*>(&packet), sizeof(NetworkPacket));
|
||||||
|
strcpy(packet.serverInfo.name,"Bar");
|
||||||
|
networkUtil.Send("127.0.0.1", 21795, reinterpret_cast<void*>(&packet), sizeof(NetworkPacket));
|
||||||
|
strcpy(packet.serverInfo.name,"World");
|
||||||
|
networkUtil.Send("127.0.0.1", 21795, reinterpret_cast<void*>(&packet), sizeof(NetworkPacket));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerApplication::Loop() {
|
void ServerApplication::Loop() {
|
||||||
//
|
//debugging
|
||||||
|
SDL_Delay(1000);
|
||||||
|
|
||||||
|
NetworkPacket packet;
|
||||||
|
while(networkQueue.Peek().meta.type != NetworkPacket::Type::NONE) {
|
||||||
|
packet = networkQueue.Pop();
|
||||||
|
std::cout << packet.serverInfo.name << std::endl;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerApplication::Quit() {
|
void ServerApplication::Quit() {
|
||||||
sqlite3_close_v2(database);
|
sqlite3_close_v2(database);
|
||||||
|
networkQueue.Quit();
|
||||||
networkUtil.Close();
|
networkUtil.Close();
|
||||||
SDLNet_Quit();
|
SDLNet_Quit();
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#define SERVERAPPLICATION_HPP_
|
#define SERVERAPPLICATION_HPP_
|
||||||
|
|
||||||
#include "udp_network_utility.hpp"
|
#include "udp_network_utility.hpp"
|
||||||
|
#include "network_queue.hpp"
|
||||||
|
|
||||||
#include "sqlite3/sqlite3.h"
|
#include "sqlite3/sqlite3.h"
|
||||||
#include "SDL/SDL.h"
|
#include "SDL/SDL.h"
|
||||||
@@ -52,6 +53,7 @@ private:
|
|||||||
sqlite3* database = nullptr;
|
sqlite3* database = nullptr;
|
||||||
|
|
||||||
UDPNetworkUtility networkUtil;
|
UDPNetworkUtility networkUtil;
|
||||||
|
NetworkQueue networkQueue;
|
||||||
std::list<ClientEntry> clientEntries;
|
std::list<ClientEntry> clientEntries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user