Writing Mobile Code Essential Software Engineering for Building Mobile Applications [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Writing Mobile Code Essential Software Engineering for Building Mobile Applications [Electronic resources] - نسخه متنی

Ivo Salmre

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید











Web Services


The industry momentum behind Web services makes it a technology that is impossible to ignore. Just as th139-enabled proprietary sources of information are wrapped and exposed to end users using a standardized presentation model, so do Web services wrap and expose proprietary information sources to other applications. Web services allow applications to communicate using a commonly agreed upon high-level standardized XML-based language.

The primary intent o140 was to allow text-based documents to be linked together in a web. This turned out to be such a good idea that application programming models were built on top of the document presentation model, resulting in dynamically generated documents; HTML grew well beyond its original intent. The original intent of Web services was to allow different servers to communicate with one another using a standard XML-based communications protocol. Just as wit142, Web services technologies have grown past their original design goals and are now commonly used to link client applications to servers as well. Web services are the XML-based glue for linking together client and server applications.

Calling a Web service from a desktop application is a fairly trivial matter. Today desktop computers are online most of the time, and fast networks are available to provide high-bandwidth and low-latency communications. Web services can also be leveraged from mobile devices, but to do so effectively developers must take into account the differences in connectivity, bandwidth, and latency and tune a mobile application's usage of Web services accordingly.

A Very Brief Description of Web Services


A vast amount of literature already exists that describes Web services technologies. This information is available both online and in book form. For a detailed introduction to Web services, I recommend starting with MSDN's online documentation. However, to set the stage for further discussions on calling Web services from mobile devices, a very brief description of Web services is offered here.

Web services use specifically formatted XML messages to send and receive requests for computing services. A Web services "call" is a request from one computing device to another to perform some processing and usually return a result. Web services have the following characteristics:

Use of the SOAP protocol
SOAP stands for Simple Object Access Protocol and is a dialect of XML. Most commonly SOAP is used to call methods on a server and get results back. SOAP packages up a requested method's name and along with the method's parameters in XML and ships the XML up to the server for processing. The server receives the XML SOAP request, parses it to extract the method's name and parameters, and then calls the method. When the server method's processing is complete, a SOAP result is returned to the client as XML. The client parses the returned XML, extracts the results, and gives them to the calling program.

Use of WSDL documents
WSDL stands for Web Service Description Language. A WSDL document is a dialect of XML that describes a Web service. A WSDL document details what methods a Web service has, what parameters each method takes, and what the return values look like for each method. WSDL documents are typically machine generated and returned upon request from a Web services server. Software development tools download WSDL documents from Web service servers and generate client-side code to make it easy to call the described Web services on those servers. Each Web service has its own associated WSDL document.

Probable use of HTTP or HTTPS communications protocols for making requests and receiving responses
Although Web services can in theory run using a variety of different communications transports, including SMTP e-mail transports, in practice most Web service requests are sent via HTTP or HTTPS. This means that most Web services run on the same kinds of Web servers that serv139-based applications. This is particularly useful because HTTP and HTTPS requests are typically allowed through firewalls; making Web services access as simple as Web page access. If a given Web server can be accessed by your mobile application, Web services running on that server can also be accessed.


In addition to these basic Web services characteristics, additional layers of technology are being designed to go on top of SOAP and WSDL to address more sophisticated needs. For example, specifications such as WS-Reliability and WS-Security address reliable delivery and integrated security needs. More specifications are being created, debated, evolved, and standardized all the time. Web services technologies will expand and evolve greatly over the next 10 years. Programming tools and frameworks that take advantage of these new standards will tend to lag the emerging standards by a few years.

Calling Web Services from a Mobile Device


The ability for mobile devices to interact with the same kinds of Web services as desktop and server applications is a great boon for mobile application developers. Any device that can access Web pages has the built-in connectivity necessary to call Web services.

It is one thing to be able to call Web services and quite another to be able to do so easily. By analogy, it is relatively easy to downloa138, but much more work to transform tha153 into a meaningful visual experience for end users. For this reason, layered programming libraries exist to make working with Web services easier. In increasing order of abstraction, the layers are as follows:

The ability to make HTTP/HTTPS requests
In theory, if your mobile application can make a request of a Web server you can call a Web service.

The ability to generate and parse XML
Because the language of conversation in Web services is XML, the ability to parse and generate XML greatly simplifies working with Web services.

The ability to generate and parse SOAP messages
SOAP messages are a specific grammar built on top of XML. A programming library that allows your application to work at the conceptual level of SOAP requests and responses is much easier to work with than building these requests manually and interpreting the XML responses.

The ability to autogenerate proxy code for Web services client applications
Some software development tools are capable of downloading the WSDL documents that describe Web services and automatically generating the Web service client code needed to build the SOAP requests and parse returned SOAP responses. Autogenerated Web services client code greatly simplifies calling Web services. Instead of needing to write code to manually construct SOAP requests, send them to servers, and parse the results returned, developers can treat Web services requests as simple method calls. For example, a Web service that adds two numbers together can simply be called as follows:


MyWebService myWS = new MyWebService();
int result = myWS.AddTwoNumbers(2, 8);

A Web services client-side proxy class called MyWebService contains all of the needed logic to create the SOAP request, send it to the server, and parse the SOAP response.


The .NET Compact Framework supports all of the levels of abstraction described above in the same way that the desktop and server .NET Framework does. At the time of this writing, other mobile device technologies (for example, J2ME, native code) did not yet support some of the higher levels of abstraction, but Web services are such an important technology that it is likely that almost all future versions of mobile programming frameworks will make Web services easy to call. However, mobile runtime deployment takes time (often new hardware needs to be rolled out with new runtimes and libraries on the devices) and if you are working with a mobile device programming technology that does not yet have built-in support for Web services, you should be prepared to do some extra lower-level coding to generate the requests and parse the responses.

Creating a Web Service Using .NET


To create a Web service to test with, you will need to be running Internet Information Server (IIS) either on your local desktop or a server accessible to the mobile device you are testing. The IIS installation will need to have the proper server-side extensions for working your development tool as well; the Visual Studio .NET setup installer can help you configure these on IIS.

To create a Web service, follow these steps:


1.

Start Visual Studio .NET and create a new C# ASP.NET Web service project. The development tool will ask you for a location to create the Web service. For example, specifying http://localhost/WebService1 will create a Web service on your desktop machine, and http://MyWebServer/WebService1 will create a Web service called WebService1 on a server named MyWebServer.

Result:
A class called Service1 will be created, and a file called Service1.asmx will be deployed to the Web server you specified.

2.

Create a public Web method in the Service1 class. The snippet code in Listing 15.6 shows a simple method exposed as a Web service. Type the code into the Service1 class you created in Step 1.

3.

Press F5 to deploy and run the Web service project. A Web page will automatically be created for the Web service that shows what methods the Web service exposes and enables you to try calling the methods through a Web browser. To test the Web service, use a Web browser to navigate to the address of the Web service and class you specified in Steps 1 and 2 (for example, http://MyWebServer/WebService1/Service1.asmx).


Listing 15.6. Simple Web Service



//This code snippet goes inside the Service1 class
//in the file "Service1.asmx".
//
//"[WebMethod]" is a meta-data attribute that tells the Web
// service engine that this method should be web accessible
[WebMethod]
public int AddTwoNumbers(int x, int y)
{
return x + y;
}

Calling a Web Service from a Device Using the .NET Compact Framework


Note

Code running on a physical or emulated device is running on a different logical machine from your development machine; even if the emulator is running on the same physical machine as your Web server, it will not share the same machine name.

Because of this, you cannot use the URL //localhost/WebService1 to locate the Web service from the device; you must use the hosting machine's actual name (for example, //myDevMachine1/WebService1), just as if you were calling the Web service from another PC.

Calling a Web service from a device works almost exactly like calling a Web service from a desktop or server application. To call a Web service from a mobile device, follow these steps:


1.

Start Visual Studio .NET and create a new C# Smart Device Application.

2.

In the Project menu, select Add Web Reference. This will bring up a dialog that lets you browse and find the Web service you want to reference. Enter the URL of the Web service you created above (for example, http://MyWebServer/WebService1/Service1.asmx).

3.

In the Add Web Reference dialog, enter the text MyTestWebService in the Web Reference Name text box, and then click the Add Reference button. This will download the WSDL document that describes the Web service and then create a local proxy class in your project that enables you to easily call the Web service.

4.

Place a button on your application's form and double-click the button. This will bring you to the button's event handler code.

5.

Enter the following lines of code:


//Create an instance of the local proxy object
MyTestWebService.Service1 myWebService;
myWebService = new MyTestWebService.Service1();
//Tell the local proxy to call the web service
int sum = myWebService.AddTwoNumbers(2,3);
//Show the result of the Web service call!
System.Windows.Forms.MessageBox.Show(sum.ToString());

6.

Run your application and call the Web service.


In the preceding example, we chose to test calling the Web service synchronously. Synchronous calls are easy to test and debug, but in real-world scenarios we would almost certainly choose to call the Web service asynchronously. The autogenerated proxy class has facilities built in to it to enable this. To call the Web service asynchronously call myWebService.BeginAddTwoNumbers(…parameters…). Each Web service method in the local proxy class has a Begin* method to invoke the Web service asynchronously and an End* method to get the results back.

Mobile Device Challenges When Using Web Services


Although consuming Web services from a mobile device is in many ways similar to utilizing Web services from a server or desktop computer, there are some important differences. The sections below describe challenges that are either specific to or magnified on mobile devices.

Support for "Browser Cookies" Will Vary


A "cookie" is a piece of device-local data that is owned and managed by a specific Web site. Cookie data "owned" by a Web site gets sent up to the server along with the rest of a HTTP request. For instance, www.Mywebaddress.com and www.Yourwebaddress.com both could maintain separate cookies on a client machine accessing their Web sites. If a computing device and application support client-side cookies, every time the Web address or subaddress (for example, www.Mywebaddress.com/somepath/somepath1) is sent an HTTP request, the cookie data for the site is sent up to the server with the request. Cookies are often used to maintain per-client preferences on a Web site. A client-side cookie that is passed up with every request can be desirable from a server's perspective because it eliminates the need for the server (or group of servers acting together in a Web farm) to maintain server-side "session state" and can increase a Web application's scalability by allowing it to be stateless between requests. A Web site that lists the weather in your city and your four favorite stock listings is probably using client-side cookies to either maintain this data explicitly in the cookie or to hold a unique ID in the cookie that allows the server to look up the data in a server database. Cookies can be used to store short-term session data such as items in a Web "shopping cart" or longer-term data that persists over different sessions such as a user's long-term stock or weather-information preferences. However, client-side cookies have several important limitations:

They are client and machine specific.
If a Web application is using client-side cookies, those cookies will need to be re-created if the user accesses the Web application from a different machine. This means that preferences stored as client cookies do not travel with the user to different machines.

They are not always secure.
A Web application should not store valuable information in a cookie because that involves passing the valuable information back and forth with every call as well as keeping a copy of the information on the client machine where another malicious application may be able to access it through a client-side vulnerability. Sensitive information should be kept securely on a server and only passed around as needed.

They take up extra transmission space.
Because cookies are passed around with every Web request, they are using bandwidth. When passed over mobile phone networks, this extra baggage wastes time and costs money. The larger the cookie, the more bandwidth that is wasted.

Cookies have a limited capacity.
There is a limit to the amount of data a client-side cookie can hold.


In addition to the general limitations listed here, client-side cookies have another disadvantage when used with Web services: complexity. A Web service conversation can be viewed as a series of well-defined requests passed between a client and a server. Often these requests can be represented as method calls with parameters being passed in and results being passed back. Using cookies while calling Web services represents a second hidden channel of communication between the client and server, and this can cause confusion. Listing 15.7 shows a Web service being called without using cookies, and Listing 15.8 shows how the same example might look if cookies were used to replace some of the parameters being passed.

Listing 15.7. Web Service Calls with Only Explicit Parameters Being Passed



//0. Establish a session
int sessionID = someWebService.LogOn(userCredentials);
//
//...Lots of other code gets run...
//
//1. Call a Web service and create a new order
int orderID = someWebService.CreateNewOrder(sessionID, userInfo, productInfo);
//
//...Lots of other code gets run...
//
//2. Confirm the order with the server
someWebService.ConfirmPayment(sessionID, orderID, paymentInfo);
//
//...Lots of other code gets run...
//
//3. Confirm the shipping address
someWebService.ConfirmShipping(sessionID, orderID, shippingAddress);
//
//...Lots of other code gets run...
//
//4. Finalize order
someWebService.FinalizeOrder(sessionID, orderID);

This code is relatively simple to follow. In Step 1, a new order is created and an orderID is returned to use in subsequent calls. This orderID is passed into each subsequent call, and it is clear that each of the Web service calls can identify the order being processed using the orderID that is passed in.

Instead of using an explicit orderID, the Web service implementer could have stuffed this information into a client-side cookie. In this case, the client-side code would look like Listing 15.8.

Listing 15.8. Web Service Calls with Implicit Parameters Passed via Cookies



//0. Establish a session
//Although you can't see it, this will pass back a client cookie!
int sessionID = someWebService.LogOn(userCredentials);
//1. Call a Web service and create a new order
//Although you can't see it, this will pass up a client cookie!
//Although you can't see it, this will pass back a client cookie!
someWebService.CreateNewOrder(userInfo, productInfo);
//
//...Lots of other code gets run...
//
//2. Confirm the order with the server
//Although you can't see it, a client-side cookie is passed
//up to the server containing the "orderID". Sneaky!
someWebService.ConfirmPayment(paymentInfo);
//
//...Lots of other code gets run...
//
//3. Confirm the shipping address
//Although you can't see it, a client-side cookie is passed
//up to the server containing the "orderID". Sneaky!
someWebService.ConfirmShipping(shippingAddress);
//
//...Lots of other code gets run...
//
//4. Finalize order
//Although you can't see it, a client-side cookie is passed
//up to the server containing the "orderID". Sneaky!
someWebService.FinalizeOrder();

The code above looks fairly simple, but as noted in the comments there is a second channel of communication that is hidden from the programmer. Hidden parameters are being passed back and forth between the client and the server via cookies. This is a good reason not to use client-side cookies when designing Web services. It is far better to explicitly pass all the parameters needed for a Web service request than to rely on an opaque second channel to hold this information.

Many mobile device platforms either do not support client-side cookies or their support differs substantially from what desktop computers and programming frameworks offer. Specifically, the .NET Compact Framework running on Smartphones, Pocket PCs, or Windows CE devices does not automatically support passing cookies back and forth via Web service requests. If you want to take any cookies sent down by a server and send them back up to the server in a subsequent request, you will have to write code to read the cookies from one HTTPWebResponse's headers and write them out into the subsequent HTTPWebRequest's headers. In the case of calling Web services, this will require that you examine and modify the client-side Web service proxy code that is autogenerated for you by Visual Studio .NET. This is by no means impossible, but it is extra work that you will need to be aware of. This is an important difference between desktop and device programming framework support.

Despite the fact that the use of client-side cookies is discouraged when building Web services, some services may use them to store session data such as logon information. If a Web service works when calling it from a desktop computer but mysteriously fails when calling it from a mobile device, cookie usage may be to blame. If possible, check with the Web service's author to see whether the service is using cookies; this is always easier than trying to reverse engineer what is going on. If it is not possible to get this information from the Web service's author, you can try to test this empirically by changing the cookie policy on the desktop computer; this is specified in Internet Explorer in the Tools->Options dialog under the Privacy tab. In addition, if you want to delve into low-level Web services client code, you can examine the client-side cookies collection returned in the HTTPResponse of a Web request. If client-side cookie dependencies are at fault, you have three possible courses of action: (1) Get the Web service to support a cookie-less access model, which in any case is good engineering; (2) build a server-based wrapper Web service that serves as an intermediary between mobile devices and the offending Web service (this wrapper will need to explicitly maintain cookie data for its clients); or (3) write your own device-side code to explicitly handle collecting the cookies returned by any Web server responses and packing them back into subsequent Web requests.

Often the First Call to a Web Service Has Additional Latency


The first call your mobile application makes to a Web service can incur significant performance overhead. Several things need to take place when a Web service call is first made:

Code may have to be loaded.
If XML, Web service, network, and other client-side classes have not been loaded into memory yet, they will need to be loaded and compiled before they can be used to call Web services. All of this takes time, possibly a few seconds.

The address of the Web service may need to be looked up.
For example, if you are calling a Web service on www.myWebService.com, this address will need to be mapped into an IP address (for example, 200.134.81.26) to locate the server. This lookup occurs by asking a DNS server to translate the Web address into an IP address. Name lookup requests from DNS servers take time; the request has to be packed up, sent to the DNS server, and your mobile application will have to wait for the reply before actually contacting the server with the Web service you want to call. Most mobile devices should cache this address locally so that subsequent requests to the server do not require DNS lookup. Name resolution can take a significant amount of time and can easily be the largest source of latency when calling a Web service for the first time. As a general rule, looking up a local network name (for example, //myLocalServer) should be quicker than looking up a World Wide Web name (for example, www.myWebServer.com).

When measuring the response times of Web services, it is useful to separate the measurement into two parts: (1) Measure the response time for the first call; (2) measure the average response time for subsequent Web service calls.

Because Web service requests rely on resources out of your application's immediate control, it is always a good idea to make these calls asynchronously to your application's user interface thread. Despite this there will be cases where the mobile application's user makes a request for information or attempts to perform a transaction and needs to wait for its completion before moving on. In these cases, it is worth doing everything possible to speed up the server communication. If your application knows that it is going to need to call a Web service on behalf of a user, it may be worth making a background "dummy call" to that same Web service prior to the user needing to make a real request. The "dummy call" will preload any necessary classes into memory and cache any IP addresses needed for subsequent calls.

Passing Large Amounts of Data via a Web Service Request Is Inefficient


Although it is possible to pass an array of 2,000 integers up to a Web service or to download an array of the same from a Web service, it is never a good idea to do so. Web services are optimized for flexibility and HTTP protocol friendliness. For this reason, Web services use a large amount of text relative to the information being passed. For example, the number 32 can be represented in 1 byte of data as 00100000. Passing an integer, 32, as XML looks roughly like <int>32</int>, which is about 14 bytes of data; the same holds true for other kinds of data. The properties that make Web services and XML flexible also make them inefficient for moving larger amounts of data around.

If your Web service needs to transfer a significant amount of data, the best way to do this is to have the Web service return a pointer to a binary data file rather than streaming the data as XML. A good example is a Web service that returns photographic images. Although it is possible for a Web service to return an image as an array of bytes or integers coded in XML, it is far more efficient to return a string that contains a URL pointing to a binary file that can be downloaded by the mobile application (for example, //somewebserver/someshare/somedir/somefile.jpg). This is exactly what Web browsers do; they download human-readable text and layout information a152 and th139 contains links to the binary image files that go into the layout. It is important to think carefully about the kind of data being moved around and to optimize for it if it is large.

Chatty Mobile Network Conversations Are Very Expensive


Each request sent to a server requires a conversation to be started, negotiated, and completed; this incurs communications overhead. Five separate Web service calls, each with one parameter, will be much more wasteful than one request that contains five parameters. In addition, because of the intermittent nature of mobile communications, making five smaller requests instead of one larger request creates a higher probability of failure during the conversation between device and server. This means complex cleanup logic will need to be written to recover when things do go wrong mid-conversation. A single Web services call has both a lower chance of communications failure as well as simpler cleanup logic if things do go wrong.

Note

When using Web services, it is still better to transfer binary data via a second request rather than trying to stream a large amount of data as XML. Because binary data becomes very verbose when expressed in XML, it will require a long amount of time to transfer. Long transfer times increase the odds of failure during the transfer. A better model is to make a single Web service call to pass all the data that can be passed reasonably efficiently as XML and subsequent calls to transfer binary files such as images. Listing 15.11 contains code to download a file from a Web server and store it locally. If multiple files' worth of binary data need to be transferred, it may also be useful to experiment with combing all the binary data into a single compressed file; this single combined file can be sent as binary data and decompressed at the other end.

Listing 15.9 shows a chatty Web service conversation with multiple requests and responses. Listing 15.10 shows the same conversation being batched up and processed in one request/response cycle. Whenever possible, it is a good idea to consolidate multiple requests into a smaller number of larger requests.

Listing 15.9. A Chatty Conversation with Multiple Web Service Calls



//--------------------------------
//Create and process an order
//--------------------------------
//0. Establish a session
int sessionID = someWebService.LogOn(userCredentials);
//1. Call a Web service and create a new order
int orderID = someWebService.CreateNewOrder(sessionID, userInfo, productInfo);
//2. Call the Web service and pass in payment info
someWebService.ConfirmPayment(sessionID, orderID, paymentInfo);
//3. Call the Web service and pass in shipping information
someWebService.ConfirmShipping(sessionID, orderID, shippingAddress);
//4. Call the Web service and finalize the order
someWebService.FinalizeOrder(sessionID, orderID);

Listing 15.10. A Batched Conversation with a Single Web Service Call



//----------------------------------------------
//Create and process an order in a batch request
//that combines:
// 0. Session initiation
// 1. Creating a new order
// 2. Confirming payment
// 3. Confirming shipping
// 4. Finalizing the order
//----------------------------------------------
//Do everything at once
someWebService.BatchCreateOrder(userCredentials, userInfo,
paymentInfo, shippingAddress);

Listing 15.11 is sample code that downloads a binary file from a server and stores it locally on the device. This code may be useful if you need to download files such as images from a server.

Listing 15.11. Code to Download a File from a Web Server



//-------------------------------------------------------------
//Performs a synchronous download of a file on a Web server
//of a file and stores it to a local file system
// [in] httpWhereFrom: URL to file
// (for example, "http://someserver/somefile.jpg")
// [in] filenameWhereTo: File location to write the file to
// (for example, "\\localfile.jpg")
//-------------------------------------------------------------
public void downloadFileToLocalStore(string httpWhereFrom,
string filenameWhereTo)
{
System.IO.FileStream myFileStream = null;
System.IO.Stream myHTTPResponseStream = null;
System.Net.WebRequest myWebRequest = null;
System.Net.WebResponse myWebResponse = null;
//If the location we want to write to exists, delete it
if(System.IO.File.Exists(filenameWhereTo) == true)
{
System.IO.File.Delete(filenameWhereTo);
}
try
{
//Create a Web request
myWebRequest =
System.Net.HttpWebRequest.Create(httpWhereFrom);
//Get the response
myWebResponse = myWebRequest.GetResponse();
//Get the stream for the response
myHTTPResponseStream = myWebResponse.GetResponseStream();
//Create a local file to stream the response to
myFileStream = System.IO.File.OpenWrite(filenameWhereTo);
//This buffer size can be tuned
const int buffer_length = 4000;
byte [] byteBuffer = new byte[buffer_length];
int bytesIn;
//Read in the file and stream it to a local file
do
{
//Read data in
bytesIn = myHTTPResponseStream.Read(byteBuffer,
0, buffer_length);
//Write data out
if(bytesIn != 0)
{
myFileStream.Write(byteBuffer, 0, bytesIn);
}
}while(bytesIn != 0);
}
catch(Exception myException) //Download failed!
{
//Something bad happened. Let's clean up
attemptCleanup_ThrowNoExceptions(myFileStream,
myHTTPResponseStream, myWebResponse);
//Now that we've cleaned up, rethrow the exception
//So that the application knows something went wrong!
throw myException;
}
//Download has succeeded!
//Lets close everything down.
try
{
//Normal clean up.
myFileStream.Close(); myFileStream = null;
myHTTPResponseStream.Close(); myHTTPResponseStream = null;
myWebResponse.Close(); myWebResponse = null;
}
catch(Exception myException) //Failure during a close!
{
//Something bad happened. Let's clean up
attemptCleanup_ThrowNoExceptions(myFileStream,
myHTTPResponseStream, myWebResponse);
//Now that we've cleaned up, rethrow the exception
//So that the application knows something went wrong!
throw myException;
}
//Success!
}
//------------------------------------------
//Tries to close and clean up everything
//Traps any exceptions that might be thrown.
//------------------------------------------
void attemptCleanup_ThrowNoExceptions(
System.IO.FileStream myFileStream,
System.IO.Stream myHTTPResponseStream,
System.Net.WebResponse myWebResponse)
{
if(myFileStream != null)
{
try
{ myFileStream.Close(); }
catch
{} //Do nothing.
}
if(myHTTPResponseStream != null)
{
try
{ myHTTPResponseStream.Close(); }
catch
{} //Do nothing.
}
if(myWebResponse != null)
{
try
{ myWebResponse.Close(); }
catch
{} //Do nothing.
}
} //end function

Working with Heterogeneous Network Topologies Can Be Challenging


Desktop and server computers sit in relatively stable network topologies; things may behave well or poorly, but they usually behave fairly consistently. Part of this stability is due to the greater maturity of desktop networking, and part of it is due to the simple fact that the pieces do not move very often. A laptop roaming through different Wi-Fi environments may experience some variance, but because Wi-Fi is intended to mimic wired connectivity the variances are usually moderate; some allowances may have to be made for bandwidth differences, proxy settings, and security configuration. Using a mobile telephone network for data communication can add further complexities because bandwidth and reliability can vary significantly. A mobile device that roams in between different mobile telephone operators' networks will add still more variance and intricacies. By using widely tested and supported Web protocols for communication, Web services can be useful in abstracting many of the details of communication networks, but there are still a few things that must be kept in mind if your mobile application is going to function well across a wide range of networks:

Generally data rates will be slower, connection latencies will be higher and both will be more variable.
Inevitably the data rates you experience on wireless networks will be lower than wired systems. What may not be obvious at first glance is that establishing a network communication channel may take more time as well. All of this will have a direct effect on how well Web services requests perform on different mobile networks. Some mobile phone networks' data facilities will be significantly faster and lower latency than others. It is important to keep this in mind as you develop and test your Web services.

Proxy servers may need to be set up manually.
Solutions that run on corporate networks often access the Internet via a proxy server that sits between the intranet and the World Wide Web. While desktop and laptop computers often have these proxy connections set up automatically mobile devices may not. If you are experiencing problems calling a Web service from a mobile application, it is often a good idea to try to see whether the Web browser on that device can access the same Web server. If you cannot access the server with a Web browser, you probably need to manually configure the proxy settings on the device.

GPRS connections and other mobile network connections may need to be configured manually.
Similar to corporate proxy servers, many mobile networks have the concept of an access point through which Internet communication occurs. On 2.5G GSM networks, this is known as a GPRS connection and may need to be configured manually for each mobile network the device roams onto. The device may need to have usernames, passwords, and DNS addresses configured. As with proxy servers, a good test for a working connection is to see whether the Web browser on the device is capable of accessing the Internet. If the Web browser is working, the Internet connection for your mobile application is probably good.

Different mobile phone networks may behave in unexpected ways.
Internet access via mobile telephone networks is still somewhat of a work in progress. In the old days (two to three years ago), phones came with hard-wired functionality for voice and limited data services; this was easy for mobile phone network operators to test because they knew what kind of requests were going to be made through their networks. Today we are in the middle of an explosion of flexible multipurpose phone hardware. Although mobile telephone network infrastructure is steadily moving toward good support of smart phones that are generic application platforms, this transformation is not yet complete. Because of this, there may still be some hard-coded server infrastructure that is expecting specific client applications and protocols. For example, a few years ago we encountered a mobile network that was always sending back HTTP responses that were compressed and thus indecipherable to client applications that were expecting plain-text data. This caused Web service responses to appear as scrambled information bearing no resemblance to the XML data expected back. The reason for this was that the Internet browser on the client phones knew to expect compressed data and how to decompress it, but this facility was not available to other applications. Temporary workarounds were required to enable generic client applications to pass in a modified HTTP request header that explicitly insisted on uncompressed responses. It is reasonable to assume that most of these kinds of issues are ironed out now, but doubtless a few "gotchas" still remain to be discovered. For this reason, it is recommended that you take a layered approach to diagnosing problems that occur. If problems occur while accessing a Web service, I recommend the following sequence of debugging steps: (1) Try calling the Web service from a desktop application; if this does not work then things are broken in a nondevice-specific way. (2) Try to browse the Web from the client device; if this works it means you have Internet connectivity. (3) Try to download files from the same Web server in question using a .NET Compact Framework System.Net.HttpWebRequest as shown in Listing 15.11; if this works and the file downloaded is intelligible, the data is getting to your application properly. (4) Try calling the Web service from a desktop application with client-side cookies turned off. (5) Step through the autogenerated Web service client-side code in your application line by line to see exactly where things are going wrong. These kinds of problems can be frustrating to debug when they occur; a disciplined and step-by-step approach will yield the best results.


There is no substitute for testing on the networks your solution will be deployed on. If your mobile solution is intended to roam between different networks, you will benefit greatly from testing on different mobile networks to get a feel for what variances your application will have to deal with.


/ 159