improved messages and structure of the program

This commit is contained in:
study-faraphel 2024-11-11 13:39:13 +01:00
parent 454e86a982
commit 3c044249f4
31 changed files with 91 additions and 77 deletions

Binary file not shown.

View file

@ -7,15 +7,20 @@
#include "RemotePeer.hpp"
struct Context {
int socket = -1;
addrinfo* broadcastAddressInfo = nullptr;
std::shared_ptr<RemotePeer> server = nullptr;
/**
* Information about the current state of our machine.
* Used everywhere to determinate how to behave.
*/
class Context {
public:
int socket = -1; /// current socket file descriptor, used to communicate
addrinfo* broadcastAddressInfo = nullptr; /// address used to broadcast messages
std::shared_ptr<RemotePeer> server = nullptr; /// peer currently used as the server
Peer me;
Peer me; /// information about our own machine
std::map<
std::uint32_t,
std::shared_ptr<RemotePeer>
> remotePeers {};
std::chrono::high_resolution_clock::time_point latestPeerDiscovery;
> remotePeers {}; /// information about other machines
std::chrono::high_resolution_clock::time_point latestPeerDiscovery; /// time of the latest discovered machine
};

View file

@ -1,4 +1,4 @@
#include "EventManager.hpp"
#include "Manager.hpp"
#include <algorithm>
#include <stdexcept>
@ -11,20 +11,19 @@
#include <random>
#include <sys/socket.h>
#include "events/types.hpp"
#include "events/audio/AudioEvent.hpp"
#include "events/info/InfoEvent.hpp"
#include "events/pong/PongEvent.hpp"
#include "events/search/SearchEvent.hpp"
#include "behavior/events/types.hpp"
#include "behavior/events/audio/AudioEvent.hpp"
#include "behavior/events/info/InfoEvent.hpp"
#include "behavior/events/pong/PongEvent.hpp"
#include "behavior/events/search/SearchEvent.hpp"
#include "packets/base/Packet.hpp"
#include "tasks/client/ClientTask.hpp"
#include "tasks/server/ServerTask.hpp"
#include "tasks/undefined/UndefinedTask.hpp"
#include "behavior/tasks/client/ClientTask.hpp"
#include "behavior/tasks/server/ServerTask.hpp"
#include "behavior/tasks/undefined/UndefinedTask.hpp"
EventManager::EventManager(const std::string& address, const std::string& port, const bool useIpv6) {
std::cout << "address: " << address << " (" << (useIpv6 ? "IPv6" : "IPv4") << ")" << std::endl;
std::cout << "port: " << port << std::endl;
Manager::Manager(const std::string& address, const std::string& port, const bool useIpv6) {
std::cout << "Broadcast address: " << address << ":" << port << " (" << (useIpv6 ? "IPv6" : "IPv4") << ")" << std::endl;
// register the different events type
this->eventRegistry = {
@ -121,10 +120,10 @@ EventManager::EventManager(const std::string& address, const std::string& port,
}
void EventManager::loop() {
void Manager::loop() {
// run an event receiver and sender
this->senderThread = std::thread(&EventManager::loopSender, this);
this->receiverThread = std::thread(&EventManager::loopReceiver, this);
this->senderThread = std::thread(&Manager::loopSender, this);
this->receiverThread = std::thread(&Manager::loopReceiver, this);
this->senderThread.join();
this->receiverThread.join();
@ -133,9 +132,9 @@ void EventManager::loop() {
}
void EventManager::loopSender() {
void Manager::loopSender() {
while (true) {
std::cout << "[Sender] Status: " + std::to_string(static_cast<int>(this->context.me.status)) << std::endl;
std::cout << "[Sender] Handling status: " + std::to_string(static_cast<int>(this->context.me.status)) << std::endl;
// get the corresponding task class
std::shared_ptr<drp::task::BaseTask> task;
@ -152,7 +151,7 @@ void EventManager::loopSender() {
}
void EventManager::loopReceiver() {
void Manager::loopReceiver() {
// prepare space for the sender address
sockaddr_storage fromAddress {};
socklen_t fromAddressLength = sizeof(fromAddress);
@ -185,10 +184,12 @@ void EventManager::loopReceiver() {
try {
event = this->eventRegistry.at(static_cast<drp::event::EventType>(packetContent.eventType));
} catch (const std::out_of_range& exception) {
std::cerr << "Unsupported event type." << std::endl;
std::cerr << "[Receiver] Unsupported event type." << std::endl;
continue;
}
std::cout << "[Receiver] handling event: " << std::to_string(packetContent.eventType) << std::endl;
// ask the event class to handle the event
event->handle(
this->context,

View file

@ -5,15 +5,20 @@
#include <thread>
#include "Context.hpp"
#include "events/types.hpp"
#include "events/base/BaseEvent.hpp"
#include "tasks/types.hpp"
#include "tasks/base/BaseTask.hpp"
#include "behavior/events/types.hpp"
#include "behavior/events/base/BaseEvent.hpp"
#include "behavior/tasks/types.hpp"
#include "behavior/tasks/base/BaseTask.hpp"
class EventManager {
/**
* The Manager.
* Manage how should the program behave depending on its current state, or the message it receive.
*/
// TODO(Faraphel): could be split in two part.
class Manager {
public:
EventManager(const std::string& address, const std::string& port, bool useIpv6 = false);
Manager(const std::string& address, const std::string& port, bool useIpv6 = false);
void loop();
void loopSender();

View file

@ -3,7 +3,10 @@
#include <chrono>
#include <sys/socket.h>
#include "tasks/types.hpp"
#include "behavior/tasks/types.hpp"
// TODO(Faraphel): should be split in multiple files.
/**

View file

@ -3,8 +3,8 @@
#include <iostream>
#include <bits/unique_lock.h>
#include "../../packets/audio/AudioPacketData.hpp"
#include "../../packets/base/PacketData.hpp"
#include "packets/audio/AudioPacketData.hpp"
#include "packets/base/PacketData.hpp"
namespace drp::event {
@ -27,7 +27,7 @@ AudioEvent::~AudioEvent() {
Pa_StopStream(this->stream);
// close the audio stream
if (const PaError error = Pa_CloseStream(this->stream))
std::cerr << "[Client] Could not close the stream: " << std::string(Pa_GetErrorText(error)) << std::endl;
std::cerr << "[Event - Audio] Could not close the stream: " << std::string(Pa_GetErrorText(error)) << std::endl;
}
@ -71,7 +71,7 @@ void AudioEvent::updateAudioStream(const int channels, const std::uint32_t sampl
nullptr,
nullptr
) != paNoError)
throw std::runtime_error("[Client] Could not open the stream: " + std::string(Pa_GetErrorText(error)));
throw std::runtime_error("[Event - Audio] Could not open the stream: " + std::string(Pa_GetErrorText(error)));
// update the new audio values
this->streamChannels = channels;
@ -101,7 +101,7 @@ void AudioEvent::loopPlay() {
std::this_thread::sleep_until(audioPacket.timePlay);
auto cTimePlay = std::chrono::high_resolution_clock::to_time_t(audioPacket.timePlay);
std::cout << "[Client] Playing: " << std::ctime(&cTimePlay) << std::endl;
std::cout << "[Event - Audio] Playing: " << std::ctime(&cTimePlay) << std::endl;
// immediately stop playing music
// this avoids an offset created if this client's clock is too ahead of the others
@ -110,7 +110,7 @@ void AudioEvent::loopPlay() {
// play the new audio data
if (const int error = Pa_StartStream(this->stream) != paNoError)
throw std::runtime_error("[Client] Could not start the PortAudio stream: " + std::string(Pa_GetErrorText(error)));
throw std::runtime_error("[Event - Audio] Could not start the PortAudio stream: " + std::string(Pa_GetErrorText(error)));
// write the new audio data into the audio buffer
const int error = Pa_WriteStream(
@ -125,10 +125,10 @@ void AudioEvent::loopPlay() {
// the output might be very slightly underflowed,
// causing a very small period where no noise will be played.
case paOutputUnderflowed:
std::cerr << "[Client] Underflowed!" << std::endl;
break;
default:
std::cerr << "[Client] Could not write to the audio stream: " << Pa_GetErrorText(error) << std::endl;
std::cerr << "[Event - Audio] Could not write to the audio stream: " << Pa_GetErrorText(error) << std::endl;
}
// remove the audio chunk

View file

@ -1,6 +1,6 @@
#pragma once
#include "../../packets/audio/AudioPacketData.hpp"
#include "packets/audio/AudioPacketData.hpp"
namespace drp::event {

View file

@ -1,7 +1,7 @@
#pragma once
#include "../../packets/base/Packet.hpp"
#include "../../Context.hpp"
#include "packets/base/Packet.hpp"
#include "Context.hpp"
namespace drp::event {

View file

@ -3,7 +3,7 @@
#include <iostream>
#include <sys/socket.h>
#include "../../packets/info/InfoPacketData.hpp"
#include "packets/info/InfoPacketData.hpp"
namespace drp::event {
@ -15,7 +15,7 @@ void InfoEvent::handle(
const sockaddr_storage& fromAddress,
const socklen_t fromAddressLength
) {
std::cout << "Received peer information." << std::endl;
std::cout << "[Event - Info] Received peer information." << std::endl;
// get the peer information
const auto packetData = packet::info::InfoPacketData::fromGeneric(content);

View file

@ -12,7 +12,7 @@ void PongEvent::handle(
const sockaddr_storage& fromAddress,
const socklen_t fromAddressLength
) {
std::cout << "[Receiver] Pong." << std::endl;
std::cout << "[Event - Pong] Pong." << std::endl;
}

View file

@ -6,8 +6,8 @@
#include <iostream>
#include <ostream>
#include "../../packets/base/SecurityMode.hpp"
#include "../../packets/info/InfoPacketData.hpp"
#include "packets/base/SecurityMode.hpp"
#include "packets/info/InfoPacketData.hpp"
namespace drp {
@ -42,11 +42,11 @@ void event::SearchEvent::handle(
reinterpret_cast<const sockaddr*>(&fromAddress),
fromAddressLength
) == -1) {
std::cerr << "[Receiver] Could not send information: " << strerror(errno) << std::endl;
std::cerr << "[Event - Search] Could not send information: " << strerror(errno) << std::endl;
return;
}
std::cout << "[Receiver] Sent back information." << std::endl;
std::cout << "[Event - Search] Sent back information." << std::endl;
}

View file

@ -1,6 +1,6 @@
#pragma once
#include "../../Context.hpp"
#include "Context.hpp"
namespace drp::task {

View file

@ -22,7 +22,7 @@ void ClientTask::handle(Context& context) {
// TODO(Faraphel): only once ?
FILE* chronyProcess = popen(("chronyc add server " + std::string(host) + " 2>&1").c_str(), "r");
if (pclose(chronyProcess) == -1)
std::cerr << "Failed to connect to chrony server !" << std::endl;
std::cerr << "[Task - Client] Failed to connect to chrony server !" << std::endl;
// TODO(Faraphel): check if the server is still reachable.
// if connection lost, go back to undefined mode.

View file

@ -10,10 +10,10 @@
#include <thread>
#include <sys/socket.h>
#include "../../packets/audio/AudioPacketData.hpp"
#include "../../packets/base/Packet.hpp"
#include "../../packets/base/SecurityMode.hpp"
#include "../../utils/audio.hpp"
#include "packets/audio/AudioPacketData.hpp"
#include "packets/base/Packet.hpp"
#include "packets/base/SecurityMode.hpp"
#include "utils/audio.hpp"
namespace drp::task {
@ -28,7 +28,7 @@ ServerTask::ServerTask() {
int error;
this->mpgHandle = mpg123_new(nullptr, &error);
if (this->mpgHandle == nullptr)
throw std::runtime_error("[Server] Could not create a mpg123 handle.");
throw std::runtime_error("[Task - Server] Could not create a mpg123 handle.");
// open the mp3 file
// TODO(Faraphel): mp3 file as argument
@ -36,7 +36,7 @@ ServerTask::ServerTask() {
this->mpgHandle,
"./assets/Queen - Another One Bites the Dust.mp3"
) != MPG123_OK)
throw std::runtime_error("[Server] Could not open file.");
throw std::runtime_error("[Task - Server] Could not open file.");
// get the format of the file
if (mpg123_getformat(
@ -45,7 +45,7 @@ ServerTask::ServerTask() {
&this->channels,
&this->encoding
) != MPG123_OK)
throw std::runtime_error("[Server] Could not get the format of the file.");
throw std::runtime_error("[Task - Server] Could not get the format of the file.");
}
ServerTask::~ServerTask() {
@ -79,7 +79,7 @@ void ServerTask::handle(Context& context) {
std::size(audioPacket.content),
&done
) != MPG123_OK) {
std::cerr << "[Server] Could not read audio data from file." << std::endl;
std::cerr << "[Task - Server] Could not read audio data from file." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
return;
}
@ -109,12 +109,12 @@ void ServerTask::handle(Context& context) {
context.broadcastAddressInfo->ai_addr,
context.broadcastAddressInfo->ai_addrlen
) == -1) {
std::cerr << "[Server] Could not send audio packet: " << strerror(errno) << std::endl;
std::cerr << "[Task - Server] Could not send audio packet: " << strerror(errno) << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
return;
}
std::cout << "[Server] Sent: " << done << " bytes" << std::endl;
std::cout << "[Task - Server] Sent: " << done << " bytes" << std::endl;
// wait for the duration of the audio chunk
std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<std::uint64_t>(

View file

@ -9,17 +9,17 @@
#include <algorithm>
#include <sys/socket.h>
#include "../../Context.hpp"
#include "../../packets/base/Packet.hpp"
#include "../../packets/base/SecurityMode.hpp"
#include "../../packets/search/SearchPacketData.hpp"
#include "Context.hpp"
#include "packets/base/Packet.hpp"
#include "packets/base/SecurityMode.hpp"
#include "packets/search/SearchPacketData.hpp"
namespace drp::task {
void UndefinedTask::handle(Context& context) {
std::cout << "List of peers: " << std::endl;
std::cout << "[Task - Undefined] List of peers: " << std::endl;
for (const auto& peer : context.remotePeers)
std::cout <<
"\tPeer(id=" << peer.second->information.id << ", " <<
@ -63,7 +63,7 @@ void UndefinedTask::handle(Context& context) {
// check if we are this peer
if (context.me.id == serverCandidate->first) {
std::cout << "Becoming server..." << std::endl;
std::cout << "[Task - Undefined] Becoming server..." << std::endl;
// set ourselves as the server
context.server = serverCandidate->second;
context.me.status = TaskType::SERVER;
@ -87,7 +87,7 @@ void UndefinedTask::handle(Context& context) {
packet.setContent(packetData.toGeneric());
std::cout << "Looking for new peers." << std::endl;
std::cout << "[Task - Undefined] Looking for new peers." << std::endl;
// send the search message
if (sendto(
@ -98,7 +98,7 @@ void UndefinedTask::handle(Context& context) {
context.broadcastAddressInfo->ai_addr,
context.broadcastAddressInfo->ai_addrlen
) == -1)
std::cerr << "[Sender] Could not send search event: " << strerror(errno) << std::endl;
std::cerr << "[Task - Undefined] Could not send search event: " << strerror(errno) << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}

View file

@ -2,7 +2,7 @@
#include <portaudio.h>
#include <stdexcept>
#include "argparse/argparse.hpp"
#include "EventManager.hpp"
#include "Manager.hpp"
int main(int argc, char* argv[]) {
@ -26,7 +26,7 @@ int main(int argc, char* argv[]) {
return EXIT_FAILURE;
}
auto eventManager = EventManager(
auto eventManager = Manager(
parser.get<std::string>("--host"),
parser.get<std::string>("--port"),
parser.get<bool>("-6")

View file

@ -3,7 +3,7 @@
#include <chrono>
#include <cstdint>
#include "../../events/types.hpp"
#include "behavior/events/types.hpp"
#include "../base/PacketData.hpp"

View file

@ -3,7 +3,7 @@
#include <cstring>
#include "PacketContent.hpp"
#include "../../events/types.hpp"
#include "behavior/events/types.hpp"
namespace drp::packet::base {

View file

@ -1,7 +1,7 @@
#pragma once
#include "../../RemotePeer.hpp"
#include "../../events/types.hpp"
#include "RemotePeer.hpp"
#include "behavior/events/types.hpp"
#include "../base/PacketData.hpp"