Как создать постоянное соединение Http в Java
Я хочу создать keep-alive соединение, которое не должно закрываться. Я пробовал ниже путь, но он закрывается после даты печати.
public class SimplePHTTPServer {
public static void main(String args[]) throws IOException {
ServerSocket server = new ServerSocket(1122);
System.out.println("Listening for connection on port 1122 ....");
while (true) {
try (Socket socket = server.accept()) {
Date today = new Date();
String httpResponse = "HTTP/1.1 200 OK\r\n\r\n" + today;
socket.getOutputStream().write(httpResponse.getBytes("UTF-8"));
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Проверено с помощью curl ниже фактический результат:
curl -i -X GET -H "Соединение: keep-alive" http://localhost:1122/
HTTP / 1.1 200 ОК
Чт Авг 02 18:42:30 IST 2018
ожидаемый результат:
curl -i -X GET -H "Соединение: keep-alive" http://localhost:1122/
HTTP / 1.1 200 ОК
Чт Авг 02 18:42:30 IST 2018
Чт Авг 02 18:47:30 IST 2018
Чт Авг 02 18:52:30 IST 2018
... скоро
Как создать keep-alive соединение?
1 ответ
Вы ошибаетесь в цели постоянного соединения. Это позволяет вам сделать несколько запросов и получить несколько ответов по одному соединению.
В своем тесте вы отправляете один запрос и пытаетесь предоставить тело ответа неограниченной длины.
То, как вы пытаетесь предоставить тело ответа неограниченной длины, неверно. Пожалуйста, прочтите этот RFC, обращая особое внимание на "кодирование передачи". Некоторые цитаты выбора:
Постоянные соединения в HTTP/1.0 явно согласовываются, поскольку они не являются поведением по умолчанию. Экспериментальные реализации постоянных соединений в HTTP/1.0 ошибочны, и новые средства в HTTP/1.1 предназначены для устранения этих проблем.
...
Постоянные соединения используются по умолчанию для сообщений HTTP/1.1; мы вводим новое ключевое слово (Connection: close) для объявления непостоянства. Смотрите раздел 14.10.
...
7.2.2 Длина объекта
Длина объекта сообщения - это длина тела сообщения до того, как были применены любые кодировки передачи. Раздел 4.4 определяет, как определяется длина передачи тела сообщения.
...
4.4 Длина сообщения
Длина передачи сообщения - это длина тела сообщения в том виде, в каком оно появляется в сообщении; то есть после того, как были применены любые кодировки передачи. Когда тело сообщения включается в сообщение, длина передачи этого тела определяется одним из следующих способов (в порядке приоритета):
...
2.Если поле заголовка Transfer-Encoding (раздел 14.41) присутствует и имеет любое значение, отличное от "identity", то длина передачи определяется с помощью "chunked" кодировки передачи (раздел 3.6), если только сообщение завершается закрытием соединения.
3.Если присутствует поле заголовка Content-Length (раздел 14.13), его десятичное значение в OCTET представляет как длину объекта, так и длину передачи. Поле заголовка Content-Length НЕ ДОЛЖНО отправляться, если эти две длины различны (то есть, если присутствует поле заголовка Transfer-Encoding). Если сообщение получено как с полем заголовка Transfer-Encoding, так и с полем заголовка Content-Length, последнее ДОЛЖНО игнорироваться.
4.Если в сообщении используется тип мультимедиа "multipart/byteranges", а длина передачи не указана иным образом, то этот самоустанавливающийся тип мультимедиа определяет длину передачи. Этот тип носителя UST НЕ должен использоваться, если отправитель не знает, что получатель может его задавать; Присутствие в запросе заголовка Range с указателями ulteple byte- range от клиента 1.1 подразумевает, что клиент может анализировать ответы multipart/byteranges.
Заголовок диапазона может быть передан прокси 1.0, который не понимает multipart/byteranges; в этом случае сервер ДОЛЖЕН разграничить сообщение, используя методы, определенные в пунктах 1,3 или 5 этого раздела.
5. На сервере, закрывающем соединение. (Закрытие соединения не может использоваться для указания конца тела запроса, так как это не оставит серверу никакой возможности отправить ответ.)