2
0
Эх сурвалжийг харах

Implemented connection handling

Ivan Savenko 1 жил өмнө
parent
commit
dff9cf39c0

+ 21 - 0
client/serverLobby/LobbyWindow.cpp

@@ -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();
 }

+ 4 - 0
client/serverLobby/LobbyWindow.h

@@ -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();
 };

+ 23 - 1
lib/network/NetworkClient.cpp

@@ -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

+ 9 - 1
lib/network/NetworkClient.h

@@ -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

+ 14 - 12
lib/network/NetworkConnection.cpp

@@ -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();
 }
 

+ 4 - 3
lib/network/NetworkConnection.h

@@ -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);

+ 11 - 0
lib/network/NetworkDefines.h

@@ -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

+ 11 - 14
lib/network/NetworkServer.cpp

@@ -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

+ 4 - 3
lib/network/NetworkServer.h

@@ -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);
 

+ 3 - 4
lobby/LobbyServer.cpp

@@ -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[])

+ 2 - 2
lobby/LobbyServer.h

@@ -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();
 };