(3)
Fruite-machine strictly speaking, it is just a game with high and low scores. It is not a real online game, but it also implements some simple functions of online games.
Although fruite-machine uses the HTTP protocol, it does not round-robin the server. Instead, it sends a packet to the server through callback and then receives another packet for processing. In this way, problems may occur in real online games, because in real online games, servers may send messages to a player. In fruite-machine, the server cannot actively send messages to players. It only calls back the response function when the user sends messages to the server, this is a one-Answer message transmission method.
Strictly speaking, in a real online game, the HTTP protocol can only be used in the round-robin server mode to solve the problem that the server actively sends packets to a client. Is the so-called heartbeat packet.
Next let's look at the program that implements the callback function:
Import java. Io .*;
Import java. util .*;
Import javax. microedition. Io .*;
/**
* This class accepts and queues POST requests for a participant URL, and
* Services them in first-in-first-out order. Using the queue allows it
* To be thread-safe without forcing its clients ever to block.
*/
Public class httpposter
Implements runnable
{
Private string URL;
Private volatile Boolean aborting = false;
Private vector requestqueue = new vector ();
Private vector listenerqueue = new vector ();
Public httpposter (string URL)
{
This. url = URL;
Thread thread = new thread (this );
Thread. Start ();
}
Public synchronized void sendrequest (string request,
Httpposterlistener listener)
Throws ioexception
{
Requestqueue. addelement (request );
Listenerqueue. addelement (listener );
Running y (); // wake up sending thread
}
Public void run ()
{
Running:
While (! Aborting)
{
String request;
Httpposterlistener listener;
Synchronized (this)
{
While (requestqueue. Size () = 0)
{
Try
{
Wait (); // releases lock
}
Catch (interruptedexception E)
{
}
If (aborting)
Break running;
}
Request = (string) (requestqueue. elementat (0 ));
Listener = (httpposterlistener) (listenerqueue. elementat (0 ));
Requestqueue. removeelementat (0 );
Listenerqueue. removeelementat (0 );
}
// Sendrequest must have notified us
Dosend (request, listener );
}
}
Private void dosend (string request,
Httpposterlistener listener)
{
Httpconnection conn = NULL;
Inputstream in = NULL;
Outputstream out = NULL;
String responsestr = NULL;
String errorstr = NULL;
Boolean waserror = false;
Try
{
Conn = (httpconnection) connector. Open (URL );
// Set the Request Method and headers
Conn. setrequestmethod (httpconnection. post );
Conn. setrequestproperty ("Content-Length", integer. tostring (request. Length ()));
// Getting the output stream may flush the headers
Out = conn. openoutputstream ();
Int requestlength = request. Length ();
For (INT I = 0; I <requestlength; ++ I)
{
Out. Write (request. charat (I ));
}
// Opening the inputstream will open the connection
// And read the HTTP headers. They are stored
// Requested.
In = conn. openinputstream ();
// Get the length and process the data
Stringbuffer responsebuf;
Long length = conn. getlength ();
If (length> 0)
{
Responsebuf = new stringbuffer (INT) length );
}
Else
{
Responsebuf = new stringbuffer (); // default Length
}
Int ch;
While (CH = in. Read ())! =-1)
{
Responsebuf. append (char) CH );
}
Responsestr = responsebuf. tostring ();
// Support URL rewriting for session handling
String rewrittenurl = conn. getheaderfield ("X-rewrittenurl ");
If (rewrittenurl! = NULL)
{
Url = rewrittenurl; // use this new one in future
}
}
Catch (ioexception E)
{
Waserror = true;
Errorstr = E. getmessage ();
}
Catch (securityexception E)
{
Waserror = true;
Errorstr = E. getmessage ();
}
Finally
{
If (in! = NULL)
{
Try
{
In. Close ();
}
Catch (ioexception E)
{
}
}
If (OUT! = NULL)
{
Try
{
Out. Close ();
}
Catch (ioexception E)
{
}
}
If (Conn! = NULL)
{
Try
{
Conn. Close ();
}
Catch (ioexception E)
Listener. receivehttpresponse (responsestr );
{
}
}
}
If (waserror)
{
Listener. handlehttperror (errorstr );
}
Else
{
Listener. receivehttpresponse (responsestr );
}
}
// This is just for tidying up-the instance is useless after it has
// Been called
Public void abort ()
{
Aborting = true;
Synchronized (this)
{
Running y (); // wake up our posting thread and kill it
}
}
}
From the httpposter class, we can see that the httpposter class uses a separate thread. As long as the sendrequest (string request, httpposterlistener listener) method of the httpposter class is called, the thread will run, call the dosend (string request, httpposterlistener listener) method to send the request to the server.
Note listener. receivehttpresponse (responsestr); this program calls back the receivehttpresponse (string response) method of httpposterlistener. polymorphism is also used here. listener calls the receivehttpresponse (string reponse) method to process the packets returned by the server.