2013-12-11 3 views
1

У меня есть фрагмент кода, который считывает данные POST из входного потока запроса сервлета. Я использую java nio для чтения данных.Тайм-аут сокета при чтении из запроса сервлета inputstream

Для большинства случаев и обычных данных код работает отлично. Однако в некоторых случаях, когда данные велики (content length = 600000), метод чтения канала, похоже, терпит неудачу с ошибкой таймаута Socket. Также, похоже, это происходит только с IE 9, он отлично работает с Firefox и Chrome.

Изучая это, я понял, что при использовании IE почтовые данные, по-видимому, занимают немного больше времени, чем другие браузеры, доступные для чтения. Поэтому я поставил Thread.sleep(400) перед кодом, и код начал нормально работать и для IE.

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

Есть ли способ, по которому я могу указать канал, чтобы не выходить из таймаута или вообще не удалять таймаут?

Ниже используется код,

ReadableByteChannel channel = Channels.newChannel(inputStream); 
byte[] postData = new byte[contentLength]; 
ByteBuffer buf = ByteBuffer.allocateDirect(contentLength); 
int numRead = 0; 
int counter = 0; 
while (numRead >= 0) { 
    buf.rewind(); 
    numRead = channel.read(buf); 
    buf.rewind(); 
    for (int i = 0; i < numRead; i++) { 
     postData[counter++] = buf.get(); 
    } 
} 
return postData; 

InputStream непосредственно с помощью request.getInputStream() и содержание длина с помощью request.getContentLength().

Используемый контейнер Tomcat 7.0.42 во встроенном режиме.

+0

Опубликуйте свой код, тогда, возможно, мы сможем вам помочь! – isnot2bad

+0

Является ли запрос POST из вашего кода на стороне клиента? Если да, то какая это технология? См. Следующее сообщение для тайм-аутов HTTP-запросов в java: http://stackoverflow.com/questions/1414795/how-to-specify-http-request-timeout-parameter-on-java-servlet-container. –

+0

@MarkTielemans, Да POST сделан из кода на стороне клиента. Использование SmartGWT (инструментария javascript). Ссылка, о которой вы упомянули, по-видимому, содержит подробные сведения о тайм-аутах на стороне клиента. Хотя в моем случае ошибка, похоже, связана с отказом от сервера, а не ожиданиями. – Vicky

ответ

0

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

Итак, следующая лучшая вещь, которую я мог применить, я поймал Исключение тайм-аута Socket и спал в течение минимального минимального времени, которое, как я знал, было необходимо, то есть 400 мс. И затем снова попытался установить логику для 3 попыток, прежде чем сдаться. До сих пор это работало, для увеличения объема данных.

0

Ваш тайм-аут чтения слишком короткий. Увеличьте его.

Но я бы выбросил этот код NIO и просто прочитал непосредственно из входного потока. С DataInputStream.readFully() это одна строка кода. Ваш код NIO делает это в любом случае, но очень круто с несколькими дополнительными слоями.

+0

Как можно увеличить время ожидания чтения на сервлете, полученном входным потоком? Я бы ожидал, что это потребует некоторой доработки конкретной реализации клиента? –

+0

@Szymon Это дает ответ на вопрос, и он не состоит или не содержит критики или просьбы о разъяснении. Вы говорите ерунду. – EJP

+0

@ AndersR.Bystrup Тайм-аут чтения для запросов будет установлен в некоторой конфигурации где-то для вашего неназванного контейнера сервлетов или в вашем неустановленном коде, который отображает входной поток в канал. – EJP

0

Если вы можете прочитать заголовок длины содержимого, вы можете увеличить время сна на его основе. Это должно по крайней мере сделать вашу функцию кода в разных сценариях. Конечно, это обходной путь, но он кажется прочным. Кроме того, вы можете set the socket timeout wait to a higher number. Однако это изменение будет для всех ваших сервлетов, и оно будет гораздо менее гибким.

+0

В этой теме вы расскажете о настройке под соединителем Apache JK к tomcat. – Vicky

Смежные вопросы