Вывод сокета Java задержал первое сообщение - PullRequest
1 голос
/ 22 мая 2011

У меня очень странная проблема с сокетами в Java. Это может быть вызвано отсутствием у меня знаний о сокетах, но вот оно:

Я использую сокет для подключения к IRC-серверу. Соединение установлено идеально, и я получаю все сообщения, которые мне отправляет IRC-сервер. Когда соединение установлено, я аутентифицируюсь на сервере и запускаю отдельный поток, чтобы получить то, что сервер отправляет мне. В этой теме я отправляю сообщение один раз, когда подключаюсь, чтобы программа присоединилась к определенному каналу.

boolean joined = false;
        while ((line = getInput().readLine()) != null) {
            if (!joined) {
                getOutput().println("JOIN #PrinZ");
                getOutput().println("JOIN #Trinorae");

                if (line.contains("JOIN :#prinz")) {
                    joined = true;
                    System.out.println("JOINED #prinz = true");
                }
            }

В конце этого метода я вызываю getOutput (). Flush ();

Теперь, когда я пытаюсь отправить сообщение на IRC-сервер через клиент, которого я пишу, кажется, что прошло много времени, прежде чем первое сообщение прошло. Когда это наконец проходит, кажется, все работает нормально. Все последующие сообщения обрабатываются немедленно. Это просто первое сообщение, которое я отправляю после подключения и подключения к этому каналу, что занимает много времени.

Метод отправки сообщения на сервер очень прост:

public void sendToServer(String input) {
        getOutput().println(input);
        getOutput().flush();
    }

Есть ли кто-нибудь, кто знает, почему первое сообщение занимает так много времени для передачи на сервер, а все последующие (после того, как первое, наконец, пришло) идет хорошо?

Если, возможно, стоит упомянуть: я использую Tomcat6 для своих сервлетов, к которым я подключаюсь, и UnrealIRCd в качестве IRC-сервера. Сообщения отправляются сервлету через AJAX. (Но отправка на сервер, кажется, идет хорошо, так как System.out, которую я делаю, когда сообщение отправляется, сразу же печатается в моем Tomcat-журнале, поэтому задержка в сокете ИЛИ на IRC-сервере. )

Если потребуется дополнительная информация, я постараюсь предоставить ее, поскольку это может выглядеть довольно сложно, как это ..

1 Ответ

0 голосов
/ 24 мая 2011

Ваш код, по-видимому, отправляет команды JOIN каждый раз, когда он проходит цикл while, который представляется один раз для каждой строки, отправляемой сервером, пока вы, наконец, не получите ответ от сервера, подтверждающий, что вы присоединились канал.

Это означает, что вы в конечном итоге будете отправлять эти JOIN команды очень много раз. IRCD предназначены для обработки только заданной скорости команд в секунду от каждого клиента - так что это, вероятно, то, что вас отстает (ваши более поздние команды заканчиваются в конце очень длинной очереди, заполненной большим количеством команд JOIN).

Вместо этого вы должны отправлять команды JOIN только один раз, устанавливая флаг сразу после их отправки:

boolean sent_join = false;
boolean joined = false;

while ((line = getInput().readLine()) != null) {
    if (!sent_join) {
        getOutput().println("JOIN #PrinZ");
        getOutput().println("JOIN #Trinorae");
        sent_join = true;
    }

    if (line.contains("JOIN :#prinz")) {
        System.out.println("JOINED #prinz = true");
        joined = true;
    }
}

Обратите внимание, что вы не можете отправлять команды JOIN до тех пор, пока вы не зарегистрируетесь, что обозначено цифрой 001, поэтому вам может потребоваться дождаться этой строки, прежде чем отправлять их.

Обратите внимание, что line.contains не очень надежный способ анализа сообщений IRC. Если я отправлю вам сообщение, содержащее «JOIN: #prinz», оно тоже сработает. Вы должны разбивать каждое входящее сообщение на источник, команду, пункт назначения и аргументы.

...