@Override
    public void run() {
        DataInputStream in = null;

        try {
            socket.setSoTimeout(1000);
        } catch (SocketException e) {
        }

        while (areAlive()) {
            if (panic) {
                messageHandler.handlePanic(new Message(Message.Type.Panic, "", node.getListenPort(), -1, socket.getLocalAddress().getHostAddress()));
            }

            if (System.currentTimeMillis() - lastSend > 1050) {
                lastSend = System.currentTimeMillis();
                messageHandler.sendHeartBeat();
            }
            if (System.currentTimeMillis() - lastReply > 5050) {
                dontKeepAlive();
                attemptToPanic();
            }

            try {
                in = new DataInputStream(socket.getInputStream());

                byte[] buffer = new byte[socket.getReceiveBufferSize()];
                int size = in.read(buffer);

                if (size == -1) {
                    in.close();
                    attemptToPanic();
                    return;
                }

                lastReply = System.currentTimeMillis();
                messageHandler.handleMessage(Message.Deserialize(buffer));

            } catch (SocketTimeoutException e) {
                //System.out.println("Socket timeout");
            } catch (IOException e) {
                if (areAlive()) {
                    attemptToPanic();
                }
                break;
            }
        }

        System.out.println("ConnectionHandler closing");
    }