Added server + network stuff

This commit is contained in:
Vladislav Khorev 2013-02-26 13:57:00 +00:00
parent 01b58124ec
commit 5d13869324
14 changed files with 417 additions and 40 deletions

View File

@ -308,6 +308,7 @@ LOCAL_SRC_FILES += src/Utils/JniApi/JniApi.cpp
LOCAL_SRC_FILES += src/Utils/JniApi/JniApplication.cpp
LOCAL_SRC_FILES += src/Utils/Console/Console.cpp
LOCAL_SRC_FILES += src/Utils/SerializeInterface/SerializeInterface.cpp
LOCAL_SRC_FILES += src/Utils/Network/Network.cpp
LOCAL_SRC_FILES += src/Utils/PngHelper.cpp
LOCAL_SRC_FILES += src/Utils/SimpleTimer.cpp
LOCAL_SRC_FILES += src/Utils/ThreadUtils.cpp

View File

@ -36,7 +36,12 @@
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SalmonEnginePath)$(Configuration)\</OutDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SalmonEnginePath)$(Configuration)\</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
@ -69,6 +74,7 @@
<ClCompile Include="..\src\Utils\DataTypes\NewDataTypes.cpp" />
<ClCompile Include="..\src\Utils\FileUtils\FileUtils.cpp" />
<ClCompile Include="..\src\Utils\Network\Network.cpp" />
<ClCompile Include="..\src\Utils\Network\Server.cpp" />
<ClCompile Include="..\src\Utils\SerializeInterface\SerializeInterface.cpp" />
<ClCompile Include="..\src\Utils\SimpleTimer.cpp" />
<ClCompile Include="..\src\Utils\ThreadUtils.cpp" />
@ -83,6 +89,7 @@
<ClInclude Include="..\include\Utils\ErrorTypes\ErrorTypes.h" />
<ClInclude Include="..\include\Utils\FileUtils\FileUtils.h" />
<ClInclude Include="..\include\Utils\Network\Network.h" />
<ClInclude Include="..\include\Utils\Network\Server.h" />
<ClInclude Include="..\include\Utils\Network\SignalSender.h" />
<ClInclude Include="..\include\Utils\SerializeInterface\SerializeInterface.h" />
<ClInclude Include="..\include\Utils\SimpleTimer.h" />

View File

@ -37,7 +37,7 @@ public:
TLiteModelResource() : TriangleCount(0), PathToResource("") { }
~TLiteModelResource();
bool LoadModel(boost::shared_array<byte> filePointer, cardinal fileSize);
bool LoadModel(boost::shared_array<unsigned char> filePointer, cardinal fileSize);
void FreeModel();

View File

@ -18,7 +18,7 @@ namespace SE
typedef unsigned int cardinal;
typedef unsigned short int word;
typedef unsigned char byte;
//typedef unsigned char byte;
typedef cardinal* pcardinal;

View File

@ -25,24 +25,50 @@ const int CONST_CONNECTION_TIMEOUT_SECONDS = 300;
void SendPropertyTree(boost::asio::io_service& ioService, boost::asio::ip::tcp::socket& socket, boost::property_tree::ptree pTree);
//Must be stored in shared_ptr only
struct TDataReader : public boost::enable_shared_from_this<TDataReader>
class TDataReadSignalMap
{
protected:
std::map<std::string, std::shared_ptr<boost::signal<void(boost::property_tree::ptree)>>> SignalMap;
public:
void AddSlot(const std::string& nodeName, boost::function<void(boost::property_tree::ptree)> f);
bool SignalExists(const std::string& signalName);
void EmitSignal(const std::string& signalName, const boost::property_tree::ptree& pt);
void Clear();
};
//Must be stored in shared_ptr only
class TDataReader : public boost::enable_shared_from_this<TDataReader>
{
protected:
bool Nonstop;
void InnerStartRead();
public:
boost::asio::ip::tcp::socket& Socket;
int DataSize;
std::vector<char> Data;
TDataReadSignalMap DataReadSignalMap;
TDataReader(boost::asio::ip::tcp::socket& socket);
void StartRead();
void StartReadOnce();
void StartReadNonstop();
void HandleReadDataSize(const boost::system::error_code& error);
void HandleReadData(const boost::system::error_code& error);
boost::signal<void(boost::property_tree::ptree)> DataReadSignal;
boost::signal<void()> ErrorSignal;
};
@ -52,6 +78,8 @@ class TAuthorizationInterface
{
public:
virtual void Authorize() = 0;
virtual ~TAuthorizationInterface() { }
};
class TSimpleAuthorization : public TAuthorizationInterface
@ -62,8 +90,6 @@ public:
boost::asio::ip::tcp::socket& Socket;
//std::shared_ptr<TDataReader> DataReader;
std::string Login;
std::string Password;
@ -105,6 +131,8 @@ public:
boost::signal<void()> OnConnectedSignal;
boost::signal<void()> OnAutorizedSignal;
boost::signal<void()> OnDisconnectedSignal;
boost::shared_ptr<TDataReader> ClientDataReader;
TAuthorizationVariant Authorization;
@ -122,16 +150,11 @@ public:
void HandleAuthorized();
void HandleAuthorizationError();
};
class TServerSocket
{
protected:
public:
void SendPropertyTree(boost::property_tree::ptree pTree);
};
} //namespace SE

View File

@ -0,0 +1,127 @@
#ifndef SERVER_H_INCLUDED
#define SERVER_H_INCLUDED
#include <string>
#include <map>
#include <vector>
#include "boost/shared_array.hpp"
#include "boost/property_tree/ptree.hpp"
#include "boost/foreach.hpp"
#include "boost/asio.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/signal.hpp"
#include "boost/variant.hpp"
#include "include/Utils/Network/SignalSender.h"
namespace SE
{
class TAutorizatorInterface
{
protected:
public:
virtual void StartListen() = 0;
virtual ~TAutorizatorInterface() { }
};
class TSimpleAutorizator : public TAutorizatorInterface
{
protected:
static std::vector<std::string> UserPasswords;
static boost::mutex UserPasswordsMutex;
public:
boost::asio::io_service& IoService;
boost::asio::ip::tcp::socket& Socket;
TSimpleAutorizator(boost::asio::io_service& ioService, boost::asio::ip::tcp::socket& socket);
virtual void StartListen();
void HandleGetData(boost::property_tree::ptree pTree);
boost::signal<void()> ErrorSignal;
boost::signal<void(std::string)> AllowedSignal;
boost::signal<void()> DeniedSignal;
};
typedef boost::variant<std::shared_ptr<TSimpleAutorizator>> TAuthorizatorVariant;
class TServerSocket;
class TConnectedUser : public boost::enable_shared_from_this<TConnectedUser>
{
protected:
TServerSocket& Server;
std::string Login; //Need to generalize this
public:
boost::asio::ip::tcp::socket Socket;
TAuthorizatorVariant Autorizator;
boost::shared_ptr<TDataReader> UserDataReader;
TConnectedUser(TServerSocket& server);
~TConnectedUser();
std::string GetLogin() { return Login; }
void HandleAllowed(std::string login); //Need to generalize this
void SendPropertyTree(boost::property_tree::ptree pTree);
};
class TServerSocket
{
protected:
std::vector<boost::shared_ptr<TConnectedUser>> UserArr;
boost::thread ServiceThread;
std::shared_ptr<boost::asio::ip::tcp::acceptor> Acceptor;
public:
boost::asio::io_service IoService;
TServerSocket();
~TServerSocket();
void Open(int port);
void Close();
void UpdateInThread();
void JoinServiceThread();
void StartAccept();
void HandleAccept(boost::shared_ptr<TConnectedUser> user, const boost::system::error_code& error);
//Need to generalize this
boost::signal<void(boost::shared_ptr<TConnectedUser>)> OnUserAuthorizedSignal;
//boost::signal<void(std::string)> OnUserDisconnectedSignal;
};
} //namespace SE
#endif

View File

@ -27,6 +27,7 @@ This code combines additional routines (such as console/log, exceptions, math ut
#include "include/Utils/SimpleTimer.h"
#include "include/Utils/ThreadUtils.h"
#include "include/Utils/Network/Network.h"
#include "include/Utils/Network/Server.h"
#ifdef TARGET_WIN32
#include "WinApi/WinApi.h"

View File

@ -16,7 +16,7 @@ TLiteModelResource::~TLiteModelResource()
*Console<<"ResourceManager::ModelManager::LiteModelResource deleting";
}
bool TLiteModelResource::LoadModel(boost::shared_array<byte> filePointer, cardinal fileSize)
bool TLiteModelResource::LoadModel(boost::shared_array<unsigned char> filePointer, cardinal fileSize)
{
FreeModel();

View File

@ -29,9 +29,10 @@ void TResourceManager::Update(cardinal timer)
GUIManager.Update(timer);
ST::MainThreadIoService.run();
//ST::MainThreadIoService.run();
ST::MainThreadIoService.run_one();
ST::MainThreadIoService.reset();
//ST::MainThreadIoService.reset();
}
TResourceManager::~TResourceManager()

View File

@ -633,7 +633,7 @@ void TSoundManagerWindows::LoadSound(const std::string& soundFileName)
HRESULT result;
std::string fileName = ResourceManager->PathToResources + soundFileName;
std::string fileName = ST::PathToResources + soundFileName;
TWaveFile waveFile;
@ -748,7 +748,7 @@ void TSoundManagerWindows::LoadMusic(const std::string& musicFileName)
StreamMap[musicName] = ptr;
StreamMap[musicName]->Load(ResourceManager->PathToResources + musicFileName);
StreamMap[musicName]->Load(ST::PathToResources + musicFileName);
}
}

View File

@ -13,7 +13,6 @@ const int CONST_ROW_WIDTH = 14;
const std::string CONST_CONSOLE_TEX_NAME = "console_bkg.bmp";
#ifndef UTILS_ENGINE
void TSimpleConsole::Draw()
{

View File

@ -8,7 +8,12 @@
namespace SE
{
//Xperimental HACK!!!
#ifdef UTILS_ENGINE
TFileConsole* Console;
#endif
namespace ST
{

View File

@ -18,17 +18,72 @@ void SendPropertyTree(boost::asio::io_service& ioService, boost::asio::ip::tcp::
boost::shared_ptr<TSignalSender> signalSender(new TSignalSender(socket, len, data));
ioService.post(boost::bind(&TSignalSender::Send, signalSender));
signalSender->Send();
//ioService.post(boost::bind(&TSignalSender::Send, signalSender));
}
void TDataReadSignalMap::AddSlot(const std::string& nodeName, boost::function<void(boost::property_tree::ptree)> f)
{
if (SignalMap.count(nodeName) == 0)
{
SignalMap[nodeName] = std::shared_ptr<boost::signal<void(boost::property_tree::ptree)>>(new boost::signal<void(boost::property_tree::ptree)>);
SignalMap[nodeName]->connect(f);
}
else
{
SignalMap[nodeName]->connect(f);
}
}
bool TDataReadSignalMap::SignalExists(const std::string& signalName)
{
return SignalMap.count(signalName) != 0;
}
void TDataReadSignalMap::EmitSignal(const std::string& signalName, const boost::property_tree::ptree& pt)
{
if (SignalMap.count(signalName) == 0)
{
throw ErrorToLog("Signal " + signalName + " does not exist!");
}
(*SignalMap[signalName])(pt);
}
void TDataReadSignalMap::Clear()
{
SignalMap.clear();
}
TDataReader::TDataReader(boost::asio::ip::tcp::socket& socket)
: Socket(socket)
{
}
void TDataReader::StartRead()
void TDataReader::InnerStartRead()
{
boost::asio::async_read(Socket, boost::asio::buffer(&DataSize, 4), boost::bind(&TDataReader::HandleReadDataSize, shared_from_this(), boost::asio::placeholders::error));
}
void TDataReader::StartReadOnce()
{
InnerStartRead();
Nonstop = false;
}
void TDataReader::StartReadNonstop()
{
InnerStartRead();
Nonstop = true;
}
void TDataReader::HandleReadDataSize(const boost::system::error_code& error)
@ -73,7 +128,19 @@ void TDataReader::HandleReadData(const boost::system::error_code& error)
boost::property_tree::read_xml(stream, propertyTree);
DataReadSignal(propertyTree);
BOOST_FOREACH(auto i, propertyTree)
{
if (DataReadSignalMap.SignalExists(i.first))
{
DataReadSignalMap.EmitSignal(i.first, i.second);
}
}
if (Nonstop)
{
InnerStartRead();
}
}
catch(boost::property_tree::ptree_error)
@ -82,7 +149,6 @@ void TDataReader::HandleReadData(const boost::system::error_code& error)
}
}
TSimpleAuthorization::TSimpleAuthorization(boost::asio::io_service& ioService, boost::asio::ip::tcp::socket& socket)
: Socket(socket)
, IoService(ioService)
@ -95,8 +161,8 @@ void TSimpleAuthorization::Authorize()
{
boost::shared_ptr<TDataReader> dataReader(new TDataReader(Socket));
dataReader->DataReadSignal.connect(boost::bind(&TSimpleAuthorization::HandleGetData, this, _1));
dataReader->DataReadSignalMap.AddSlot("OnHello", boost::bind(&TSimpleAuthorization::HandleGetData, this, _1));
dataReader->ErrorSignal.connect(ErrorSignal);
boost::property_tree::ptree pt;
@ -105,7 +171,7 @@ void TSimpleAuthorization::Authorize()
SendPropertyTree(IoService, Socket, pt);
dataReader->StartRead();
dataReader->StartReadOnce();
}
@ -113,18 +179,12 @@ void TSimpleAuthorization::Authorize()
void TSimpleAuthorization::HandleGetData(boost::property_tree::ptree pTree)
{
if (pTree.find("OnHello") != pTree.not_found())
{
Login = pTree.get<std::string>("OnHello.Login");
Password = pTree.get<std::string>("OnHello.Password");
Login = pTree.get<std::string>("Login");
Password = pTree.get<std::string>("Password");
SaveLoginPasswordSignal(Login, Password);
AuthorizedSignal();
return;
}
SaveLoginPasswordSignal(Login, Password);
ErrorSignal();
AuthorizedSignal();
}
TClientSocket::TClientSocket()
@ -192,6 +252,8 @@ void TClientSocket::Close()
Socket.close();
ClientDataReader->DataReadSignalMap.Clear();
OnDisconnectedSignal();
}
}
@ -231,7 +293,9 @@ void TClientSocket::HandleConnect(const boost::system::error_code& error)
void TClientSocket::HandleAuthorized()
{
ClientDataReader = boost::shared_ptr<TDataReader>(new TDataReader(Socket));
OnAutorizedSignal();
ClientDataReader->StartReadNonstop();
}
void TClientSocket::HandleAuthorizationError()
@ -239,4 +303,9 @@ void TClientSocket::HandleAuthorizationError()
}
void TClientSocket::SendPropertyTree(boost::property_tree::ptree pTree)
{
SE::SendPropertyTree(IoService, Socket, pTree);
}
} //namspace SE

View File

@ -0,0 +1,144 @@
#include "include/Utils/Utils.h"
namespace SE
{
std::vector<std::string> TSimpleAutorizator::UserPasswords;
boost::mutex TSimpleAutorizator::UserPasswordsMutex;
TSimpleAutorizator::TSimpleAutorizator(boost::asio::io_service& ioService, boost::asio::ip::tcp::socket& socket)
: IoService(ioService)
, Socket(socket)
{
}
void TSimpleAutorizator::StartListen()
{
boost::shared_ptr<TDataReader> dataReader(new TDataReader(Socket));
dataReader->DataReadSignalMap.AddSlot("Hello", boost::bind(&TSimpleAutorizator::HandleGetData, this, _1));
dataReader->ErrorSignal.connect(ErrorSignal);
dataReader->StartReadOnce();
}
void TSimpleAutorizator::HandleGetData(boost::property_tree::ptree pTree)
{
std::string Login = boost::lexical_cast<std::string>(UserPasswords.size());
std::string Password = "12345";
UserPasswordsMutex.lock();
UserPasswords.push_back(Password);
UserPasswordsMutex.unlock();
boost::property_tree::ptree pt;
pt.put("OnHello.Login", Login);
pt.put("OnHello.Password", Password);
SendPropertyTree(IoService, Socket, pt);
AllowedSignal(Login);
}
TConnectedUser::TConnectedUser(TServerSocket& server)
: Server(server)
, Socket(server.IoService)
, Autorizator(std::shared_ptr<TSimpleAutorizator>(new TSimpleAutorizator(server.IoService, Socket)))
{
}
TConnectedUser::~TConnectedUser()
{
}
void TConnectedUser::HandleAllowed(std::string login)
{
UserDataReader = boost::shared_ptr<TDataReader>(new TDataReader(Socket));
Login = login;
Server.OnUserAuthorizedSignal(shared_from_this());
UserDataReader->StartReadNonstop();
}
void TConnectedUser::SendPropertyTree(boost::property_tree::ptree pTree)
{
SE::SendPropertyTree(Server.IoService, Socket, pTree);
}
TServerSocket::TServerSocket()
{
}
TServerSocket::~TServerSocket()
{
}
void TServerSocket::Open(int port)
{
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
Acceptor = std::shared_ptr<boost::asio::ip::tcp::acceptor>(new boost::asio::ip::tcp::acceptor(IoService, endpoint));
StartAccept();
ServiceThread = boost::thread(boost::bind(&TServerSocket::UpdateInThread, this));
}
void TServerSocket::Close()
{
}
void TServerSocket::UpdateInThread()
{
IoService.run();
IoService.reset();
}
void TServerSocket::JoinServiceThread()
{
ServiceThread.join();
}
void TServerSocket::StartAccept()
{
boost::shared_ptr<TConnectedUser> newUser(new TConnectedUser(*this));
Acceptor->async_accept(newUser->Socket, boost::bind(&TServerSocket::HandleAccept, this, newUser, boost::asio::placeholders::error));
}
void TServerSocket::HandleAccept(boost::shared_ptr<TConnectedUser> user, const boost::system::error_code& error)
{
if (!error)
{
UserArr.push_back(user);
boost::get<std::shared_ptr<TSimpleAutorizator>>(user->Autorizator)->AllowedSignal.connect(boost::bind(&TConnectedUser::HandleAllowed, user, _1));
boost::get<std::shared_ptr<TSimpleAutorizator>>(user->Autorizator)->StartListen();
}
StartAccept();
}
} //namspace SE