NOTE: The Networking Toolkit is being made available in Alpha form only, to support the RMS Toolkit’s network store capability (example: ExpensePad.)  The Networking Toolkit API is likely to change.  Documentation is being provided for those features required by the RMS Toolkit.

Classes

The Networking Toolkit API consists of classes and interfaces found in the com.nextel.net package.  Two test drivers are included in the toolkit for use with the HTTP service.  The test drivers reference the com.nextel.util.Debug.UNIT_TEST attribute.  When running the test drivers, this attribute should be set to true.  Below are descriptions of the classes and interfaces found in the com.nextel.net package.

1.      HttpRequest – A class that implements HTTP requests synchronously.  Methods of this class will directly return the InputStream that results from successful HTTP requests with network resources.

2.      HttpRequestDriver – A test class for unit testing the HttpRequestClass.  This class provides the HttpRequest with testing the correctness of its methods apart from network dependencies.  To use this class, first set the Debug.UNIT_TEST attribute in com.nextel.util to true.

3.      OInputStream – A Timeable class that represents an extended InputStream that is monitored for timeout conditions during read operations.  This class is bound to a RequestTimer.  The HttpRequest and HttpAsyncRequest class will use instances of OInputStream if a timeout value greater than 0 is used.

4.      Request – A base class for request objects.

5.      RequestListener – An interface that describes the behavior of classes that respond to request progress.   It would be common for a MIDlet class to implement this interface so that it will be notified of completed requests or problems encountered during the request transmission.

6.      RequestTimer – A class that monitors operations for timeout conditions.  RequestTimers are used to monitor latency while making connections, obtaining streams, and during stream operations.

7.      Timeable – An interface that describes the behavior of a class that requires monitoring of timeout conditions.  These are specifically classes that initialize RequestTimer instances.  HttpRequest, UDPReliableRequest and OInputStream implement the Timeable interface.

8.      TimeoutException – An exception class that signifies a timeout condition.  Instances of this class are typically communicated to RequestListeners through the RequestListener.exception(Exception, Request) method.

Requests and RequestListeners

The RequestListener interface describes classes that respond to request activity. Not all request classes require a RequestListener.  The HttpRequest class performs its operations synchronously as called.  In using the HttpRequest class, an InputStream is returned from get() and post() calls.  Programmatically, execution will continue once the InputStream is returned and operations on the stream are performed. 

The completed() method on the RequestListener provides a mechanism for indicating that the request has finished transmitting the request.  The completed method is provided a copy of the Request that invoked the method.  With this instance, attributes of the Request can be retrieved for further processing.  An example of this would be to use the passed in Request to retrieve the InputStream which then could be read from to retrieve data from the network resource that was requested.  The completed() method can serve as a control mechanism for sending multiple requests if each subsequent send is only initiated once the completed() has been called.  In this manner, requests will not be sent until the previous request has completed thereby reducing the risk of exhausting socket resources.

The exception() method on the RequestListener provides notification about request failure.  Similar to the completed() method, exception() is a chained method between bound instances of RequestListeners.  This method gets invoked from within Request objects once it has been determined that the request cannot be successfully completed.  For Requests that support latency timeouts and retries, the exception() method would only be invoked once the number of retries has been reached.  The exception method, is called with an instance of the Request that the RequestListener is monitoring and the exception resulting from the failed transmission. 

Requests and RequestTimers

Request types can be instantiated with an optional timeout value.  This value, if greater than 0, causes the request to use a RequestTimer for monitoring of timeout conditions during request handling.  The RequestTimer is instantiated with the Timeable instance that it monitors.  The request will then call into the RequestTimer before and after critical operations that need monitoring for latency.  Such operations in the request are obtaining the Connection and InputStream.  If these operations succeed without incurring a timeout, the RequestTimer is terminated.  Because of the high probability of latency timeouts while reading from an InputStream, the returned stream is configured with a RequestTimer.  This timeable InputStream is the OInputStream class.  In the OInputStream, read calls are embedded with start and stop calls to the RequestTimer to enable detection of timeouts.  This allows the program using the InputStream to benefit from not permitting blocked reads to occur.  If a timeout is set, the RequestTimer will call the OInputStream timeout method if such a condition is warranted, allowing the stream class to terminate the blocked read condition.  If this occurs, the application will need to reissue the request.  The reason for this is that programmatically the only way to interrupt the blocked stream is to close both the stream and connection involved.

TimeoutException

If the KVM times out and throws an exception it throws a TimeoutException that is a subclass of java.io.IOException.  For the toolkit to be consistent with these timeouts, timeout conditions detected through a RequestTimer throw com.nextel.net.TimeoutException which also is a subclass of java.io.IOException.  Timeout conditions occur when a RequestTimer detects a set period of latency and calls the timeout() method on the timeable instance to which it is bound.  The timeout() method is responsible for implementing the necessary actions for that type of request to terminate the current transmission.  The timeout method then creates a com.nextel.net.TimeoutException and passes it up through the associated RequestListeners through the RequestListener exception() method.

There are two places where this course of action is incurred.  The first is from within the Request object itself.  Requests that are Timeable objects, by definition will contain the timeout() method that the RequestTimer invokes once the timeout condition has occurred.  The RequestTimer is activated from within the Request during creation of, and transmission over, the network connection.  If a timeout occurs during this use of the connection, the timeout method will be invoked.  Inside the timeout method, the current request attempt will be checked to determine if more retries are available.  If more retries exist, a timeout exception is not created, and the timeout method exits.  Within the Request, an IOException will occur due to the timeout method having closed the connection.  The exception will get caught and being that there are more retries available, the request will get initiated again.  If there are no additional retries, the TimeoutException is created and sent up the exception() method of the RequestListener.

The second place where timeout occur is while performing stream operations.  If the Request was created with a timeout option greater than 0, the resulting InputStream available from the Request is an instance of OInputStream.  OInputStream is a timeable object and its operations become monitored by a RequestTimer.  If an operation upon the OInputStream incurs a timeout, the OInputStream timeout() method will become invoked.  Inside this method, the underlying DataInputStream and Connection are closed and an internal timeout flag is set.  With the stream and connection closed, subsequent operations on the OInputStream will result in an IOException.  The timeout flag is used to determine if the impending IOException is a result of a timeout.  To make this determination, all operations are checked for IOExceptions and should one occur, the flag is checked.  If the timeout flag is set, the IOException is a result of the timeout, resulting in the creation and handling of a TimeoutException through the RequestListener exception() method.  This handling is particularly necessary since the timeout() method and OInputStream read operations occur on different threads.

Resources

It is important to be aware of the limited resources available to the developer when creating applications for the handset.  With respect to networking applications the critical resource constraint is with sockets.  At the time of developing this toolkit the handset only supported the use of two concurrent sockets.  This constraint does not affect the developer’s use of the HttpRequest class since this class provides a synchronous service.

Examples

The previously mentioned expense pad example in com.nextel.examples.expensepad.ExpensePad utilizes the network toolkit support for http connections.