泽西岛 SSE 客户端未收到任何事件
Jersey SSE Client receives no events
我正在尝试使用 Jersey 2.5.1(无法升级到更高版本)实现 Server-Sent-Events 客户端,但连接不断关闭,没有读取任何事件。
我已将代码缩减为我认为最简单的 manual,但没有成功。
我已经针对其他服务器测试了我的客户端,行为是相同的,所以我相信我的问题是基于客户端的。
客户端连接到资源,服务器开始发送事件。但是没有收到任何事件,连接过早关闭。
我也尝试过使用 EventSource 而不是 EventInput,但结果是一样的。
有人可以告诉我我错过了什么吗?谢谢
服务器代码:
@Path("events")
public class SseResource {
/**
* Create stream.
* @return chunkedOutput of events.
*/
@GET
@Produces(SseFeature.SERVER_SENT_EVENTS)
public EventOutput getServerSentEvents() {
System.out.println("Received GetEvent");
final EventOutput eventOutput = new EventOutput();
new Thread(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
final OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder();
eventBuilder.name("message-to-client");
eventBuilder.data(String.class, "Hello world " + i + "!");
final OutboundEvent event = eventBuilder.build();
eventOutput.write(event);
System.out.println("Wrote event " + i);
// ... code that waits 1 second
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
} catch (IOException e) {
System.out.println("Error when writing the event" + e);
throw new RuntimeException("Error when writing the event.", e);
} finally {
try {
eventOutput.close();
} catch (IOException ioClose) {
System.out.println("Error when closing the eventOuput" + ioClose);
throw new RuntimeException("Error when closing the event output.", ioClose);
}
}
}
}).start();
return eventOutput;
}
}
客户代码:
import org.glassfish.jersey.media.sse.EventInput;
import org.glassfish.jersey.media.sse.InboundEvent;
import org.glassfish.jersey.media.sse.SseFeature;
...
public final void simpleClientTest() {
final Client client = ClientBuilder.newBuilder().register(SseFeature.class).build();
final WebTarget target = client.target("http://localhost:8182/events");
final EventInput eventInput = target.request().get(EventInput.class);
while (!eventInput.isClosed()) {
final InboundEvent inboundEvent = eventInput.read();
if (inboundEvent == null) {
// connection has been closed
break;
}
System.out.println(inboundEvent.getName() + "; " + inboundEvent.readData(String.class));
}
System.out.println("eventInput finished");
}
我终于找到问题的原因了。服务器启动代码(上面未给出)不包含 SseFeature.class 资源。包括这里以防其他人遇到此问题....
public void startServer() throws IOException {
final URI baseUri = UriBuilder.fromUri("http://0.0.0.0").port(serverPort).build();
System.out.println("Starting media server at: " + baseUri);
final ResourceConfig config = new ResourceConfig(SseResource.class, SseFeature.class);
server = GrizzlyHttpServerFactory.createHttpServer(baseUri, config);
}
我正在尝试使用 Jersey 2.5.1(无法升级到更高版本)实现 Server-Sent-Events 客户端,但连接不断关闭,没有读取任何事件。 我已将代码缩减为我认为最简单的 manual,但没有成功。
我已经针对其他服务器测试了我的客户端,行为是相同的,所以我相信我的问题是基于客户端的。 客户端连接到资源,服务器开始发送事件。但是没有收到任何事件,连接过早关闭。
我也尝试过使用 EventSource 而不是 EventInput,但结果是一样的。 有人可以告诉我我错过了什么吗?谢谢
服务器代码:
@Path("events")
public class SseResource {
/**
* Create stream.
* @return chunkedOutput of events.
*/
@GET
@Produces(SseFeature.SERVER_SENT_EVENTS)
public EventOutput getServerSentEvents() {
System.out.println("Received GetEvent");
final EventOutput eventOutput = new EventOutput();
new Thread(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
final OutboundEvent.Builder eventBuilder = new OutboundEvent.Builder();
eventBuilder.name("message-to-client");
eventBuilder.data(String.class, "Hello world " + i + "!");
final OutboundEvent event = eventBuilder.build();
eventOutput.write(event);
System.out.println("Wrote event " + i);
// ... code that waits 1 second
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
} catch (IOException e) {
System.out.println("Error when writing the event" + e);
throw new RuntimeException("Error when writing the event.", e);
} finally {
try {
eventOutput.close();
} catch (IOException ioClose) {
System.out.println("Error when closing the eventOuput" + ioClose);
throw new RuntimeException("Error when closing the event output.", ioClose);
}
}
}
}).start();
return eventOutput;
}
}
客户代码:
import org.glassfish.jersey.media.sse.EventInput;
import org.glassfish.jersey.media.sse.InboundEvent;
import org.glassfish.jersey.media.sse.SseFeature;
...
public final void simpleClientTest() {
final Client client = ClientBuilder.newBuilder().register(SseFeature.class).build();
final WebTarget target = client.target("http://localhost:8182/events");
final EventInput eventInput = target.request().get(EventInput.class);
while (!eventInput.isClosed()) {
final InboundEvent inboundEvent = eventInput.read();
if (inboundEvent == null) {
// connection has been closed
break;
}
System.out.println(inboundEvent.getName() + "; " + inboundEvent.readData(String.class));
}
System.out.println("eventInput finished");
}
我终于找到问题的原因了。服务器启动代码(上面未给出)不包含 SseFeature.class 资源。包括这里以防其他人遇到此问题....
public void startServer() throws IOException {
final URI baseUri = UriBuilder.fromUri("http://0.0.0.0").port(serverPort).build();
System.out.println("Starting media server at: " + baseUri);
final ResourceConfig config = new ResourceConfig(SseResource.class, SseFeature.class);
server = GrizzlyHttpServerFactory.createHttpServer(baseUri, config);
}