Чат-система на Java - PullRequest
       3

Чат-система на Java

1 голос
/ 01 декабря 2011

Есть ли способ немедленно напечатать сообщение, полученное от клиента, без использования бесконечного цикла, чтобы проверить, пуст ли входной поток или нет? Потому что я обнаружил, что использование бесконечного цикла потребляет много системных ресурсов, что делает работу программы очень медленной. И мы также должны сделать то же самое (бесконечный цикл) на стороне клиента, чтобы напечатать сообщение на экране в режиме реального времени. Я использую Java.

Ответы [ 6 ]

2 голосов
/ 01 декабря 2011

Вы должны иметь дело с потоком ввода в отдельном потоке - и позволить ему блокировать в ожидании ввода.Он не будет использовать какие-либо ресурсы, пока он блокирует.Если вы наблюдаете чрезмерное использование ресурсов, когда делаете такие вещи, вы делаете это неправильно.

0 голосов
/ 01 декабря 2011

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

Объекты, записывающие в буфер, будут выполнять свою обычную запись, а затем вызовут метод notify () во входном потоке, информируя все заинтересованные объекты об изменении.

Редактировать: для этого может потребоваться создать подклассы более чем на пару классов, что может повлечь за собой множество изменений кода. Не зная больше о вашем дизайне, вы должны будете решить, стоит ли реализация усилий.

0 голосов
/ 01 декабря 2011

Если вы используете Sockets, которым вы должны быть для любой сети.

Тогда вы можете использовать сокет DataInputStream, который вы можете получить, используя socket.getInputStream() (я думаю, что это правильный метод) и выполните следующие действия:

public DataInputStream streamIn;
public Socket soc;

// initialize socket, etc...
    streamIn = soc.getInputStream();

public String getInput() {
    return (String) streamIn.readUTF(); // Do some other casting if this doesn't work
}

streamIn.readUTF() блокирует до тех пор, пока данные не станут доступными, что означает, что вам не нужно выполнять цикл, а многопоточность позволит вам выполнять другую обработку, пока вы ожидаете данные.

Смотрите здесь для получения дополнительной информации о DataInputStream и о том, что вы можете с этим сделать: http://docs.oracle.com/javase/6/docs/api/java/io/DataInputStream.html

0 голосов
/ 01 декабря 2011

Вы не меняете свою архитектуру немного, чтобы приспособить WebSockets.проверить Socket.IO .Это кросс-браузерный активатор WebSockets.

Вам придется написать контроллеры (сервлеты, например, в Java) , которые передают данные клиенту.Это не соответствует архитектуре запрос-ответ.

Вы также можете сконструировать его так, чтобы «push-сервлет» запускал «запрос» от клиента для получения «ответа».заинтересован в WebSockets, проверьте эту ссылку out.

0 голосов
/ 01 декабря 2011

Существует два подхода, позволяющие избежать занятых циклов / снов.

  • Используйте поток для каждого клиентского соединения и просто вызовите каждый поток read. Это блокирует поток, пока клиент не отправит некоторые данные, но это не проблема, потому что он не блокирует потоки, обрабатывающие других клиентов.

  • Использовать селекторы каналов Java NIO. Это позволяет потоку ждать, пока один из набора каналов (в данном случае сокетов) не получит данные для чтения. На этом есть раздел Oracle Java Tutorials .

Из этих двух подходов второй наиболее эффективен с точки зрения общего использования ресурсов. (Подход «поток-на-клиент» использует много памяти для стеков потоков и ЦП для издержек на переключение потоков.)


Занятые циклы, которые многократно вызывают (скажем) InputStream.available(), чтобы увидеть, есть ли какой-либо ввод, ужасно неэффективны. Вы можете сделать их менее неэффективными, замедляя опрос с помощью вызовов Thread.sleep(...), но это побочным эффектом делает службу менее отзывчивой. Например, если вы добавляете 1-секундный сон между каждым набором опросов, эффект, который увидит каждый клиент, состоит в том, что сервер , как правило, , задерживает 1 секунду перед обработкой каждого запроса. Предполагая, что эти запросы являются нажатиями клавиш, и ответы повторяют их, чистый результат - ужасно запаздывающий сервис.

0 голосов
/ 01 декабря 2011

Я думаю, вы можете просто поместить свой цикл в другой поток и немного поспать (возможно, на полсекунды?) Между итерациямиЭто все равно будет бесконечный цикл, но он не будет потреблять почти столько же ресурсов.

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