📄 httpcommunicator.java.hide
字号:
package net.frog_parrot.checkers;import java.io.*;import javax.microedition.io.*;import javax.microedition.lcdui.*;import javax.microedition.rms.*;import net.frog_parrot.util.DataConverter;/** * This class contacts a remote server in order to * play a game of checkers against an opponent.. * * @author Carol Hamer */public class HttpCommunicator extends Thread { //-------------------------------------------------------- // static fields /** * This is the URL to contact. */ public static final String SERVER_URL = "http://malbec:8080/games/Checkers"; //-------------------------------------------------------- // game instance fields /** * The MIDlet subclass, used to set the Display * in the case where an error message needs to be sent.. */ Checkers myCheckers; /** * The Canvas subclass, used to set the Display * in the case where an error message needs to be sent.. */ CheckersCanvas myCanvas; /** * The game logic class that we send the opponent's * moves to.. */ CheckersGame myGame; /** * Whether or not the MIDlet class has requested the * game to end. */ boolean myShouldStop; //-------------------------------------------------------- // data exchange instance fields /** * The data from the local player that is to * be sent to the opponent. */ byte[] myMove; /** * Whether or not the current turn is done and * should be sent. */ boolean myTurnIsDone = true; //-------------------------------------------------------- // connection instance fields /** * A session token to find the correct checkers game on * the server for later requests. */ String myToken; /** * The connection object. */ ContentConnection myConnection; /** * The stream to write the data to. */ DataOutputStream myOutputStream; //-------------------------------------------------------- // initialization /** * Constructor is used only when the program wants * to spawn a data-fetching thread, not for merely * reading local data with static methods. */ HttpCommunicator(Checkers checkers, CheckersCanvas canvas, CheckersGame game) { myCheckers = checkers; myCanvas = canvas; myGame = game; } //-------------------------------------------------------- // connection controls (to be called by the MIDlet subclass) /** * attempt to contact the server.. */ void connect() { } /** * disconnect temporarily (in case the game has to pause). */ void disconnect() { } /** * Stop the game entirely. Notify the servlet that * the user is exiting the game. */ void endGame() { } //-------------------------------------------------------- // methods called by CheckersGame to send move // information to the opponent. /** * This is called when the player moves a piece. */ synchronized void move(byte sourceX, byte sourceY, byte destinationX, byte destinationY) { myMove = new byte[4]; myMove[0] = sourceX; myMove[1] = sourceY; myMove[2] = destinationX; myMove[3] = destinationY; myTurnIsDone = false; notify(); } /** * This is called when the local player's turn is over. */ synchronized void endTurn() { myTurnIsDone = true; notify(); } //-------------------------------------------------------- // main communication method /** * Makes a HTTP connection to the server and sends and receives * information about moves. */ public void run() { DataInputStream dis = null; // first make the connection and get a session token: try { myCanvas.setWaitScreen(true); myConnection = (ContentConnection)Connector.open(SERVER_URL); byte[] tokenChars = new byte[10]; dis = myConnection.openDataInputStream(); dis.readFully(tokenChars); myToken = new String(tokenChars); myCanvas.setWaitScreen(false); byte startX = dis.readInt(); if(startX != -1) { byte startY = dis.readInt(); byte endX = dis.readInt(); byte endY = dis.readInt(); myGame.moveOpponent(startX, startY, endX, endY); } myGame.endOpponentTurn(); } catch(Exception e) { // if this fails, it is almost undoubtedly // a communication problem (server down, etc.) // we need to give the right message to the user: Alert alert = new Alert("communication error", "?", null, AlertType.INFO); // since we set the timeout to forever, but since we // do not set a command listener this time, this method // will not be called when the user presses the // default Alert.DISMISS_COMMAND, the display // will merely be given to the Displayable // indicated below: alert.setTimeout(Alert.FOREVER); //myCanvas.setNeedsRepaint(); // the second arg tells the Display to go to // myCanvas when the user dismisses the alert Display.getDisplay(myCheckers).setCurrent(alert, myCanvas); } finally { try { if(dis != null) { dis.close(); } if(myConnection != null) { myConnection.close(); } dis = null; myConnection = null; } catch(Exception e) { // if this throws, at least we made our best effort // to close everything up.... } } // begin main game loop: while(true) { try { synchronized(this) { wait(); } while(! myTurnIsDone) { if(myConnection == null) { myConnection = (ContentConnection)Connector.open(SERVER_URL); myOutputStream = myConnection.openDataOutputStream(); myOutputStream.writeChars(myToken); } // send the current move: if(myMove != null) { for(byte i = 0; i < myMove.length; i++) { myOutputStream.writeInt(myMove[i]); } myMove = null; } synchronized(this) { wait(); } } myOutputStream.writeInt(-1); myOutputStream.close(); myOutputStream.flush(); // now that we've sent the move, we wait for a response dis = myConnection.openDataInputStream(); byte[] opponentMove = new byte[4]; byte index = 0; byte readInt = dis.readInt(); while(readInt != -1) { opponentMove[index] = readInt; index++; if(index == opponentMove.length) { myGame.moveOpponent(opponentMove[0], opponentMove[1], opponentMove[2], opponentMove[3]); index = 0; } readInt = dis.readInt(); } myGame.endOpponentTurn(); } catch(Exception e) { // if this fails, it is almost undoubtedly // a communication problem (server down, etc.) // we need to give the right message to the user: Alert alert = new Alert("communication error", "?", null, AlertType.INFO); // since we set the timeout to forever, but since we // do not set a command listener this time, this method // will not be called when the user presses the // default Alert.DISMISS_COMMAND, the display // will merely be given to the Displayable // indicated below: alert.setTimeout(Alert.FOREVER); //myCanvas.setNeedsRepaint(); // the second arg tells the Display to go to // myCanvas when the user dismisses the alert Display.getDisplay(myCheckers).setCurrent(alert, myCanvas); } finally { try { if(dis != null) { dis.close(); } if(myOutputStream != null) { myOutputStream.close(); } if(myConnection != null) { myConnection.close(); } dis = null; myOutputStream = null; myConnection = null; } catch(Exception e) { // if this throws, at least we made our best effort // to close everything up.... } } } // end while loop } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -