Sunday, March 11, 2012

A little framework for TCP client-server communications (part2)

Here we are for the second part of this article.  I remeber to everybody that this little framework is not created for market, distrubution or diffusion. (Not even for best practices)

Let's start with some example code!

On the base of what I wrote in the first part, let' see how to create a simple server with JRR Framework.

ResponseManager server = new ResponseManager(8888); //8888 is the listening port
server.setConsoleLogEnabled(true); //enable printing log on the console
server.start(); //start listening


What happens now?
This object is listening to port 8888 and accept incoming connections with its default method.
Want to override this method? Just do it in this way:
server.OverrideRequestWorker(new BaseRequestWorker()
{
 @Override
 public String Work(String clientRequest)
 {
  String serverResponse ="DO WORK HERE";
  return serverResponse;
 }
});

Want to see a console log? Just write this:
server.setConsoleLogEnabled(true);
Want to catch the log and show it in another control, create a listener in this way:
server.addLogListener(new LogCallBack()
{ 
 @Override
 public void OnReceived(String logLine)
 {
  myControl.appendText(logline);    
 }
});

Provide your own dispatching method for client messages and that's all.
I leave you to discover default behaviour :)

Let's see the client classe which is IMHO more complete than server's.
This is how to connect to a server.

String sServer= InetAddress.getLocalHost().getHostAddress();
RequestManager client = new RequestManager(sServer, 8888 , new ExceptionCallBack()
{
 @Override
 public void onThrow(Exception ex)
 {
  //here if something goes wrong (connection timeout / server not found ...)
 }
});

if(!client.Timedout)
{
 //server connected
}

and this is how to sent a request to the server:
client.BeginRequest("INVOCATION", new String[]{ "param1","param2" }, new ResponseCallBack()
{
 @Override
 public void onInvoke(BaseResponse r)
 {
  //Here when it cames the server response
 }
 @Override
 public void onThrow(Request r, Exception ex)
 {
  //Here when some exception is throwed 
 }
},5); //5 seconds of timeout

The request is prepared from an abstract class (RequestBuilder) and sent to server in string format mode. If you want to provide your own just override it in this way:
client.OverrideRequestBuilder(new BaseStringRequestBuilder()
{ 
 @Override
 public String Build(String clientName, int reqNumber, String INV_NAME,
   String[] Parameters, boolean justSend)
 {
  //...
  return myString;
 }
});

Then the string it's managed from server RequestWorker.

If you payed attention, you'll notice that Response is wrapped in a class called BaseResponse.

Its task is to split the responses in InvokedMethod, NameOfServer, MessageValue, Errors, etc...
BaseResponse standarly provide a simple method of splitting a response from server.
You can write your own ResponseFactory with the OverrideResponseFactory method.

If you keep default behaviour this is the resulting log:
/*
SERVER Start Method -> Server Started
SERVER ListenRunnable -> Connection acceppted from: /192.168.1.134
CLIENT Begin Request -> JRR_CLIENT|TEST METHOD|param1#0$
SERVER Request received  -> JRR_CLIENT|TEST METHOD|param1#0$
SERVER Response sent  -> 0|JRR_CLIENT|0|TEST METHOD|UnImplementedValue|$
CLIENT ListenRunnable -> Server sent a message: 0|JRR_CLIENT|0|TEST METHOD|UnImplementedValue|$
onInvoke=0 $
onInvoke=0 UnImplementedValue
*/

And that's all. As you see it's all very simple, but depends how you use it, you can simplify a lot of work.

You can try JRR downloading here.

Otherwise, happy coding elsewhere :)

No comments:

Post a Comment