Protocol Examples

This sections presents examples of protocol implementation to be used with Push Framework. The library is not restricted to a single protocol. It is up to you to decide how to serialize/deserialize your structured data. Serialization happens when the library is ready to send your structured responses through the TCP connection. De-serialization translates the incoming stream of bytes into structured requests that are routed to your Service instances. For more info. read the Developer Guide.

  • Using Streamed XML : We show an implementation of a protocol that uses XML.
  • Using Google Protobuf protocol : We integrate Protobuf library so that it can be used along with Push Framework
  • Using Websocket : We present a protocol implementation of Websocket which enables the development of PF-based servers able to exchange real time messages with Web clients.

Using Streamed XML

XML is an ideal way to serialize your structured information. In most cases, the structure of the data you want to send/receive is a complex hierarchy. XML can handle this, so you can stream the hierarchy and sucessfully reconstruct it in the other end.

The implementation we provide here includes a fast and open source XML parser by Business Insight. Two intermediate classes are created :

  1. IncomingXMLPacket : public PushFramework::IncomingPacket and
  2. OutgoingXMLPacket : public PushFramework::OutgoingPacket

Then these are wrapped again into two others :

  1. XMLRequest : public IncomingXMLPacket, public OutgoingXMLPacket
  2. XMLResponse : public OutgoingXMLPacket, public IncomingXMLPacket

The symetry between XMLRequest and XMLResponse is beneficial for those who have their client applications written in C++ too. The same code used to encode responses at the server-side, can be used to encode requests at client side. The server-side decoding of requests is the same as the client side decoding of server responses.

The effort remained is to create your data classes, override the two members ::ConstructXML and ::FragmentXML in order to convert your own structures into XML DOM, and the base code will deal with the parsing and serialization job.

A working demo of this protocol is found in the Tutorial Section.

The protocol is encapsulated into a DLL you can use with Push Framework : XMLProtocol.dll

If the client-side of your application is written in C++ then you might find TCPSocket project interesting as well, so you not have to worry about encoding/decoding. This project is also found in the Tutorial section where a Chat client program is developed to talk with a Push Framework – based server.

Using Google ProtoBuf protocol

Google says it created its own protocol to let its heteregenous appliactions exchange data. Encoding/decoding is extremely fast and produce a minimum footprint. To allows users who want to use this protocol along side Push Framework, a client-server application is created. The functionnality implemented by our example is extremely simple : the client sends a requests about some item with a particular id. The response is expected to contain the detailed information about that item. One could have imagined anything, but the aim here is merely to let the integration between ProtoBuf and Push Framework be understood.

When you finally decide to use PushFramework along side Google ProtoBuf , you will need the Google ProtoBuf itself (Library + compiler) as well as ProtoBufProtocol DLL project which  is supplied here. That should encapsulates the serialization details and let you only interact with the classes that ProtoBuf compiler has created for you.

So Google expects you to describe all the data you want to exchange, in a specific langage then compile the result to produce the corresponding classes. In our situation, we only need to compile our messages into C++ because both server-side and client-side is in C++. However it is all possible to use a client application written in other langage (JAVA,, C# etc), compile the messages for them,and be able to talk with Push Framework.

Here are our data structures :

// content of loginrequest.proto :
package gprotoexample;
 
message LoginRequest {
}
 
//content of loginresponse.proto
package gprotoexample;
 
message LoginResponse {
  required bool result = true;        
 
}
 
//content of datainforrequest.proto
package gprotoexample;
 
message DataInfoRequest {
  required int32 id = 2;        // Unique ID number for this person.
 
}
 
//content of datainforesponse.proto
package gprotoexample;
 
message DataInfoResponse {
   enum ResultType {
    InfoFound = 0;
    InfoNotFound = 1;
    InfounspecifiedError = 2;
  }
 
  required ResultType result = 0;
  required int32 id = 1;        //
  optional string description = 1;
 
}
 
//content of logoutrequest.proto
package gprotoexample;
 
message LoginResponse {
  required bool result = true;        
 
}

Client will send a LoginRequest packet, receives a LoginResponse packet, then send DataInfoRequest  and receive DataInfoResponse. The client program is a simple DOS application that will constantly wait for the user to input an id, construct an send a DataInfoRequest packet then receive and display DataInfoResponse.

When user is to exit, a Logout request is sent.

Now we compile this proto file and include the resulting classes into our project. The ProtoBufProtocol  DLL project contains the public ProtobufPacketImpl class and alsoProtobufProtocol Protocol subclass. The former inherits from  PushFramework::OutgoingPacket and PushFramework::IncomingPacket so you can use your data structures within Push Framework. The latter will take care of the serialization job beneficiating from ProtoBuf facilities. It is essential to not that ProtoBufProtocol class also takes care about the framing job in a custom manner since ProtoBuf message are not self delimiting. It is up-to you to change this in another way if you want.

Let’s examine ProtobufPacketImpl :

class ProtobufPacketImpl : public PushFramework::IncomingPacket, public PushFramework::OutgoingPacket
{
public:
	ProtobufPacketImpl(int serviceId);
	~ProtobufPacketImpl(void);
protected:
	virtual bool Decode(char* pBuf, unsigned int nSize);
	virtual bool Encode();
	virtual google::protobuf::Message& getStructuredData() = 0;
private:
	int serviceId;
	std::string* pEncodedStream;
 
public:
	std::string* getEncodedStream() const { return pEncodedStream; }
	int getEncodedStreamSize();
	int getServiceId() const { return serviceId; }
};

I do’nt advise you to use this class into your code, instead use this easier template :

template
class ProtobufPacket : public ProtobufPacketImpl
{
public:
	ProtobufPacket(int serviceId)
		: ProtobufPacketImpl(serviceId)
	{
		//
	}
	~ProtobufPacket()
	{
		//
	}
private:
	T data;
public:
	virtual google::protobuf::Message& getStructuredData()
	{
		return data;
	}
};

Here’s how the servicing code for the DataInfoRequest goes :

void CDataInfoRequestService::handle( ClientKey clientKey, PushFramework::IncomingPacket* pRequest )
{
	ExampleClient* pClient = (ExampleClient*) getClient(clientKey);
	if(!pClient)
		return;
 
	ProtobufPacket* pDataInfoRequest = (ProtobufPacket*) pRequest;
 
	ProtobufPacket response(DataInfoResponseID);
	response.getData().set_id(pDataInfoRequest->getData().id());
	response.getData().set_result(DataInfoResponse_ResultType_InfoFound);
	response.getData().set_description("this is a description");
	//
	pClient->pushPacket(&response);
 
	returnClient(clientKey);
}

There you can see the efficiency of using ProtobufPacket template.

Using Websocket protocol

Push Framework can be used to power HTML5-web application thanks to the introduction of the Websocket protocol. We dedicated a separate project area to present a protocol implementation that enables PF-based server to talk to Web applications. A working web clients that interacts with a Push Framework based server in different ways is available in the project place below :

websocket.codeplex.com

Share