Search in sources :

Example 1 with AutoFlushObjectOutputStream

use of com.laytonsmith.PureUtilities.Common.AutoFlushObjectOutputStream in project CommandHelper by EngineHub.

the class PNViewer method startServer.

public static void startServer(int port, final String password) throws IOException {
    ServerSocket socket = new ServerSocket(port);
    log("Server started on port " + port + ". Type Ctrl+C to kill the server.");
    log("Process info: " + ManagementFactory.getRuntimeMXBean().getName());
    log("Server version: " + PROTOCOL_VERSION);
    connection: while (true) {
        log("Persistence Network Viewers may now connect to this server.");
        final Socket s = socket.accept();
        log("A client has connected from " + s.getInetAddress().toString());
        new Thread(new Runnable() {

            @Override
            public void run() {
                Thread waitThread = null;
                try {
                    final AtomicBoolean dataReceieved = new AtomicBoolean(false);
                    final AtomicBoolean longTimeout = new AtomicBoolean(false);
                    waitThread = new Thread(new Runnable() {

                        @Override
                        public void run() {
                            try {
                                while (true) {
                                    synchronized (dataReceieved) {
                                        dataReceieved.wait(longTimeout.get() ? 10 * 60 * 1000 : 10 * 1000);
                                    }
                                    if (dataReceieved.get() == false) {
                                        log("No response from client in too long, forcibly closing connection.");
                                        try {
                                            s.close();
                                        } catch (IOException ex) {
                                        // 
                                        }
                                        break;
                                    }
                                    dataReceieved.set(false);
                                }
                            } catch (InterruptedException ex) {
                            // 
                            }
                        }
                    });
                    waitThread.start();
                    ObjectInputStream is = new ObjectInputStream(s.getInputStream());
                    ObjectOutputStream os = new AutoFlushObjectOutputStream(s.getOutputStream());
                    int protocolVersion = is.readInt();
                    if (protocolVersion != PROTOCOL_VERSION) {
                        log("Client version unsupported: " + protocolVersion);
                        os.writeUTF("VERSION-MISMATCH");
                        return;
                    } else {
                        log("Client version supported: " + protocolVersion);
                        os.writeUTF("VERSION-OK");
                    }
                    String clientPassword = is.readUTF();
                    if (!password.equals(clientPassword)) {
                        log("Client supplied the wrong password, disconnecting.");
                        os.writeUTF("PASSWORD-BAD");
                        os.writeUTF("DISCONNECT");
                        return;
                    } else {
                        if (!"".equals(password)) {
                            log("Client supplied the correct password");
                        }
                        os.writeUTF("PASSWORD-OK");
                    }
                    // They have now authed correctly, so we can up the idle time.
                    longTimeout.set(true);
                    // Now we need to create instance variables for the remainder of
                    // the connection, that is, the meat of the connection.
                    String remoteFile = null;
                    PersistenceNetwork pn = null;
                    connected: while (s.isConnected()) {
                        String command = is.readUTF();
                        log("Command received from client: " + command);
                        dataReceieved.set(true);
                        synchronized (dataReceieved) {
                            dataReceieved.notifyAll();
                        }
                        switch(command) {
                            case "DISCONNECT":
                                // Write the disconnect out to the client as well, so
                                // the client will gracefully disconnect.
                                os.writeUTF("DISCONNECT");
                                break connected;
                            case "SET-REMOTE-FILE":
                                remoteFile = is.readUTF();
                                log("File set to " + remoteFile);
                                if (new File(remoteFile).exists()) {
                                    log("File accepted.");
                                    os.writeUTF("FILE-OK");
                                } else {
                                    log("File not accepted.");
                                    os.writeUTF("FILE-BAD");
                                    os.writeUTF("DISCONNECT");
                                }
                                break;
                            case "LOAD-DATA":
                                os.writeUTF("LOAD-DATA");
                                try {
                                    // Load the data from the PN, and send it on
                                    pn = getPersistenceNetwork(remoteFile);
                                    Map<String[], String> data = pn.getNamespace(ArrayUtils.EMPTY_STRING_ARRAY);
                                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                                    ObjectOutputStream oos = new ObjectOutputStream(baos);
                                    oos.writeObject(data);
                                    oos.flush();
                                    byte[] output = baos.toByteArray();
                                    os.writeInt(output.length);
                                    os.write(output);
                                } catch (URISyntaxException | DataSourceException ex) {
                                    os.writeUTF("LOAD-ERROR");
                                    os.writeUTF(ex.getMessage());
                                    log("Load error!");
                                    log(ex);
                                }
                                break;
                            case "KEY-SOURCE":
                                os.writeUTF("KEY-SOURCE");
                                String key = is.readUTF();
                                if (pn == null) {
                                    log("pn is null, can't get key source");
                                    os.writeUTF("DISCONNECT");
                                } else {
                                    log("Requested source for key: " + key);
                                    URI uri = pn.getKeySource(key.split("\\."));
                                    log("Responding with: " + uri);
                                    os.writeObject(uri);
                                }
                                break;
                            default:
                                // Bad command, disconnect them.
                                os.writeUTF("DISCONNECT");
                                break connected;
                        }
                    }
                } catch (IOException ex) {
                // Disconnected
                } finally {
                    try {
                        s.close();
                    } catch (IOException ex) {
                    // 
                    }
                    log("Client has disconnected.");
                    if (waitThread != null) {
                        waitThread.interrupt();
                    }
                }
            }
        }).start();
    }
}
Also used : AutoFlushObjectOutputStream(com.laytonsmith.PureUtilities.Common.AutoFlushObjectOutputStream) ServerSocket(java.net.ServerSocket) IOException(java.io.IOException) PersistenceNetwork(com.laytonsmith.persistence.PersistenceNetwork) ByteArrayOutputStream(java.io.ByteArrayOutputStream) URISyntaxException(java.net.URISyntaxException) AutoFlushObjectOutputStream(com.laytonsmith.PureUtilities.Common.AutoFlushObjectOutputStream) ObjectOutputStream(java.io.ObjectOutputStream) URI(java.net.URI) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) DataSourceException(com.laytonsmith.persistence.DataSourceException) File(java.io.File) ServerSocket(java.net.ServerSocket) Socket(java.net.Socket) ObjectInputStream(java.io.ObjectInputStream)

Example 2 with AutoFlushObjectOutputStream

use of com.laytonsmith.PureUtilities.Common.AutoFlushObjectOutputStream in project CommandHelper by EngineHub.

the class PNViewer method loadFromRemote.

private void loadFromRemote(final String host, final int port, final String password, final String remoteFile) {
    remoteSocketThread = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                try (Socket s = new Socket()) {
                    s.connect(new InetSocketAddress(host, port), 30000);
                    remoteSocket = s;
                    setStatus("Connected to remote server", true);
                    setProgress(null);
                    try {
                        final ObjectOutputStream os = new AutoFlushObjectOutputStream(s.getOutputStream());
                        final ObjectInputStream is = new ObjectInputStream(s.getInputStream());
                        remoteOutput = os;
                        remoteInput = is;
                        // Set up our initial data
                        log("Writing client version: " + PROTOCOL_VERSION);
                        os.writeInt(PROTOCOL_VERSION);
                        switch(is.readUTF()) {
                            case "VERSION-OK":
                                break;
                            default:
                                showError("The server does not support this client's version.");
                                return;
                        }
                        os.writeUTF(password);
                        switch(is.readUTF()) {
                            case "PASSWORD-OK":
                                log("Password accepted by server.");
                                break;
                            default:
                                showError("Server rejected our password. Check the password and try again.");
                                return;
                        }
                        os.writeUTF("SET-REMOTE-FILE");
                        os.writeUTF(remoteFile);
                        final MutableObject<Map<String[], String>> data = new MutableObject<>();
                        final MutableObject<URI> sourceURI = new MutableObject<>();
                        VirtualPersistenceNetwork vpn = null;
                        connection: while (!Thread.currentThread().isInterrupted() && s.isConnected()) {
                            String serverCommand = is.readUTF();
                            switch(serverCommand) {
                                case "DISCONNECT":
                                    break connection;
                                case "FILE-OK":
                                    os.writeUTF("LOAD-DATA");
                                    reloadButton.setEnabled(false);
                                    break;
                                case "FILE-BAD":
                                    showError("Remote file doesn't exist, disconnecting.");
                                    break;
                                case "LOAD-DATA":
                                    int size = is.readInt();
                                    setStatus("Downloading data from server...", true);
                                    setProgress(0);
                                    byte[] bdata = new byte[size];
                                    for (int i = 0; i < size; i++) {
                                        bdata[i] = is.readByte();
                                        setProgress((int) ((((double) i) / ((double) size)) * 100));
                                    }
                                    setStatus("Processing data from server", true);
                                    setProgress(null);
                                    ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bdata));
                                    try {
                                        Map<String[], String> d = (Map<String[], String>) ois.readObject();
                                        data.setObject(d);
                                        vpn = new VirtualPersistenceNetwork() {

                                            Map<String, URI> sources = new HashMap<>();

                                            @Override
                                            public Map<String[], String> getAllData() throws DataSourceException {
                                                return data.getObject();
                                            }

                                            @Override
                                            public URI getKeySource(String[] key) {
                                                String kk = join(key);
                                                if (!sources.containsKey(kk)) {
                                                    try {
                                                        sourceURI.setObject(null);
                                                        os.writeUTF("KEY-SOURCE");
                                                        os.writeUTF(kk);
                                                        synchronized (sourceURI) {
                                                            if (sourceURI.getObject() == null) {
                                                                try {
                                                                    sourceURI.wait();
                                                                } catch (InterruptedException ex) {
                                                                // 
                                                                }
                                                            }
                                                        }
                                                        URI uri = sourceURI.getObject();
                                                        sources.put(kk, uri);
                                                    } catch (IOException ex) {
                                                        showError(ex.getMessage());
                                                        log(ex);
                                                    }
                                                }
                                                return sources.get(kk);
                                            }
                                        };
                                        try {
                                            displayData(vpn);
                                            setStatus("Done.", false);
                                        } catch (DataSourceException ex) {
                                            log(ex);
                                            showError(ex.getMessage());
                                        }
                                    } catch (ClassNotFoundException ex) {
                                        log(ex);
                                        showError(ex.getMessage());
                                    }
                                    reloadButton.setEnabled(true);
                                    break;
                                case "KEY-SOURCE":
                                    try {
                                        URI uri = (URI) is.readObject();
                                        sourceURI.setObject(uri);
                                        synchronized (sourceURI) {
                                            sourceURI.notifyAll();
                                        }
                                    } catch (ClassNotFoundException ex) {
                                        log(ex);
                                    }
                                    break;
                                case "LOAD-ERROR":
                                    String message = is.readUTF();
                                    setStatus(message, false);
                                    showError(message);
                                    reloadButton.setEnabled(true);
                                    break;
                                default:
                                    showError("Server sent unrecognized command, disconnecting.");
                                    log("Unrecognized command: " + serverCommand);
                                    break connection;
                            }
                        }
                        log("Closing connection.");
                    } catch (EOFException ex) {
                        log(ex);
                        showError("The server closed the connection unexpectedly.");
                    }
                } catch (SocketTimeoutException ex) {
                    showError("Connection timed out, check your settings and try again.");
                } finally {
                    setStatus("Connection to remote server closed.", false);
                    remoteOutput = null;
                    remoteInput = null;
                    reloadButton.setEnabled(true);
                }
            } catch (IOException ex) {
                showError(ex.getMessage());
                Logger.getLogger(PNViewer.class.getName()).log(Level.SEVERE, null, ex);
            }
            remoteSocketThread = null;
        }
    });
    remoteSocketThread.start();
}
Also used : InetSocketAddress(java.net.InetSocketAddress) AutoFlushObjectOutputStream(com.laytonsmith.PureUtilities.Common.AutoFlushObjectOutputStream) IOException(java.io.IOException) AutoFlushObjectOutputStream(com.laytonsmith.PureUtilities.Common.AutoFlushObjectOutputStream) ObjectOutputStream(java.io.ObjectOutputStream) URI(java.net.URI) SocketTimeoutException(java.net.SocketTimeoutException) DataSourceException(com.laytonsmith.persistence.DataSourceException) ByteArrayInputStream(java.io.ByteArrayInputStream) EOFException(java.io.EOFException) Map(java.util.Map) HashMap(java.util.HashMap) ServerSocket(java.net.ServerSocket) Socket(java.net.Socket) ObjectInputStream(java.io.ObjectInputStream) MutableObject(com.laytonsmith.PureUtilities.Common.MutableObject)

Aggregations

AutoFlushObjectOutputStream (com.laytonsmith.PureUtilities.Common.AutoFlushObjectOutputStream)2 DataSourceException (com.laytonsmith.persistence.DataSourceException)2 IOException (java.io.IOException)2 ObjectInputStream (java.io.ObjectInputStream)2 ObjectOutputStream (java.io.ObjectOutputStream)2 ServerSocket (java.net.ServerSocket)2 Socket (java.net.Socket)2 URI (java.net.URI)2 MutableObject (com.laytonsmith.PureUtilities.Common.MutableObject)1 PersistenceNetwork (com.laytonsmith.persistence.PersistenceNetwork)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 EOFException (java.io.EOFException)1 File (java.io.File)1 InetSocketAddress (java.net.InetSocketAddress)1 SocketTimeoutException (java.net.SocketTimeoutException)1 URISyntaxException (java.net.URISyntaxException)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1