Commit 49106383 authored by louiz’'s avatar louiz’

Implement timed events.

parent 082831e2
...@@ -118,6 +118,8 @@ file( ...@@ -118,6 +118,8 @@ file(
src/network/server.* src/network/server.*
src/network/transfer_sender.* src/network/transfer_sender.*
src/network/command.* src/network/command.*
src/network/timed_event.*
src/network/timed_event_handler.*
) )
add_library(server STATIC ${source_server}) add_library(server STATIC ${source_server})
...@@ -135,6 +137,8 @@ file( ...@@ -135,6 +137,8 @@ file(
src/network/command_handler.* src/network/command_handler.*
src/network/transfer_receiver.* src/network/transfer_receiver.*
src/network/command.* src/network/command.*
src/network/timed_event.*
src/network/timed_event_handler.*
) )
add_library(client STATIC ${source_client}) add_library(client STATIC ${source_client})
......
#include <game/game.hpp> #include <game/game.hpp>
#include <logging/logging.hpp> #include <logging/logging.hpp>
#include <unistd.h> #include <unistd.h>
static const char* auth_messages[] = {"Success", static const char* auth_messages[] = {"Success",
......
...@@ -71,6 +71,11 @@ void Client::transfer_init_callback(Command* received_command) ...@@ -71,6 +71,11 @@ void Client::transfer_init_callback(Command* received_command)
this->receivers.push_back(receiver); this->receivers.push_back(receiver);
} }
boost::asio::io_service& Client::get_io_service()
{
return this->io_service;
}
void Client::on_transfer_ended(const TransferReceiver* receiver) void Client::on_transfer_ended(const TransferReceiver* receiver)
{ {
log_debug("on_transfer_ended"); log_debug("on_transfer_ended");
......
...@@ -20,12 +20,14 @@ ...@@ -20,12 +20,14 @@
# define __CLIENT_HPP__ # define __CLIENT_HPP__
#include <network/command_handler.hpp> #include <network/command_handler.hpp>
#include <network/timed_event_handler.hpp>
#include <network/command.hpp> #include <network/command.hpp>
#include <network/timed_event.hpp>
#include <network/transfer_receiver.hpp> #include <network/transfer_receiver.hpp>
using boost::asio::ip::tcp; using boost::asio::ip::tcp;
class Client: public CommandHandler class Client: public CommandHandler, public TimedEventHandler
{ {
public: public:
Client(); Client();
...@@ -51,6 +53,8 @@ public: ...@@ -51,6 +53,8 @@ public:
void poll(void); void poll(void);
virtual void on_connection_closed() {} virtual void on_connection_closed() {}
virtual boost::asio::io_service& get_io_service();
/** /**
* Called when a file transfer is finished. * Called when a file transfer is finished.
*/ */
......
...@@ -125,7 +125,6 @@ void CommandHandler::binary_read_handler(const boost::system::error_code& error, ...@@ -125,7 +125,6 @@ void CommandHandler::binary_read_handler(const boost::system::error_code& error,
this->install_read_handler(); this->install_read_handler();
} }
// Set a callback to be called whenever there’s something to read on the socket.
void CommandHandler::install_read_handler(void) void CommandHandler::install_read_handler(void)
{ {
boost::asio::async_read_until(*this->socket, boost::asio::async_read_until(*this->socket,
...@@ -155,12 +154,8 @@ void CommandHandler::send(Command* command, boost::function< void(void) > on_sen ...@@ -155,12 +154,8 @@ void CommandHandler::send(Command* command, boost::function< void(void) > on_sen
bool CommandHandler::check_commands_to_send() bool CommandHandler::check_commands_to_send()
{ {
log_debug("Length of the queue: " << this->commands_to_send.size()); log_debug("Length of the queue: " << this->commands_to_send.size());
// log_debug("check_commands_to_send");
if (this->writing || this->commands_to_send.empty()) if (this->writing || this->commands_to_send.empty())
{ return false;
// log_debug("not sending: this->writing=" << this->writing << " queue empty" << this->commands_to_send.empty());
return false;
}
this->actually_send(this->commands_to_send.back()); this->actually_send(this->commands_to_send.back());
this->commands_to_send.pop_back(); this->commands_to_send.pop_back();
return true; return true;
......
...@@ -118,7 +118,6 @@ private: ...@@ -118,7 +118,6 @@ private:
* from it and we send it. * from it and we send it.
*/ */
command_queue commands_to_send; command_queue commands_to_send;
/** /**
* Tells us if we are waiting for an async_write to finish or not. * Tells us if we are waiting for an async_write to finish or not.
* This must be set to true when calling async_write(), to false * This must be set to true when calling async_write(), to false
......
...@@ -101,7 +101,6 @@ void RemoteClient::on_auth_success() ...@@ -101,7 +101,6 @@ void RemoteClient::on_auth_success()
void RemoteClient::start() void RemoteClient::start()
{ {
log_debug("Starting RemoteClient " << this->number); log_debug("Starting RemoteClient " << this->number);
CommandHandler::install_read_handler();
this->install_callbacks(); this->install_callbacks();
} }
...@@ -124,6 +123,11 @@ void RemoteClient::on_connection_closed() ...@@ -124,6 +123,11 @@ void RemoteClient::on_connection_closed()
this->server->remove_client(this); this->server->remove_client(this);
} }
boost::asio::io_service& RemoteClient::get_io_service()
{
return this->server->io_service;
}
void RemoteClient::on_transfer_ended(const TransferSender* transfer) void RemoteClient::on_transfer_ended(const TransferSender* transfer)
{ {
log_debug("on_transfer_ended"); log_debug("on_transfer_ended");
......
...@@ -20,13 +20,15 @@ ...@@ -20,13 +20,15 @@
#include <database/user.hpp> #include <database/user.hpp>
#include <network/command_handler.hpp> #include <network/command_handler.hpp>
#include <network/command.hpp> #include <network/command.hpp>
#include <network/timed_event_handler.hpp>
#include <network/timed_event.hpp>
#include <network/transfer_sender.hpp> #include <network/transfer_sender.hpp>
class Server; class Server;
using boost::asio::ip::tcp; using boost::asio::ip::tcp;
class RemoteClient: public CommandHandler class RemoteClient: public CommandHandler, public TimedEventHandler
{ {
public: public:
RemoteClient(boost::asio::io_service&, Server*); RemoteClient(boost::asio::io_service&, Server*);
...@@ -47,6 +49,7 @@ public: ...@@ -47,6 +49,7 @@ public:
virtual void on_connection_closed(); virtual void on_connection_closed();
virtual boost::asio::io_service& get_io_service();
/** /**
* Sends a file to the remote client. * Sends a file to the remote client.
* @param filename The file to send. * @param filename The file to send.
......
...@@ -43,13 +43,14 @@ public: ...@@ -43,13 +43,14 @@ public:
*/ */
RemoteClient* find_client_by_login(const std::string&); RemoteClient* find_client_by_login(const std::string&);
boost::asio::io_service io_service;
private: private:
void install_accept_handler(void); void install_accept_handler(void);
void handle_accept(RemoteClient*, const boost::system::error_code&); void handle_accept(RemoteClient*, const boost::system::error_code&);
void accept(void); void accept(void);
std::vector<RemoteClient*> clients; std::vector<RemoteClient*> clients;
boost::asio::io_service io_service;
tcp::acceptor* acceptor; tcp::acceptor* acceptor;
short port; short port;
}; };
......
#include <network/timed_event.hpp>
#include <network/timed_event_handler.hpp>
TimedEvent::TimedEvent(const TimedEventHandler* handler,
boost::asio::deadline_timer* timer,
const t_timed_callback callback):
handler(handler),
timer(timer),
callback(callback)
{
this->timer->async_wait(boost::bind(&TimedEvent::on_expires, this, _1));
}
void TimedEvent::on_expires(const boost::system::error_code& e)
{
log_debug("on_timeout");
this->callback();
}
TimedEvent::~TimedEvent()
{
log_debug("Deleting timed event");
delete this->timer;
}
void TimedEvent::cancel()
{
this->timer->cancel();
}
/** @addtogroup Network
* @{
*/
/**
* An event to be executed (using a callback) in the future, after the
* specified time has passed.
* @class TimedEvent
*/
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#ifndef __TIMED_EVENT_HPP__
# define __TIMED_EVENT_HPP__
class TimedEventHandler;
typedef boost::function< void(void) > t_timed_callback;
class TimedEventHandler;
class TimedEvent
{
public:
TimedEvent(const TimedEventHandler*,
boost::asio::deadline_timer*,
const t_timed_callback);
~TimedEvent();
void cancel();
void on_expires(const boost::system::error_code&);
private:
TimedEvent(const TimedEvent&);
TimedEvent& operator=(const TimedEvent&);
const TimedEventHandler* handler;
boost::asio::deadline_timer* timer;
const t_timed_callback callback;
};
#endif // __TIMED_EVENT_HPP__
#include <network/timed_event_handler.hpp>
TimedEventHandler::TimedEventHandler()
{
}
TimedEventHandler::~TimedEventHandler()
{
log_debug("Deleting TimedEventHandler");
std::vector<TimedEvent*>::iterator it;
for (it = this->events.begin(); it < this->events.end(); ++it)
{
delete (*it);
}
}
void TimedEventHandler::install_timed_event(const t_timed_callback callback,
const int delay)
{
log_debug("installing timed_event");
boost::asio::deadline_timer* timer = new boost::asio::deadline_timer(this->get_io_service(), boost::posix_time::seconds(delay));
TimedEvent* event = new TimedEvent(this, timer, callback);
this->events.push_back(event);
}
/** @addtogroup Network
* @{
*/
/**
*
* @class TimedEventHandler
*/
#include <map>
#ifndef __TIMED_EVENT_HANDLER_HPP__
# define __TIMED_EVENT_HANDLER_HPP__
#include <network/timed_event.hpp>
#include <logging/logging.hpp>
class TimedEventHandler
{
public:
TimedEventHandler();
~TimedEventHandler();
/**
* Install a timed event to be executed in the futur at the specified date.
*/
void install_timed_event(const t_timed_callback, const int);
virtual boost::asio::io_service& get_io_service() = 0;
private:
TimedEventHandler(const TimedEventHandler&);
TimedEventHandler& operator=(const TimedEventHandler&);
std::vector<TimedEvent*> events;
};
#endif // __TIMED_EVENT_HANDLER_HPP__
/**@}*/
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment