Сервер Java SSE с com.sun.net.httpserver.HTTPServer

#java #http #java-11

Вопрос:

Как можно реализовать сервер SSE с com.sun.net.httpserver.HttpServer
Я написал HttpHandler вот так просто для тестирования соединения:

 public class SseResource implements HttpHandler {

    @Override
    public void handle(HttpExchange exchange) throws IOException {
        Headers responseHeaders = exchange.getResponseHeaders();
        responseHeaders.add("Content-Type", "text/event-stream");
        responseHeaders.add("Connection", "keep-alive");
        responseHeaders.add("Transfer-Encoding", "chunked");
        responseHeaders.add("X-Powered-By", "Native Application Server");

        exchange.sendResponseHeaders(200, responseHeaders.size());
        OutputStream writer = exchange.getResponseBody();
        for (int i = 0; i < 10; i  ) {
            writer.write("event: countn".getBytes()); // <-- Connection Closed at this line 
            writer.write(("data: "   i   "n").getBytes());
            writer.write("nn".getBytes());
            writer.flush();
            sleep();
        }

        writer.close();
    }


    public static void sleep() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}    
 

Не работает.
Я тестирую соединение с curl командой Linux:

 curl -Ni http://localhost:8080/stream

HTTP/1.1 200 OK
Connection: keep-alive
X-powered-by: Native Application Server
Date: Thu, 10 Jun 2021 05:27:56 GMT
Transfer-encoding: chunked
Content-type: text/event-stream
Content-length: 4

curl: (18) transfer closed with outstanding read data remaining
 

Я неправильно понял насчет сервера SSE? или в моем коде есть проблема?

Комментарии:

1. exchange.sendResponseHeaders(200, responseHeaders.size()); Как насчет использования размера ответа вместо количества заголовков?

Ответ №1:

размер ответа должен быть равен нулю .
Я сравниваю заголовки своих ответов с результатом этого проекта : https://github.com/enkot/SSE-Fake-Server

 exchange.sendResponseHeaders(200, 0);
 

Комментарии:

1. Да, и вы не должны указывать «Кодировка передачи: фрагментированный» в заголовках пользовательских ответов: HTTPServer делает это за вас. Более конкретно, если вы вызовете: sendResponseHeaders(код, 0), сервер передаст тело ответа с использованием фрагментированной кодировки. Если вы укажете <длина> (вместо 0), сервер отправит ответ без кодировки передачи, но с «Длина содержимого: <длина><длина>». Видишь docs.oracle.com/en/java/javase/16/docs/api/jdk.httpserver/com/…