Linux, C++ and other Tortures

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Monday, 16 July 2012

Communicating with RaspBerry via GSoap Web Services

Posted on 14:28 by Unknown
According to wikipedia "A Web service is a method of communication between two electronic devices over the Web (Internet)." I would not say over the 'Web', indeed you can communicate within a local area network without the need on going 'Web'.

On this tutorial we are going to explain step by step how to deploy a Web Service on our Rasberry. We are also going to see how to develop a little application in our laptop that will communicate with this Web Service.

The protocol used on a web service is called 'SOAP' and is based on 'XML'. The following diagram explains in a simplified way how a Web Service communication is carried out.


Fig.1 Simplified SOAP exchange diagram 

The most common usage of Web Services is via HTTP, and that is the reason behind its popularity. In fact all the existing web infrastructure (from routers to web servers) fits perfectly on this model, without the need of adapt absolutely anything.

How the xml is formed, is specified on the SOAP protocol. Normally the commercial Web Services API, like the ones used on .Net, Java, or C++, hide the complexity of the protocol, so we can focus on our object s model and the 'dirty' work of converting those object on 'XML' (and viceversa) is completely transparent for us.

1. Downloading GSoap.

GSoap is a open source Web Service API, written in C and C++. You can download the last version from here.

There are 2 important tools shipped on the download, the one that we are going to use is called 'soapcpp2' and you can find it on the following path:

./gsoap-2.8/gsoap/bin/linux386/soapcpp2


2. Defining our service interface.

On this example we are going to create a service that returns the hour from our Raspberry.

The service interface is defined in a similar way than a library interface. We are going to create a header defining the method that will be called:

Fig. 2 Sevice Definition header


2. Generating the server classes.

Now that our service is defined, we have to generate the classes that will handle the request. Fortunately this can be done automatically by using 'soapcpp2'. Go to your project path (in my case ~/workspace/workspace64/GSoapTuto/MyRaspberryTimeServer/src) and execute soapcpp2 with  the following options:


~/Desktop/GSoap/gsoap-2.8/gsoap/bin/linux386/soapcpp2 -S  currentTime.h

-S indicates server-side only files


If everything went ok, several files should have been added to your project:

Fig 3. Auto generated code


Remove the files 'soapcurrentTimeService.cpp' and 'soapcurrentTimeService.h', and add the files 'stdsoap2.cpp' and 'stdsoap2.h'. You can find these last on the downloaded package (/gsoap-2.8/gsoap).


2. Creating a standalone server.


We are almost done with the server, we just need to create a new file 'currentTime.cpp' and create the 'main' method and define what must be done when 'ns__currentTime' is called.


Fig 4. Resultant file structure


currentTime.cpp code:


#include "soapH.h" // include the generated declarations 
#include "currentTime.nsmap" // include the XML namespace mappings 
int main() 
{
   struct soap soap;
   int m, s; // master and slave sockets
   soap_init(&soap);
   m = soap_bind(&soap, "192.168.1.54", 2012, 100);
   if (m < 0)
      soap_print_fault(&soap, stderr);
   else
   {
      fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
      for (int i = 1; ; i++)
      {
         s = soap_accept(&soap);
         if (s < 0)
         {
            soap_print_fault(&soap, stderr);
            break;
         }
         fprintf(stderr, "%d: accepted connection from IP=%d.%d.%d.%d socket=%d", i,
            (soap.ip >> 24)&0xFF, (soap.ip >> 16)&0xFF, (soap.ip >> 8)&0xFF, soap.ip&0xFF, s);
         if (soap_serve(&soap) != SOAP_OK) // process RPC request
            soap_print_fault(&soap, stderr); // print error
         fprintf(stderr, "request served\n");
         soap_destroy(&soap); // clean up class instances
         soap_end(&soap); // clean up everything and close socket
      }
   }
   soap_done(&soap); // close master socket and detach context
}
int ns__currentTime(struct soap *soap, time_t& response) 
{ 
   response = time(0); 
   return SOAP_OK; 
}


You will have to change the line 'm = soap_bind(&soap, "192.168.1.54", 2012, 100);' and set the IP of your Raspberry (192.168.1.54 in my case) and the port you want it to listen from (2012 in my case).


If you want to make the resultant program work on Raspberry, you will have to cross-compile it. You can do it by changing the properties of your project and performing the following changes:


Under GCC C++ Compiler, change Command: 'g++' by 'arm-linux-gnueabi-g++'
Under GCC C++ Linker, change Command: 'g++' by 'arm-linux-gnueabi-g++'


You can find more information about cross-compilation for Raspberry on my previous post here.




2. Executing the server on Raspberry


The last thing we have to do is to copy the resultant compiled into Raspberry:

fig 5. Copy the resultant program to raspberry using scp


And finally, execute it:


Fig 6. Raspberry serving our service




3. Developing the client:


Now that we have a Web Service deployed on our RaspBerry, lets communicate with it. The steps to build the client are quite similar to the ones we followed to build the server.

First, we create a client project, containing exactly the same header definition than the one we used for the server (you can copy-paste the file).

From the project src path (~/workspace/workspace64/GSoapTuto/MyRaspberryTimeClient/src in my case), execute the following command to generate the code for the client:


~/Desktop/GSoap/gsoap-2.8/gsoap/bin/linux386/soapcpp2 -i -C  currentTime.h

Add the 'stdsoap2.cpp' and 'stdsoap2.h' as we did for the server. And finally add 'currentTime.cpp' including the main method with the following content:

Fig 7. Resultant client structure


Finally, on change the line 'soap_endpoint = "http://www.yourdomain.com/currentTime.cgi";' on the file 'soapcurrentTimeProxy.cpp' in order to target your Raspberry:

soap_endpoint = "http://192.168.1.54:2012"; in my case


And that's all!! If you fulfilled all the steps, after compiling and executing your client, you should get a beautiful result like 'The time is 1342473837' indicating the date in seconds from your Raspberry.

If you have a look to the Raspberry console, it should display some info about the just served request:

Fig 8. First Raspberry served request!!




Email ThisBlogThis!Share to XShare to FacebookShare to Pinterest
Posted in | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • Mercurial with Apache... on the Cloud!!
    And here we go with our third tutorial explaining how to deploy and enjoy applications 'In the cloud'. This time we will take advant...
  • Cross Compiling and Cross Debugging C++ with Eclipse from Debian Squeeze x64 to Debian Squeeze ARM (Raspberry Pi)
    1. Introduction I have received yesterday my Raspberry Pi ( http://www.raspberrypi.org/ )  unit.  Fig 1. Raspberry Pi connected After comple...
  • Shared Libraries with Eclipse
    Hello there! So here we go with another tutorial, this time explaining how to develop shared libraries using Eclipse-CDT as IDE. If you are...
  • Unit Testing with CppUnit and Eclipse
    As I already mentioned in one of my previous posts, CppUnit is a powerful framework that allows us to automatize the unit testing execution....
  • Communicating with RaspBerry via GSoap Web Services
    According to wikipedia "A Web service is a method of communication between two electronic devices over the Web (Internet)." I wou...
  • Shared Libraries with Eclipse on 86_64 (64 bits) systems
    If you followed my previous post  http://linuxtortures.blogspot.com/2012/02/shared-libraries-with-eclipse.html where I explained how to deve...
  • Configuring Ubuntu on my new HP G62-a55SF
    As usual, after the Operative System installation, there are some drivers to configure and some programs and features to install. Comparing ...
  • Using C++ Libraries from Python
    It's been a while since my last post but here I am back with a very interesting post about Wrapping C++ libraries to be used in python. ...
  • Image processing with OpenCV
    Hi again!! Following the format of my previous posts I will try to show step by step how to install and configure the OpenCV libraries, one ...
  • Continuous Integration with Jenkins, Mercurial and CppUnit on C++
    Hello again!! Today I am going to talk about Jenkins, an open source tool that enables the continuous integration and delivery for our proje...

Blog Archive

  • ▼  2012 (9)
    • ►  December (1)
    • ▼  July (1)
      • Communicating with RaspBerry via GSoap Web Services
    • ►  June (1)
    • ►  April (2)
    • ►  March (3)
    • ►  February (1)
  • ►  2011 (7)
    • ►  December (5)
    • ►  January (2)
  • ►  2010 (3)
    • ►  December (3)
Powered by Blogger.

About Me

Unknown
View my complete profile