Hi.
Been at this all day, have learnt alot about boost binding and what not to do with a std::stringstream.
I first tryed haveing a std::stringstream in the network packet class that failed after hours of trying to get that to work,
I switched to a std:string.
and I have finaly got some thing that works I was wondering if I have forgot to add any thing.
Please have a quick look, And your advice will be welcome, thank in advance.
This is the base message class it holds a type. This type is what the message is something like chatMsg, or KIllUintMsg
These messages will be user define with the use of a DEFINE_USER_MSG_START any number after this the user can define for amessage type
all values before are reserved for system mesages(work in progress)
all message classes will need to derive from this class.
.
//------------------------------------------------------------------------------
//all net messages must be Derived from this base Class
//it holds a type
//-------------------------------------------------------------------------------
class cNetWorkMessageBase
{
friend class boost::serialization::access;
// When the class Archive corresponds to an output archive, the
// & operator is defined similar to <<. Likewise, when the class Archive
// is a type of input archive the & operator is defined similar to >>.
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & Type;
}
public:
cNetWorkMessageBase()
{
Type = -1;
}
~cNetWorkMessageBase(){}
int32_t Type;//the type of the message all messages need the firts variable to be a type
};//end cNetWorkMessageBase
/////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Ok this next class is the packet data that will be sent over the network
It use's boost serialization to serialize the the passed in message classes into a std::string
.
//------------------------------------------------------------------------
//we send this message to the network layer it holds the real message
//Serialized all messages will need to be derived from cNetWorkMessageBase
//the class cNetWorkMessageBase has a type member we deserialize to
//tell what the message is
//-------------------------------------------------------------------------
class cNetWorkPacket
{
std::string archive_stream;//hold the message in its serialized form
public:
cNetWorkPacket(const cNetWorkPacket &net)
{
archive_stream = net.archive_stream;
}
cNetWorkPacket(){}
~cNetWorkPacket(){}
//-------------------------------------------------------------
//reset the data
//--------------------------------------------------------------
void Reset()
{
archive_stream = "";
}//end Reset
//////////////////////////////////////////////////////////////////
cNetWorkPacket& cNetWorkPacket::operator=( const cNetWorkPacket& other )
{
if(this == &other)
return *this;
archive_stream = other.archive_stream;
return *this;
}
//-------------------------------------------------------------------------
//returns the stream as a string
//-------------------------------------------------------------------------
void GetData(std::string &str)
{
str = archive_stream;
}//end GetData
/////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------
//call only in the network layer
//-------------------------------------------------------------------------
void SetData(std::string &str)
{
archive_stream = str;
}//end SetData
/////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------
//serialize the message into its network form
//-----------------------------------------------------------------------
template <typename T>
bool SerializeMessage(const T& t)
{
std::ostringstream outstream;
try
{
// Serialize the data
boost::archive::text_oarchive archive(outstream);
archive << t;
archive_stream = outstream.str();
}
catch (std::exception& e)
{
return false;
}
if(archive_stream.empty())
return false;
return true;
}//end SerializeMessage
////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------
//serialize the message into its network form
//-----------------------------------------------------------------------
template <typename T>
bool DeSerializeMessage(T& t)
{
if(archive_stream.empty())
return false;
try
{
//DeSerialize the data
std::istringstream archivestream(archive_stream);
boost::archive::text_iarchive archive(archivestream);
archive >> t;
}
catch (std::exception& e)
{
return false;
}
return true;
}//end DeSerializeMessage
////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------
//returns the messages type member
//--------------------------------------------------------------------
bool GetMessageType(cNetWorkMessageBase &type)
{
return DeSerializeMessage(type);
}//end GetMessageType
//////////////////////////////////////////////////////////////////////
};//end class cNetWorkPacket
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
And this is my first message its a chat message class derived from the networkbase class
.
//--------------------------------------------------------------
//this class holds our message type we dont send this
//we send the Serialized message based on this classes data
//---------------------------------------------------------------
class cMessage: public cNetWorkMessageBase
{
private:
friend class boost::serialization::access;
// When the class Archive corresponds to an output archive, the
// & operator is defined similar to <<. Likewise, when the class Archive
// is a type of input archive the & operator is defined similar to >>.
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
// invoke serialization of the base class
ar & boost::serialization::base_object<cNetWorkMessageBase>(*this);
// save/load class member variables
ar & Name;
}
public:
cMessage()
{
Type = 111;//message type
}//end
~cMessage()
{
}
std::string Name;
};//end cMessage
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
To use do this.
cMessage mychat;
mychat.Type = CHAT_MSG;
mychat.Name = "Hello network World";
you cant just send this, you first need to serialize the message
cNetWorkPacket packet;
packet.Serialize(mychat);
now we can pass the packet to the network class for proccessing.
I think this is some of my best work yet
next I need a app to network pass on type thing something to feed the network with app messages and back out also.
Some more reading.