Table of ContentsUsing TimersPersistence (RMS)

Networking

The MIDP includes support for the Generic Connection Framework that is part of the CLDC. However, the MIDP specifications only mandate that an HTTP connection is included in any implementation. This isn't as bad as it sounds; if you had any ideas about writing a high-performance action multiplayer game in the wireless world, I suggest you keep your pants on. Right now you have to design the networking elements of your game around high latency (the time it takes for data to move from one point to another) and high packet loss (the chance that data may not arrive at all). Sub-50ms UDP gaming is out of the question at the moment.

The design of the Generic Connection Framework is reasonably simple. Use the static factory Connector class to build and return a connection. Figure 5.3 shows the full class hierarchy of the available connection types.

Figure 5.3. The Generic Connection Framework provides a full spread of general-purpose communications classes; however, the MIDP only guarantees support for HttpConnection.

graphic/05fig03.gif


Working with the Connector

The Generic Connection Framework design includes the concept of a single super-connector class that serves as a factory for any type of supported connection. Basically, you make a static call to the Connector class's open method, passing in the name of the resource to which you want to connect. This location name should be in the form protocol:address;parameters.

For example, here's how you would get a connection to an HTTP resource:

Connector.open("http://java.sun.com");

To establish a direct socket connection (if it is supported), you would use something like:

Connector.open("socket://127.0.0.1:999");

In your case, you'll stick to using the HttpConnection.

Table 5.5. javax.microedition.io.Connector

Method

Description

static Connection open(String name)

Constructs, opens, and returns a new connection to the specified URL name.

static Connection open(String name, int mode)

Constructs, opens, and returns a new connection to the specified URL name and access mode.

static Connection open(String name, int mode, boolean timeouts)

Constructs, opens, and returns a new connection to the specified URL name, access mode, and a Boolean indicating whether you want to see timeout exceptions being thrown.

static Connection openDataInputStream(String name)

Opens a connection and then constructs and returns a data input stream.

static Connection openDataOutputStream(String name)

Opens a connection and then constructs and returns a data output stream.

static Connection openInputStream(String name)

Opens a connection and then constructs and returns an input stream.

static Connection openOutputStream(String name)

Opens a connection and then constructs and returns an output stream.


Working with HttpConnection

The HttpConnection class is a full-featured HTTP client that serves very well for most (low-latency) network tasks. For games, you can use it to download content on demand (such as a new level), update scores or higher-level meta-game data, or even to implement inter-player communications. You can see all the methods available in the HttpConnection class in Table 5.6.

Table 5.6. javax.microedition.io.HttpConnection

Method

Description

Header Methods

long getDate()

Retrieves the date header value.

long getExpiration()

Retrieves the expiration header value.

String getHeaderFieldKey(int n)

Retrieves the header key by index.

String getHeaderField(int n)

Retrieves the header value by index.

String getHeaderField(String name)

Retrieves the value of the named header field.

long getHeaderFieldDate(String name, long def)

Retrieves the value of the named header field in the format of a date long. If the field doesn't exist, the def value is returned.

int getHeaderFieldInt(String name, int def)

Retrieves the value of the named header field as an integer. If the field doesn't exist, the def value is returned.

long getLastModified()

Returns the last modified header field.

Connection Methods

String getURL()

Returns the URL.

String getFile()

Get the file portion of the URL.

String getHost()

Returns the host part of the URL.

int getPort()

Returns the port part of the URL.

String getProtocol()

Returns the protocol part of the URL.

String getQuery()

Returns the query part of the URL.

String getRef()

Returns the ref portion of the URL.

int getResponseCode()

Returns the HTTP response status code.

String getResponseMessage()

Returns the HTTP response message (if there was one).

Request Handling Methods

String getRequestMethod()

Returns the request method of the connection.

void setRequestMethod(String method)

Sets the method of the URL request. Available types are GET, POST, and HEAD.

String getRequestProperty(String key)

Returns the request property value associated with the named key.

void setRequestProperty(String key, String value)

Set the request property value associated with the named key.


In the following sample MIDlet, you'll create a connection to a popular Web site, drag down the first few hundred bytes of content, and then display it. Thankfully, actually doing this is as simple as it sounds.

import java.util.*;
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;

import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;

/**
 * A demonstration MIDlet which shows the basics of HTTP networking.
 * @author Martin J. Wells
 */
public class NetworkingTest extends javax.microedition.midlet.MIDlet
{
   private Form form;

   /**
    * MIDlet constructor that instantiates a form and then opens up an HTTP
    * connection to java.sun.com. It then reads a few bytes and adds those as
    * a string to the form.
    * @throws IOException if a networking error occurs
    */
   public NetworkingTest() throws IOException
   {
      // Setup the UI
      form = new Form("Http Dump");

      // Create a HTTP connection to the java.sun.com site
      InputStream inStream = Connector.openInputStream("http://java.sun.com/");

      // Open the result and stream the first chunk into a byte buffer
      byte[] buffer = new byte[255];
      int bytesRead = inStream.read(buffer);
      if (bytesRead > 0) 
   {
      inStream.close();

      // Turn the result into a string and display it
      String webString = new String(buffer, 0, bytesRead);
      form.append(webString);
   }
}

/**
 * Called by the Application Manager when the MIDlet is starting or resuming
 * after being paused. In this example it acquires the current Display object
 * and uses it to set the Form object created in the MIDlet constructor as
 * the active Screen to display.
 * @throws MIDletStateChangeException
 */
protected void startApp() throws MIDletStateChangeException
{
   // display our UI
   Display.getDisplay(this).setCurrent(form);
}

/**
 * Called by the MID's Application Manager to pause the MIDlet. A good
 * example of this is when the user receives an incoming phone call whilst
 * playing your game. When they're done the Application Manager will call
 * startApp to resume. For this example we don't need to do anything.
 */
protected void pauseApp()
{
}

/**
 * Called by the MID's Application Manager when the MIDlet is about to
 * be destroyed (removed from memory). You should take this as an opportunity
 * to clear up any resources and save the game. For this example we don't
 * need to do anything.
 * @param unconditional if false you have the option of throwing a
 * MIDletStateChangeException to abort the destruction process.
 * @throws MIDletStateChangeException 
    */
   protected void destroyApp(boolean unconditional) throws MIDletStateChangeException
   {
   }
}

NOTE

Tip

You can see the complete source code in the NetworkingTest.java on the CD (Chapter 5 source code).

All of the action happens in the constructor. The connection is first opened using the following code:

InputStream inStream = Connector.openInputStream("http://java.sun.com/");

The static Connector.openInputStream is a convenience method to both establish the connection and return an input stream from that connection. If you wanted to play around with the HTTP aspect of things, you could do so in two stages, and thus retain a reference to the HttpConnection. For example:

HttpConnection http =
(HttpConnection)Connector.openInputStream("http://java.sun.com/");
InputStream inStream = http.openInputStream();

The subsequent code within the constructor simply reads the first chunk of data from the input stream into a buffer and displays it. You don't bother reading the whole page because displaying it would be a bit like trying to draw the Mona Lisa with a neon pink highlighter.

    Table of ContentsUsing TimersPersistence (RMS)