如何使用 JAX-RS 连续流式传输文本数据
How to stream text data with JAX-RS continuously
我阅读了多个与我相似的问题并发现了这个:
但是我做不到。我使用纯 JAX-RS API 和 Open Liberty 作为我的服务器。不幸的是找不到 ResourceConfig,所以我无法禁用缓冲区,如上面的答案所述。
这是我的代码:
@GET
@Produces(MediaType.TEXT_PLAIN)
public Response sayHelloStream() {
LOGGER.debug("calling sayHelloStream");
StreamingOutput out = outputStream -> {
Writer writer = new BufferedWriter(new OutputStreamWriter(outputStream));
for (int i = 0; i < 999999999; i++) {
writer.write("Hello\n");
writer.flush();
try {
LOGGER.debug("before sleep");
TimeUnit.SECONDS.sleep(3);
LOGGER.debug("after sleep");
} catch (InterruptedException e) {
LOGGER.error("error with the timer", e);
}
}
};
return Response.ok(out).build();
}
在浏览器中调用它时没有任何反应。据我了解,由于缓冲区。我如何使用纯 JAX-RS 像这样流式传输文本数据?
我会使用 SSE 扩展。据我所知,它是 JAX-RS API 的一部分,尽管您可能需要一个额外的模块来启用它 server-side:
https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/sse.html
...
import javax.ws.rs.sse.Sse;
import javax.ws.rs.sse.SseEventSink;
import javax.ws.rs.sse.OutboundSseEvent;
...
@Path("events")
public static class SseResource {
@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
public void getServerSentEvents(@Context SseEventSink eventSink, @Context Sse sse) {
new Thread(() -> {
for (int i = 0; i < 10; i++) {
// ... code that waits 1 second
final OutboundSseEvent event = sse.newEventBuilder()
.name("message-to-client")
.data(String.class, "Hello world " + i + "!")
.build();
eventSink.send(event);
}
}).start();
}
}
它以 SSE 格式的块将文本数据流式传输到客户端,因此可以在浏览器中轻松处理,例如使用HTML5 <eventsource>
元素或 EventSource
JavaScript API.
var source = new EventSource('.../events');
source.addEventListener('message-to-client', function(e) {
console.log(e.data);
}, false);
我阅读了多个与我相似的问题并发现了这个:
但是我做不到。我使用纯 JAX-RS API 和 Open Liberty 作为我的服务器。不幸的是找不到 ResourceConfig,所以我无法禁用缓冲区,如上面的答案所述。
这是我的代码:
@GET
@Produces(MediaType.TEXT_PLAIN)
public Response sayHelloStream() {
LOGGER.debug("calling sayHelloStream");
StreamingOutput out = outputStream -> {
Writer writer = new BufferedWriter(new OutputStreamWriter(outputStream));
for (int i = 0; i < 999999999; i++) {
writer.write("Hello\n");
writer.flush();
try {
LOGGER.debug("before sleep");
TimeUnit.SECONDS.sleep(3);
LOGGER.debug("after sleep");
} catch (InterruptedException e) {
LOGGER.error("error with the timer", e);
}
}
};
return Response.ok(out).build();
}
在浏览器中调用它时没有任何反应。据我了解,由于缓冲区。我如何使用纯 JAX-RS 像这样流式传输文本数据?
我会使用 SSE 扩展。据我所知,它是 JAX-RS API 的一部分,尽管您可能需要一个额外的模块来启用它 server-side:
https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/sse.html
...
import javax.ws.rs.sse.Sse;
import javax.ws.rs.sse.SseEventSink;
import javax.ws.rs.sse.OutboundSseEvent;
...
@Path("events")
public static class SseResource {
@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
public void getServerSentEvents(@Context SseEventSink eventSink, @Context Sse sse) {
new Thread(() -> {
for (int i = 0; i < 10; i++) {
// ... code that waits 1 second
final OutboundSseEvent event = sse.newEventBuilder()
.name("message-to-client")
.data(String.class, "Hello world " + i + "!")
.build();
eventSink.send(event);
}
}).start();
}
}
它以 SSE 格式的块将文本数据流式传输到客户端,因此可以在浏览器中轻松处理,例如使用HTML5 <eventsource>
元素或 EventSource
JavaScript API.
var source = new EventSource('.../events');
source.addEventListener('message-to-client', function(e) {
console.log(e.data);
}, false);