October 24, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Accessing Web Services from a Mobile Application

  • March 2, 2004
  • By Alex Gusev
  • Send Email »
  • More Articles »

Web Services today have became a common technique. Windows CE-based devices, as usual, were several steps behind desktop systems. A couple of months ago, Microsoft finally re-released SP2 for CE.NET, promising significant performance improvements. Thus, recently mobile developers are also able to use most of Web Services' cake. I have no intention to discuss the theory or concept of this technology here; you may freely find a lot of articles on the Web. Also, we won't touch Web Services or Visual Studio.NET basics. What we'll be focused on is what does it all mean in the case of Windows CE.

Creation of a C# Sample Project

As a test sample, we will create a simple client application that will use Amazon's Web Services to query information about available books. So, let's create a new "Smart Device Application" using Visual Studio.NET. The only option actually relevant for Windows CE is to create a C# project. That's the simpliest way to develop Web Services-related applications. If you've used C++, you may either consider using the SOAP toolkit available in WinCE 4.x or, as the most complicated case, write a similar wrapper for SOAP classes for previous versions of Windows CE to assemble SOAP messages manually. The last case may become relevant when you need to achieve high performance benchmarks; for example, when developing an application that performs barcode scanning and then gets item details from a remote server. Our sample is simple, so all such details will be left out of this article's scope.



Click here for a larger image.

Well, to be ready to start using Amazon Web Services, you should download Amazon Web Service Developer's Kit from http://www.amazon.com/webservices. The last thing is to apply fora Developer's token, and you're completely set up. So, now, let's add a Web Reference to our project to get a wrapper class for the Web Service. A WSDL file describing its API can be found here. Finally, we have a form to enter the author name and display search results Until now, all we've done is absolutely similar to desktop application development. Now, it's time to take a look at the actual search code.



Click here for a larger image.

private void button1_Click(object sender, System.EventArgs e)
{
   Cursor.Current = Cursors.WaitCursor;

   AmazonSearchService srvc = new AmazonSearchService();
   WebProxy objProxy = new WebProxy (proxyAddr,proxyPort);
   objProxy.BypassProxyOnLocal = true;
   objProxy.Credentials = new NetworkCredential (user, password,
                                                 domain);
   srvc.Proxy = objProxy;
   GlobalProxySelection.Select = objProxy;

   AuthorRequest req = new AuthorRequest();
   req.author = SearchText.Text;
   req.devtag = DEVTAG;
   req.mode   = "books";
   req.type   = "lite";
   req.page   = "1";

   try
   {
      ProductInfo pi = srvc.AuthorSearchRequest(req);
      for (int i = 0; i < pi.Details.Length; i++)
      {
         string s = pi.Details[i].ProductName;
         AuthorsLB.Items.Add(s);
      }
   }
   catch(WebException ex)
   {
      string message = ex.Message;
      HttpWebResponse response = (HttpWebResponse)ex.Response;
      if(null != response)
      {
         message = response.StatusDescription;
         response.Close();
      }
      AuthorsLB.Items.Add(message);
   }

   Cursor.Current = Cursors.Default;
}

As you see, first we should create an instance of a service object. If you're connecting to the Internet or an intranet via a proxy, you should also define proxy settings. There was a bug in the CE.NET Web Client; it doesn't look into the credentials of a global WebProxy object to authenticate it to the proxy server. For a workaround, you may define it directly, as shown in the above sample. All the rest of the code proceeds an actual call to Web Service and gets the search result from the remote server. If you were developing Web Service consuming applications for a PC, that's the same story here. Like at Microsoft's presentations, just do a Copy/Paste, and it'll work.

Let's now consider another important aspect of online applications. Your program should verify that the network connection is alive; in other words, requested network resources are available during the application's lifetime. CE.NET framework has no classes to notify applications in response to changes in the network connectivity status. Therefore, mobile apps need to implement their own algorithms of polling active connections and possibly providing caching functionality. The simplest way to verify whether a device is connected to the network is to use a System.Theading.Timer object. When Tick Event occurs, you may use WebRequest and HttpWebResponse objects to send a HTTP GET request to the URL where the Web Service is located and receive an answer. If the status code of the response is equal to HttpStatusCode.OK, the connection to remote server is valid:

   // Somewhere in the code
   timer1.Interval = 1000;
   timer1.Enabled = true;
   .........................
   // In responase to Tick event of timer
   WebRequest req = WebRequest.Create(url);
   HttpWebResponse result = (HttpWebResponse)req.GetResponse();
   if ( result.StatusCode != HttpStatusCode.OK )
   {
      // Network connection was lost or remote server is
      // unavailable or some other HTTP error occurred
      ....
   }

Actually that's all you need to start successfully using Web Services on CE.NET mobile devices. If performance issues aren't your headaches, you may just move your C# code to a mobile environment, obviously taking into account all existing restictions. For those of you who develop mobile business applications working with heavy data, C# can't offer a sufficient solution. Therefore, our old buddy C++ is coming from behind the scene.

Creation of a C++ Sample Project

There are cases when you can't use C# as a project's programming language due to different reasons, such as performance, existing code, and so forth. I guess you may freely continue this list... Well, as usal, C++ may help us survive in such a situation. The current status is that, under WinCE 4.x, you have a MS SOAP toolkit, equivalent to the SOAP SDK 2.0 for the desktop. Programming it is not as comfortable as using C#, but it hides some low-level details from the developer. The toolkit consists of a set of interfaces that allow you to create SOAP messages, send requests, receive responses back, and finally extract received data. The sample code is listed below (you may find full text, for example, here):

...
      ISoapSerializerPtr pSerializer;
      ISoapReaderPtr pReader;
      ISoapConnectorPtr pConnector;

      hr = pConnector.CreateInstance(__uuidof(HttpConnector));
      if(FAILED(hr))
      {
         DisplayHResult(_T("Cannot create SoapClient."), hr);
         return;
      }

      CString EndPointURL;
      m_EndPointURLCtl.GetWindowText(EndPointURL);
      pConnector->Property["EndPointURL"] = _variant_t(EndPointURL);

      pConnector->Property["SoapAction"] =
         _variant_t(CString(BASE_SOAP_ACTION_URI) + pMethodName);
      pConnector->BeginMessage();

      hr = pSerializer.CreateInstance(__uuidof(SoapSerializer));
      pSerializer->Init((IUnknown*)pConnector->InputStream);

      pSerializer->startEnvelope("","", "");
      pSerializer->startBody("");
      pSerializer->startElement(pMethodName,
                                WRAPPER_ELEMENT_NAMESPACE, "", "m");

      CString A;
      m_ACtl.GetWindowText(A);
      pSerializer->startElement("A", "", "", "");
      pSerializer->writeString(_bstr_t(A));
      pSerializer->endElement();

      CString B;
      m_BCtl.GetWindowText(B);
      pSerializer->startElement("B", "", "", "");
      pSerializer->writeString(_bstr_t(B));
      pSerializer->endElement();

      pSerializer->endElement();
      pSerializer->endBody();
      pSerializer->endEnvelope();

      pConnector->EndMessage();

      pReader.CreateInstance(__uuidof(SoapReader));
      pReader->Load((IUnknown*)pConnector->OutputStream, "");

      if(pReader->Fault != NULL)
      {
      MessageBox(CString(pReader->faultstring), NULL,
                 MB_ICONEXCLAMATION);
      }
      else
      {
         m_ResultCtl.SetWindowText(pReader->RPCResult->text);
      }
...

This example gives you some feeling of how to program it; once again, it's pretty similar to desktop programming.





Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel