mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Implemented connection handling
This commit is contained in:
parent
c2c43602ea
commit
dff9cf39c0
@ -14,11 +14,25 @@
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/WindowHandler.h"
|
||||
|
||||
#include "../windows/InfoWindows.h"
|
||||
|
||||
void LobbyClient::onPacketReceived(const std::vector<uint8_t> & message)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LobbyClient::onConnectionFailed(const std::string & errorMessage)
|
||||
{
|
||||
GH.windows().popWindows(1);
|
||||
CInfoWindow::showInfoDialog("Failed to connect to game lobby!\n" + errorMessage, {});
|
||||
}
|
||||
|
||||
void LobbyClient::onDisconnected()
|
||||
{
|
||||
GH.windows().popWindows(1);
|
||||
CInfoWindow::showInfoDialog("Connection to game lobby was lost!", {});
|
||||
}
|
||||
|
||||
LobbyWidget::LobbyWidget()
|
||||
{
|
||||
addCallback("closeWindow", [](int) { GH.windows().popWindows(1); });
|
||||
@ -37,4 +51,11 @@ LobbyWindow::LobbyWindow():
|
||||
connection = std::make_shared<LobbyClient>();
|
||||
|
||||
connection->start("127.0.0.1", 30303);
|
||||
|
||||
addUsedEvents(TIME);
|
||||
}
|
||||
|
||||
void LobbyWindow::tick(uint32_t msPassed)
|
||||
{
|
||||
connection->poll();
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ public:
|
||||
class LobbyClient : public NetworkClient
|
||||
{
|
||||
void onPacketReceived(const std::vector<uint8_t> & message) override;
|
||||
void onConnectionFailed(const std::string & errorMessage) override;
|
||||
void onDisconnected() override;
|
||||
public:
|
||||
LobbyClient() = default;
|
||||
};
|
||||
@ -32,6 +34,8 @@ class LobbyWindow : public CWindowObject
|
||||
std::shared_ptr<LobbyWidget> widget;
|
||||
std::shared_ptr<LobbyClient> connection;
|
||||
|
||||
void tick(uint32_t msPassed);
|
||||
|
||||
public:
|
||||
LobbyWindow();
|
||||
};
|
||||
|
@ -30,7 +30,13 @@ void NetworkClient::start(const std::string & host, uint16_t port)
|
||||
|
||||
void NetworkClient::onConnected(const boost::system::error_code & ec)
|
||||
{
|
||||
connection = std::make_shared<NetworkConnection>(socket);
|
||||
if (ec)
|
||||
{
|
||||
onConnectionFailed(ec.message());
|
||||
return;
|
||||
}
|
||||
|
||||
connection = std::make_shared<NetworkConnection>(socket, *this);
|
||||
connection->start();
|
||||
}
|
||||
|
||||
@ -39,9 +45,25 @@ void NetworkClient::run()
|
||||
io->run();
|
||||
}
|
||||
|
||||
void NetworkClient::poll()
|
||||
{
|
||||
io->poll();
|
||||
}
|
||||
|
||||
void NetworkClient::sendPacket(const std::vector<uint8_t> & message)
|
||||
{
|
||||
connection->sendPacket(message);
|
||||
}
|
||||
|
||||
void NetworkClient::onDisconnected(const std::shared_ptr<NetworkConnection> & connection)
|
||||
{
|
||||
onDisconnected();
|
||||
}
|
||||
|
||||
void NetworkClient::onPacketReceived(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message)
|
||||
{
|
||||
onPacketReceived(message);
|
||||
}
|
||||
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -15,7 +15,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class NetworkConnection;
|
||||
|
||||
class DLL_LINKAGE NetworkClient : boost::noncopyable
|
||||
class DLL_LINKAGE NetworkClient : boost::noncopyable, public INetworkConnectionListener
|
||||
{
|
||||
std::shared_ptr<NetworkService> io;
|
||||
std::shared_ptr<NetworkSocket> socket;
|
||||
@ -23,8 +23,15 @@ class DLL_LINKAGE NetworkClient : boost::noncopyable
|
||||
std::shared_ptr<NetworkTimer> timer;
|
||||
|
||||
void onConnected(const boost::system::error_code & ec);
|
||||
|
||||
void onDisconnected(const std::shared_ptr<NetworkConnection> & connection) override;
|
||||
void onPacketReceived(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message) override;
|
||||
|
||||
protected:
|
||||
virtual void onPacketReceived(const std::vector<uint8_t> & message) = 0;
|
||||
virtual void onConnectionFailed(const std::string & errorMessage) = 0;
|
||||
virtual void onDisconnected() = 0;
|
||||
|
||||
public:
|
||||
NetworkClient();
|
||||
virtual ~NetworkClient() = default;
|
||||
@ -32,6 +39,7 @@ public:
|
||||
void start(const std::string & host, uint16_t port);
|
||||
void sendPacket(const std::vector<uint8_t> & message);
|
||||
void run();
|
||||
void poll();
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -12,8 +12,9 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
NetworkConnection::NetworkConnection(const std::shared_ptr<NetworkSocket> & socket)
|
||||
NetworkConnection::NetworkConnection(const std::shared_ptr<NetworkSocket> & socket, INetworkConnectionListener & listener)
|
||||
: socket(socket)
|
||||
, listener(listener)
|
||||
{
|
||||
|
||||
}
|
||||
@ -28,7 +29,13 @@ void NetworkConnection::start()
|
||||
|
||||
void NetworkConnection::onHeaderReceived(const boost::system::error_code & ec)
|
||||
{
|
||||
uint32_t messageSize = readPacketSize(ec);
|
||||
if (ec)
|
||||
{
|
||||
listener.onDisconnected(shared_from_this());
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t messageSize = readPacketSize();
|
||||
|
||||
boost::asio::async_read(*socket,
|
||||
readBuffer,
|
||||
@ -36,23 +43,15 @@ void NetworkConnection::onHeaderReceived(const boost::system::error_code & ec)
|
||||
std::bind(&NetworkConnection::onPacketReceived,this, _1, messageSize));
|
||||
}
|
||||
|
||||
uint32_t NetworkConnection::readPacketSize(const boost::system::error_code & ec)
|
||||
uint32_t NetworkConnection::readPacketSize()
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
throw std::runtime_error("Connection aborted!");
|
||||
}
|
||||
|
||||
if (readBuffer.size() < messageHeaderSize)
|
||||
{
|
||||
throw std::runtime_error("Failed to read header!");
|
||||
}
|
||||
|
||||
std::istream istream(&readBuffer);
|
||||
|
||||
uint32_t messageSize;
|
||||
istream.read(reinterpret_cast<char *>(&messageSize), messageHeaderSize);
|
||||
|
||||
if (messageSize > messageMaxSize)
|
||||
{
|
||||
throw std::runtime_error("Invalid packet size!");
|
||||
@ -65,7 +64,8 @@ void NetworkConnection::onPacketReceived(const boost::system::error_code & ec, u
|
||||
{
|
||||
if (ec)
|
||||
{
|
||||
throw std::runtime_error("Connection aborted!");
|
||||
listener.onDisconnected(shared_from_this());
|
||||
return;
|
||||
}
|
||||
|
||||
if (readBuffer.size() < expectedPacketSize)
|
||||
@ -79,6 +79,8 @@ void NetworkConnection::onPacketReceived(const boost::system::error_code & ec, u
|
||||
std::istream istream(&readBuffer);
|
||||
istream.read(reinterpret_cast<char *>(message.data()), messageHeaderSize);
|
||||
|
||||
listener.onPacketReceived(shared_from_this(), message);
|
||||
|
||||
start();
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class DLL_LINKAGE NetworkConnection : boost::noncopyable
|
||||
class DLL_LINKAGE NetworkConnection :public std::enable_shared_from_this<NetworkConnection>, boost::noncopyable
|
||||
{
|
||||
static const int messageHeaderSize = sizeof(uint32_t);
|
||||
static const int messageMaxSize = 1024;
|
||||
@ -21,13 +21,14 @@ class DLL_LINKAGE NetworkConnection : boost::noncopyable
|
||||
std::shared_ptr<NetworkSocket> socket;
|
||||
|
||||
NetworkBuffer readBuffer;
|
||||
INetworkConnectionListener & listener;
|
||||
|
||||
void onHeaderReceived(const boost::system::error_code & ec);
|
||||
void onPacketReceived(const boost::system::error_code & ec, uint32_t expectedPacketSize);
|
||||
uint32_t readPacketSize(const boost::system::error_code & ec);
|
||||
uint32_t readPacketSize();
|
||||
|
||||
public:
|
||||
NetworkConnection(const std::shared_ptr<NetworkSocket> & socket);
|
||||
NetworkConnection(const std::shared_ptr<NetworkSocket> & socket, INetworkConnectionListener & listener);
|
||||
|
||||
void start();
|
||||
void sendPacket(const std::vector<uint8_t> & message);
|
||||
|
@ -19,4 +19,15 @@ using NetworkAcceptor = boost::asio::basic_socket_acceptor<boost::asio::ip::tcp>
|
||||
using NetworkBuffer = boost::asio::streambuf;
|
||||
using NetworkTimer = boost::asio::steady_timer;
|
||||
|
||||
class NetworkConnection;
|
||||
|
||||
class DLL_LINKAGE INetworkConnectionListener
|
||||
{
|
||||
friend class NetworkConnection;
|
||||
|
||||
protected:
|
||||
virtual void onDisconnected(const std::shared_ptr<NetworkConnection> & connection) = 0;
|
||||
virtual void onPacketReceived(const std::shared_ptr<NetworkConnection> & connection, const std::vector<uint8_t> & message) = 0;
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -36,22 +36,13 @@ void NetworkServer::connectionAccepted(std::shared_ptr<NetworkSocket> upcomingCo
|
||||
{
|
||||
if(ec)
|
||||
{
|
||||
logNetwork->info("Something wrong during accepting: %s", ec.message());
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
logNetwork->info("We got a new connection! :)");
|
||||
auto connection = std::make_shared<NetworkConnection>(upcomingConnection);
|
||||
connections.insert(connection);
|
||||
connection->start();
|
||||
}
|
||||
catch(std::exception & e)
|
||||
{
|
||||
logNetwork->error("Failure processing new connection! %s", e.what());
|
||||
throw std::runtime_error("Something wrong during accepting: " + ec.message());
|
||||
}
|
||||
|
||||
logNetwork->info("We got a new connection! :)");
|
||||
auto connection = std::make_shared<NetworkConnection>(upcomingConnection, *this);
|
||||
connections.insert(connection);
|
||||
connection->start();
|
||||
startAsyncAccept();
|
||||
}
|
||||
|
||||
@ -60,4 +51,10 @@ void NetworkServer::sendPacket(const std::shared_ptr<NetworkConnection> & connec
|
||||
connection->sendPacket(message);
|
||||
}
|
||||
|
||||
void NetworkServer::onDisconnected(const std::shared_ptr<NetworkConnection> & connection)
|
||||
{
|
||||
assert(connections.count(connection));
|
||||
connections.erase(connection);
|
||||
}
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
@ -15,7 +15,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class NetworkConnection;
|
||||
|
||||
class DLL_LINKAGE NetworkServer : boost::noncopyable
|
||||
class DLL_LINKAGE NetworkServer : boost::noncopyable, public INetworkConnectionListener
|
||||
{
|
||||
std::shared_ptr<NetworkService> io;
|
||||
std::shared_ptr<NetworkAcceptor> acceptor;
|
||||
@ -23,9 +23,10 @@ class DLL_LINKAGE NetworkServer : boost::noncopyable
|
||||
|
||||
void connectionAccepted(std::shared_ptr<NetworkSocket>, const boost::system::error_code & ec);
|
||||
void startAsyncAccept();
|
||||
|
||||
void onDisconnected(const std::shared_ptr<NetworkConnection> & connection) override;
|
||||
protected:
|
||||
virtual void onNewConnection(std::shared_ptr<NetworkConnection>) = 0;
|
||||
virtual void onPacketReceived(std::shared_ptr<NetworkConnection>, const std::vector<uint8_t> & message) = 0;
|
||||
virtual void onNewConnection(const std::shared_ptr<NetworkConnection> &) = 0;
|
||||
|
||||
void sendPacket(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message);
|
||||
|
||||
|
@ -15,17 +15,17 @@
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
|
||||
static const std::string DATABASE_PATH = "~/vcmi.db";
|
||||
static const std::string DATABASE_PATH = "/home/ivan/vcmi.db";
|
||||
static const int LISTENING_PORT = 30303;
|
||||
//static const std::string SERVER_NAME = GameConstants::VCMI_VERSION + " (server)";
|
||||
//static const std::string SERVER_UUID = boost::uuids::to_string(boost::uuids::random_generator()());
|
||||
|
||||
void LobbyServer::onNewConnection(std::shared_ptr<NetworkConnection>)
|
||||
void LobbyServer::onNewConnection(const std::shared_ptr<NetworkConnection> &)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LobbyServer::onPacketReceived(std::shared_ptr<NetworkConnection>, const std::vector<uint8_t> & message)
|
||||
void LobbyServer::onPacketReceived(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message)
|
||||
{
|
||||
|
||||
}
|
||||
@ -33,7 +33,6 @@ void LobbyServer::onPacketReceived(std::shared_ptr<NetworkConnection>, const std
|
||||
LobbyServer::LobbyServer()
|
||||
{
|
||||
database = SQLiteInstance::open(DATABASE_PATH, true);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[])
|
||||
|
@ -17,8 +17,8 @@ class LobbyServer : public NetworkServer
|
||||
{
|
||||
std::unique_ptr<SQLiteInstance> database;
|
||||
|
||||
void onNewConnection(std::shared_ptr<NetworkConnection>) override;
|
||||
void onPacketReceived(std::shared_ptr<NetworkConnection>, const std::vector<uint8_t> & message) override;
|
||||
void onNewConnection(const std::shared_ptr<NetworkConnection> &) override;
|
||||
void onPacketReceived(const std::shared_ptr<NetworkConnection> &, const std::vector<uint8_t> & message) override;
|
||||
public:
|
||||
LobbyServer();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user