gjset.server.PlayerClientHandler.java Source code

Java tutorial

Introduction

Here is the source code for gjset.server.PlayerClientHandler.java

Source

package gjset.server;

import gjset.data.PlayerData;
import gjset.server.gui.ServerConsole;
import gjset.tools.MessageUtils;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.Socket;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentFactory;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/* 
 *  LEGAL STUFF
 * 
 *  This file is part of Combo Cards.
 *  
 *  Combo Cards is Copyright 2008-2010 Artless Entertainment
 *  
 *  Set is a registered trademark of Set Enterprises. 
 *  
 *  This project is in no way affiliated with Set Enterprises, 
 *  but the authors of Combo Cards are very grateful for
 *  them creating such an excellent card game.
 *  
 *  Combo Cards is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *   
 *  Combo Cards is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details
 *   
 *  You should have received a copy of the GNU General Public License
 *  along with Combo Cards.  If not, see <http://www.gnu.org/licenses/>.
 */

public class PlayerClientHandler {
    private GameServer server;
    private ServerConsole console;

    private Socket socket;
    private XMLWriter writer;
    private BufferedReader reader;

    private Thread listeningThread;

    private DocumentFactory documentFactory;
    private PlayerData player;

    public PlayerClientHandler(Socket socket, GameServer server, ServerConsole console) {
        this.socket = socket;
        this.server = server;
        this.console = console;

        console.message("Creating client handler");

        documentFactory = DocumentFactory.getInstance();

        //Get our I/O streams.
        try {
            createIOStreams();
        } catch (IOException e) {
            console.errorMessage("Could not obtain I/O streams for client socket.");
            e.printStackTrace();
        }
    }

    /**
     * 
     * Executes the listening thread.
     *
     */
    public void startListening() {
        console.message("Starting to listen to client");

        // Start listening.
        listeningThread.start();

        // Now that we're listening, initialize the other end.
        sendInitializationMessage();
    }

    /**
     * Return the id for this player.
     *
     * @return
     */
    public int getPlayerId() {
        if (player != null) {
            return player.getId();
        } else {
            return 0;
        }
    }

    /**
     * Set the player to associate with this client.
     *
     * @param player
     */
    public void setPlayer(PlayerData player) {
        this.player = player;
    }

    /**
     * This command sends the indicated XML to the server, appending the appropriate information.
     *
     * @param messageElement
     * @see gjset.client.ClientCommunicator#sendMessage(org.dom4j.tree.DefaultElement)
     */
    public void sendMessage(Element messageElement) {
        Element fullXMLElement = MessageUtils.wrapMessage(messageElement);
        try {
            writer.write(fullXMLElement);
            writer.write("\n");
            writer.flush();
        } catch (IOException e) {
            System.err.println("Failed to send message");
            e.printStackTrace();
        }
    }

    /**
     * 
     * Handle receiving the message.
     *
     * @param message
     */
    public void receiveMessage(Element message) {
        server.receiveMessage(this, message);
    }

    /**
     * Shut down this client handler.
     *
     */
    public void destroy() {
        try {
            server.removeClient(this);
            socket.close();
            listeningThread.interrupt();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * Send a message to the client indicating our protocol version.
     *
     */
    private void sendInitializationMessage() {
        console.message("Initializing client");

        Element message = documentFactory.createElement("init");

        sendMessage(message);
    }

    //Used to create the Input/Output stream handling tools for a newly created socket.
    private void createIOStreams() throws IOException {
        try {
            writer = new XMLWriter(socket.getOutputStream());
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        final SAXReader XMLreader = new SAXReader();

        Runnable listenForMessage = new Runnable() {
            public void run() {
                try {
                    String textReceived = reader.readLine();
                    while (socket.isConnected() && textReceived != null) {
                        // Create an input stream to allow the XML parser to read from the string.
                        InputStream stringInput = new ByteArrayInputStream(textReceived.getBytes());
                        Document document = XMLreader.read(stringInput);

                        // Now receive the message.
                        receiveMessage(document.getRootElement());

                        // Then go looking for the next message.
                        textReceived = reader.readLine();
                    }

                    destroy();
                } catch (IOException e) {
                    System.err.println(
                            "IO Exception reading input in client handler. (Possibly because of closed socket.)");
                    //e.printStackTrace();
                } catch (DocumentException e) {
                    System.err.println("Document Exception parsing text in client handler.");
                    //e.printStackTrace();
                }
            }
        };

        listeningThread = new Thread(listenForMessage, "Client Handler Thread");
    }

}