WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button

Developing Web-Service-Driven, Smart Mobile Applications
Pages: 1, 2

Session ID in the RPC Protocol

For earlier devices that cannot upgrade to Service Pack 1, we cannot easily use cookies on the client side. The solution is to build the session ID into the RPC protocol as a mandatory call argument. An added benefit here is that this solution is not dependent on the underlying HTTP transport. If we extend the service in the future beyond HTTP (e.g., over an asynchronous messaging protocol), this approach would still work.



In this setup, the facade web method getSID creates an empty CachedRoute object, generates a random session ID based on the current time, stores it in the global cache, and then returns the session ID.

Random rand = new Random ();

[WebMethod]
public String getSID () {
  String sid = DateTime.Now.Ticks.ToString() + rand.Next().ToString();
  Context.Cache.Add(sid, new CachedRoute(), null, DateTime.MaxValue, 
                    TimeSpan.Zero, CacheItemPriority.Default, null);
  return sid;
}

The getSID method must be invoked at least once before any other facade remote method can be called. When a session ID is passed to a remote service method, the server calls the getCache method to locate the proper CachedRoute object.

private CachedRoute getCache(String sid) {
    return (CachedRoute) Context.Cache.Get(sid);
}

The getDirections method populates the CachedRoute object with route and segment objects; the getMap method renders a GIF map for the requested segment based on the route information in the CachedRoute object.

[WebMethod]
public String [] getSidDirections (String sid, String fromStreet, 
          String fromCity, String fromState, String fromZip, 
          String toStreet, String toCity, String toState, String toZip) {
  CachedRoute cache = getCache(sid);
  return getDirections(cache, fromStreet, fromCity, 
    fromState, fromZip, toStreet, toCity, toState, toZip);
}

In fact, a mobile client can cache several different routes using different session IDs. We can manage those IDs on the client side and further improve the efficiency of the application.

The Facade Client

The facade client MPClient has a useCookie flag, which indicates whether the client wants to use HTTP cookies for session tracking. Depending on the useCookie flag setting, MPClient instantiates the appropriate proxy object and dispatches to the corresponding remote methods.

public class MPClient {
  private String sid;
  private bool useCookie;
  private FacadeService facade;

  public MPClient(bool useCookie) {
    this.useCookie = useCookie;
    if (useCookie)  {
      facade = new SessionFacadeService ();
    } else  {
      facade = new FacadeService ();
      sid = facade.getSID ();
    }
  }

  public String [] getDirections(String fromStreet, String fromCity,
    String fromState, String fromZip, String toStreet,
    String toCity, String toState, String toZip) {
    if (useCookie) {
      return facade.getSessDirections(fromStreet, fromCity,
        fromState, fromZip, toStreet, toCity, toState, toZip);
    } else {
      return facade.getSidDirections(sid, fromStreet, fromCity,
        fromState, fromZip, toStreet, toCity, toState, toZip);
    }
  }

  // ...

}

For example, in the Smartphone UI, we use cookies for session tracking, while in the PocketPC UI, we use RPC arguments.

UI Design

With the facade in place, now it is time to develop the mobile front-end UI. We use the Windows Form visual designer in Visual Studio .NET for this task. As shown in Figure 3, the .NET Compact Framework visual UI designers for both Smartphone and PocketPC offer a wide selection of widgets and produce realistic-looking design layouts.

PocketPC and Smartphone Windows Form designers
Figure 3. PocketPC and Smartphone Windows Form Designers

All widgets have the native PocketPC or Smartphone look and feel. Services from the underlying OS, such as multiple text entry methods and predictive text, are available. The UI event-handling model is intuitive and takes advantage of advanced .NET language features such as the C# delegates.

PocketPC

PocketPC widgets such as the tabbed control, contextual menu, progress bar, and DataGrid are very useful in making the best use of the limited screen real estate on the pen-based mobile UI. The PocketPC client is based on tabbed pages navigation and it is shown in action in Figure 4.

The PocketPC 2003 UI in action
Figure 4. The PocketPC 2003 UI in Action

Smartphone

On Smartphones, fewer widgets are supported, due to the limited screen size and input methods (the gray controls on the designer are not supported). In particular, the button control is not supported. Instead, you have to use the menu control, which will be mapped to the two soft buttons on the Smartphone device. The left-side soft button can only be mapped to a single menu item for "one hand" operation. The right-side button can be mapped to a hierarchy of sub-menus. The smartphone client is based on multiple forms navigation (Figure 5). A static Controller class holds references to those forms and controls their display.

The Smartphone 2003 UI in action
Figure 5. The Smartphone 2003 UI in Action

public class Controller : System.Windows.Forms.Form {
  private static FromAddr from;
  private static ToAddr to;
  private static DirectionsList directionsList;
  private static DrivingMap drivingMap;
  private static Form current;

  private static MPClient mpclient;
  // ... ...
  
  // To enforce singleton pattern for the controller
  private Controller() {
    // We use HTTP cookie for session tracking
    mpclient = new MPClient (true);
  }
  
  static void Main() {
    from = new FromAddr ();
    to = new ToAddr ();
    directionsList = new DirectionsList ();
    drivingMap = new DrivingMap ();
  
    Application.Run(new Controller());
  }
  
  public static void showDirections (bool reload) {
    if (reload) {
      String [] directions = mpclient.getDirections(
               from.street, from.city, from.state, from.zip,
              to.street, to.city, to.state, to.zip);
      ArrayList al = new ArrayList ();
      al.Add("Overview Map");
      for (int i = 0; i < directions.Length; i++ ) {
        al.Add( directions[i] );
      }
      directionsList.listSource = al;
    }
    showForm (directionsList);
  }
  
  public static void showMap ()
  {
    int index = directionsList.selectedIndex;
    byte [] imgarray = mpclient.getMap(index, 160, 160);
    drivingMap.imageSource = 
      new Bitmap (new MemoryStream(imgarray));
    showForm (drivingMap);
  }

  public static void exit ()
  {
    from.Dispose ();
    to.Dispose ();
    directionsList.Dispose ();
    drivingMap.Dispose ();

    Application.Exit ();
  }
  
  // ... ...
}

Summary

The web-services-driven smart client is not only a powerful application paradigm for mobile solutions, but also a future convergence point of today's desktop and web applications. The .NET framework and .NET Compact Framework provide excellent support for this paradigm. In this article, we only scratched the surface by covering the simplest types of ASP.NET web methods. The .NET Compact Framework can be used to handle complex web-service protocols. An excellent article about using the .NET Compact Framework for WebService Enhancements (WSE) can be found here.

In this article, we introduced the web services facade -- a key component in many such systems. We also discussed web service integration issues that are specific to the current versions of the .NET Compact Framework. Near the end, we covered effective UI designs for different devices. Now, it's your turn to make the most out of that PocketPC or Smartphone device you got last Christmas!

Michael Juntao Yuan specializes in lightweight enterprise / web application, and end-to-end mobile application development.


Return to ONDotnet.com