Package pong.client.model

Source Code of pong.client.model.ClientProtocolThread

package pong.client.model;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;

import pong.common.Debugger;
import pong.common.Message;
import pong.common.Position;

/**
* This class manages the client protocol to communicate with the Pong server.
*
* @author Lorenzo Gatto
*
*/
public class ClientProtocolThread extends Thread {

  private Socket socket;
  private ObjectOutputStream output;
  private ObjectInputStream input;
  private final EventsHandler eventsHandler;
  private final String hostName;
  private final int port;

  /**
   * Class constructor.
   *
   * @param eventsHander
   *            the handler of network events
   * @param host
   *            the server host name
   * @param port
   *            the port number of the server
   */
  public ClientProtocolThread(final EventsHandler eventsHander, final String host, final int port) {
    super();
    this.eventsHandler = eventsHander;
    this.hostName = host;
    this.port = port;
  }

  /**
   * This method connects to the server and waits for messages continuosly, sending player
   * movement information after receiving object positions.
   */
  public synchronized void run() {
    try {
      this.socket = new Socket(hostName, port);
      this.socket.setTcpNoDelay(true);
    } catch (IOException | IllegalArgumentException | NullPointerException e) {
      this.eventsHandler.connectionFailedEvent();
      return;
    }
    assert this.socket != null;
    try {
      OutputStream o;
      InputStream i;
      o = this.socket.getOutputStream();
      i = this.socket.getInputStream();
      this.output = new ObjectOutputStream(o);
      this.input = new ObjectInputStream(i);
    } catch (IOException e) {
      if (!this.isInterrupted()) {
        onServerDisconnect();
      }
      return;
    }
    this.eventsHandler.connectionSuccessfullEvent();
    while (!this.isInterrupted()) {
      getMessage();
    }
  }

  /**
   * Disconnects the client from the server.
   */
  public void disconnect() {
    interrupt();
    try {
      this.socket.close();
    } catch (IOException e) {
      return;
    }
  }

  /**
   * This method gets a message from the server and performs an appropriate action
   */
  private void getMessage() {
    Message message = null;
    try {
      message = (Message) input.readObject();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
      System.exit(1);
    } catch (IOException e) {
      Debugger.printLine("Error receiving message");
      if (!this.isInterrupted()) {
        onServerDisconnect();
      }
      return;
    }

    Debugger.printLine(message.getMessageType().name() + " message received" + " time "
        + System.currentTimeMillis());
    if (message.getMessageType() == Message.Type.POSITIONS) {
      this.eventsHandler.objectPositionsReceivedEvent((Position[]) message.getContent());
      sendMovementInformation();
    } else if (message.getMessageType() == Message.Type.MATCH_BEGINS) {
      final Integer roundsNumber = (Integer) message.getContent();
      this.eventsHandler.matchBeginsEvent(roundsNumber);
    } else if (message.getMessageType() == Message.Type.ROUND_BEGINS) {
      this.eventsHandler.roundBeginsEvent();
    } else if (message.getMessageType() == Message.Type.ROUND_END) {
      final Boolean won = (Boolean) message.getContent();
      this.eventsHandler.roundEndEvent(won);
    } else if (message.getMessageType() == Message.Type.OTHER_DISCONNECTED) {
      this.eventsHandler.otherDisconnectedWhilePlayingEvent();
    } else if (message.getMessageType() == Message.Type.YOUR_PLAYER_INDEX) {
      final Integer playerIndex = (Integer) message.getContent();
      this.eventsHandler.playerIndexReceivedEvent(playerIndex);
    }
    assert message.getMessageType() == Message.Type.ARE_YOU_ALIVE;
  }

  /**
   * This method sends information about player movement
   */
  private void sendMovementInformation() {
    final Message message = new Message(Message.Type.MOVEMENT,
        this.eventsHandler.movementInformationRequestedEvent());
    try {
      this.output.writeObject(message);
      this.output.reset();
    } catch (IOException e) {
      if (!this.isInterrupted()) {
        onServerDisconnect();
      }
      Debugger.printLine("Error sending message");
    }
  }

  /**
   * This method tells the model that the server disconnected, interrupting the current thread
   */
  private void onServerDisconnect() {
    this.eventsHandler.serverDisconnectedEvent();
    interrupt();
  }

}
TOP

Related Classes of pong.client.model.ClientProtocolThread

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.