Написание асинхронного (или асинхронного) кода клиентского сокета на Java - PullRequest
1 голос
/ 01 октября 2010

Я пишу сокет-клиент для взаимодействия с сетевым сервисом.В настоящее время, потому что я хочу поддерживать асинхронное чтение и запись, я работаю как с потоком вывода, так и с потоком ввода одного сокета, но мне было интересно, есть ли лучший способ сделать это.Я взглянул на Java NIO и был не очень впечатлен, а также посмотрел на Мину, но мне было интересно, есть ли у кого-нибудь лучшие идеи.

Спасибо.

Ответы [ 2 ]

1 голос
/ 06 июля 2011

Техника, которую я использовал для асинхронной связи, заключалась в использовании ExecutorService. В моем примере ниже, служба будет выполнять FutureTask, которая будет ждать следующей строки. Тем временем сервер может продолжать выполнять другие задачи и периодически опрашивать читателя, чтобы узнать, был ли получен результат.

Для написания вы можете реализовать аналогичный FutureTask.

Примечание. Вам не нужно расширять функциональность существующего Stream / Reader / Writer, как я. Это был просто исходный код, который мне пригодился

 public class SocketStringReader extends BufferedReader {
    /**
     * Internal buffer used for asynchronous reads
     */
    private HashMap<String, String> buf = null;
    /**
     * Waiting status used for asynchronous reads
     */
    private boolean waiting = false;
    /**
     * Shared ExecutorService for asynchronous reads
     */
    private static ExecutorService executor = Executors.newCachedThreadPool();

    /**
     * Constructor here to pacify Java
     * @param in The InputStream to be used as the underlying stream
     */
    public SocketStringReader(InputStream in) {
        super(new InputStreamReader(in));
    }

    @Override
    public HashMap<String, String> readHashMap() throws IOException,
    ClassNotFoundException {
        if (buf != null) {
            HashMap<String, String> resp = new HashMap<String, String>(buf);
            buf = null;
            return resp;
        }
        return stringToHashMap(this.readLine());
    }

    /**
     * Parses a string and converts it to a HashMap
     * @param map A String object of the format "{key=value, key=value, ...}" 
     * that is parsed into a HashMap
     * @return The parsed HashMap
     */
    public static HashMap<String, String> stringToHashMap(String map) {
        // take the string apart
        String[] split = map.split("[={},]");
        HashMap<String, String> result = new HashMap<String, String>();
        for (int i = 1; i < split.length; i += 2) {
            result.put(split[i].trim(), split[i + 1].trim());
        }
        logger.debug("new incoming HashMap: " + result.toString());
        return result;
    }

    /**
     * Returns the availability of the input stream
     * @return The number HashMap objects in the internal buffer
     */
    public int getAvailable() throws IOException {
        return (buf == null) ? 0 : 1;
    }

    @Override
    public HashMap<String, String> readHashMapAsync() throws IOException,
            ClassNotFoundException {
        //Check internal buffer
        if (buf != null) {
            HashMap<String, String> temp = new HashMap<String, String>(buf);
            buf = null;
            return temp;
        } else {
            //Do future crap? or nothing perhaps...
            if (!waiting) {
                waiting = true;
                FutureTask<HashMap<String, String>> future = new FutureTask<HashMap<String, String>>(
                        new Callable<HashMap<String, String>>() {
                            @Override
                            public HashMap<String, String> call() throws Exception {
                                buf = stringToHashMap(readLine());
                                logger.debug("Read object with sessionid: " + buf.get("sessionid"));
                                waiting = false;
                                return null;
                            }
                        });
                executor.execute(future);
            }
        }
        return null;
    }
}
0 голосов
/ 02 октября 2010

Помимо Mina и NIO, есть несколько других библиотек (все обычно построены на NIO)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...