
By Bill Swaney | Article Rating: |
|
May 1, 2002 12:00 AM EDT | Reads: |
29,434 |
In Part 1 of this article (JDJ, Vol. 7, issue 3) I introduced the idea of using the surrogate architecture within Jini as a platform for J2ME games. I also showed how to start Madison, Sun's reference implementation, and how to connect to it with the provided device simulator.
This article continues the surrogate architecture tour and introduces a method through which a J2ME device can use it.
To briefly recap, the architecture allows any device, in our case a J2ME one, to connect to a Jini network through a surrogate object that represents the device in the network. The surrogate host provides a mechanism for the devices to register themselves and obtain a context that enables access to the underlying Jini infrastructure.
Another important reason for choosing the surrogate architecture is that it allows us to view the device as a single object from the network perspective. There's no single monolithic portal API or application running; instead, many different surrogate objects with unique capabilities and representing many potentially different devices are displayed in the Jini network.
How Should We Connect?
The surrogate architecture defines the term connector as a means by which a device will discover and register with a surrogate host. Possible connectors might include such protocols as Bluetooth, USB, or even traditional network ones. Madison comes with an IP interconnect, useful in many cases but it may not be the best one for our project. For several reasons I believe HTTP is the best protocol to use.
HTTP? It does have its disadvantages. Foremost of these - it's a request/response protocol. This means that either we settle for a one-way communication model where all communication with the device must come as a response to an initial request, or we have an HTTP server at both the device and the surrogate object. The second option is just not possible in J2ME, so we're stuck with the first.
The second disadvantage is that HTTP has no notion of "discovery," at least in the Jini sense. This means that our device must have knowledge, in the form of a URL, of where the surrogate host is beforehand. It would be nice to somehow find a surrogate host but we can hardly multicast the Internet looking for one.
The J2ME specification only requires support for HTTP connections, though implementations of J2ME may support other types of communication. By choosing HTTP we guarantee that any J2ME device will be able to work with our surrogate host connector. There have been many debates as to whether J2ME is powerful enough, as well as fears that using it results in the loss of powerful native functionality. Cross-platform code has its own set of disadvantages, but in our case the portability is worth the loss in functionality.
To see another advantage, let's think about our use case. Our goal is to create a games platform on mobile devices. Typically, this means many users connecting with our system simultaneously. It's not unrealistic to think of multiplayer games with thousands of players concurrently connected. In this case, HTTP scales quite well - after all, it's a proven technology already handling huge numbers of simultaneous requests. Thus our system should be able to handle more users making requests every few minutes or so rather than a group of users who are constantly connected over sockets. It may even be cheaper for the end user by minimizing the amount of airtime consumed.
Finally, even though I'm advocating HTTP as the protocol to communicate with the surrogate host, it doesn't have to be the protocol used to communicate with the surrogate object once it's instantiated. I'll continue to use HTTP in our project, but the surrogate architecture doesn't require this and other protocols could be used depending on the device's J2ME implementation.
Defining Our Protocol
In defining a surrogate HTTP protocol I'll rely heavily on what has already been defined for the IP connector. That specification is already in the review stage of the Jini Decision Process (see www.jini.org/standards/), and since HTTP is built on IP, there are some similarities. In addition, doing so is what I consider being a "good Jini citizen": cooperating and contributing to a community that gives a tremendous amount to its members. By building on the IP connector work, we respect the standards already defined, ensuring that Jini services in general will be able to communicate with each other and interoperate without difficulty.
As stated earlier we won't need the discovery protocols. We will, however, need a registration protocol that allows a device to register with the surrogate host. Examining the IP interconnect registration request protocol we can see that it will suit our needs as well for HTTP. The registration request protocol is sent by the device to the surrogate host and has the following format:
- int protocol version
- short length of surrogate code URL
- byte[] surrogate code URL
- int length of initialization data
- byte[] initialization data
- int length of surrogate code
- byte[] surrogate code
- int protocol version
- short length of surrogate connect URL
- byte[] surrogate connect URL
- int protocol version
- int message type
- int length of payload data
- byte[] payload data
Wait a minute, isn't this supposed to have something to do with J2ME? Well, there are still some missing pieces on the Jini side, but let's take a little break first and make use of the protocols introduced earlier.
Every game written using the HTTP interconnect will need to register with the surrogate host and receive a response. Therefore, it makes sense to encapsulate these two protocols in objects. Since our registration protocol is the same as the one for the IP interconnect, we may be able to reuse some of our code should we use J2ME over IP in the future.
The limited resources of a typical J2ME device now force us to make some design decisions. It's tempting to define an interface for our two protocols, something like the following:
public interface InterconnectProtocolThis allows us a nice layer of abstraction, and by encapsulating the protocol in an object that accepts streams for reading and writing, we can use any type of connection.
{
void read(java.io.InputStream in) throws java.io.IOException;
void write(java.io.OutputStream out) throws java.io.IOException;
}
What about those limited resources? By creating an interface we have one more file to add to our J2ME JAR. With some phones having an application limit of 50K, why add unnecessary bloat? It's a case of evaluating each situation. For now I'll keep the interface, as it allows flexibility in adding more protocols for different message formats. Be aware though that sometimes every little byte counts; I've worked on applications in which I removed all evidence of object-oriented design in order to bring the size of the code down.
A further reduction in code size can be obtained, in our case by combining the registration and response protocols into one object. The reason is simply that the J2ME device need only send registrations to the surrogate host; it doesn't need to read the registration protocol. Similarly it only has to read the responses and never needs to send them. Again this is a decision to make based on the situation. By combining the protocols here we lose the reusability of the registration protocol with an IP interconnect, as the response is only needed with the HTTP interconnect.
See Listings 1 and 2 for J2ME encapsulations of the registration and response protocols, respectively.
What Should an HTTP Surrogate Look Like?
Let's turn back to the Jini side of our project and think about what still needs to be defined, what an HTTP surrogate will look like, and how the surrogate host combined with the HTTP interconnect will interact with these surrogate objects.
In this section I'm assuming we'll continue to communicate with the surrogate object using HTTP. This means that either the surrogate must have an embedded HTTP server in its code, or the HTTP interconnect must provide that service for the surrogate object. The second case is not unreasonable as it simplifies the creation of surrogate objects, which is an important goal in a development platform. It also philosophically fits with the surrogate architecture: the host provides a context for the surrogate object and so does the interconnect.
This leads to the question of how a message is delivered from the interconnect-provided HTTP server to the surrogate. The embedded HTTP server provided by the interconnect and the surrogate object should have an exclusive relationship. At the very least, there should be some separation, and depending on the embedded server this might be an exclusive handler for HTTP requests destined for a specific surrogate object. To pass the message to the surrogate object we need to create an interface that it should implement:
public interface HttpSurrogate extends net.jini.surrogate.SurrogateAre there potential problems in defining an interface our surrogates must implement? Other HTTP interconnect implementations may have different designs and we run into a case of surrogate objects being incompatible across different surrogate hosts. However, as we are going to further define the relationship between the HTTP surrogate object and the HTTP interconnect, this seems a small issue.
{
void handle(java.io.InputStream in, java.io.OutputStream out)
throws java.io.IOException;
}
The HttpSurrogate interface extends the basic surrogate interface as defined in the surrogate architecture specification (included in the Madison download). This interface is defined as follows and allows the surrogate host to provide basic life-cycle services to the surrogate:
package net.jini.surrogate;The first object in the activate() method is the HostContext, provided by the surrogate host. The second object is the context, provided by the interconnect, and it's passed as an object; since the surrogate host calls this method on the surrogate, it doesn't need to know the nature of the context.
public interface Surrogate {
void activate(HostContext hostContext, Object context)
throws Exception;
void deactivate();
}
We'll need to define a context for the HTTP interconnect. The context defined in the IP interconnect fits our needs and keeps some consistency between the interconnects. The interface for the context is:
public interface HttpInterconnectContext extendsThis provides a way to retrieve both the initialization data we may include in the registration protocol and the InetAddress of the device. We may want the InetAddress in the future, as it will allow the surrogate to create connections back to the device should the J2ME implementation on that device support them.
net.jini.surrogate.KeepAliveManagement
{
byte[] getInitializationData();
java.net.InetAddress getAddress();
}
You'll notice that the interface extends another surrogate specification interface. This allows the interconnect to assist in defining and enforcing what it means to have a live connection between a device and a surrogate.
Tell Me What You Think
So far we've covered a lot of ground and further detailed some of the ideas introduced in Part 1. We're still not there, but we're getting closer to achieving the goal of developing a game platform for J2ME devices in a Jini network.
I'm interested in hearing your opinions. Are there pieces missing, whether technical or logistical, to this puzzle? How does the Jini/J2ME platform compare to others you've used for interactive, wireless device applications? Your thoughts and suggestions are welcome.
Published May 1, 2002 Reads 29,434
Copyright © 2002 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Bill Swaney
William Swaney, a software developer specializing in distributed computing, works for Valaran Corp., where he experiments with mobile devices and Jini networks. He divides his time between tweaking Valaran’s surrogate host implementation and kicking a soccer ball into a bucket.
![]() Nov. 11, 2018 04:00 PM EST Reads: 3,170 |
By Pat Romanski Nov. 11, 2018 11:45 AM EST Reads: 2,284 |
By Elizabeth White Nov. 10, 2018 11:45 PM EST Reads: 2,064 |
By Pat Romanski Nov. 10, 2018 10:00 PM EST Reads: 3,206 |
By Pat Romanski Nov. 10, 2018 01:00 AM EST Reads: 2,941 |
By Pat Romanski Nov. 9, 2018 04:45 PM EST Reads: 2,282 |
By Yeshim Deniz Nov. 3, 2018 05:00 AM EDT Reads: 4,027 |
By Yeshim Deniz Nov. 2, 2018 03:00 PM EDT Reads: 3,210 |
By Elizabeth White ![]() Oct. 30, 2018 03:45 PM EDT Reads: 14,062 |
By Zakia Bouachraoui Oct. 30, 2018 11:45 AM EDT |