3
我與澤西上證所的官方文檔服務器端事件不使用SSE
在下面的鏈接,請參閱「14.5.2。異步SSE處理用的EventSource」在給定的樣本例如試圖在澤西島2.8射擊 https://jersey.github.io/documentation/2.8/user-guide.html#example-simple-sse
我的代碼如下
客戶端代碼 -
public class ClientSSEEventManager {
public void WaitForEvents() {
// Client client = ClientBuilder.newBuilder()
// .register(SseFeature.class).build();
// WebTarget target =
// client.target("http://localhost:8080/server/events");
//
// 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));
// }
Client client = ClientBuilder.newBuilder().register(SseFeature.class)
.build();
WebTarget target = client.target("http://localhost:8080/server/events");
EventSource eventSource = EventSource.target(target).build();
EventListener listener = new EventListener() {
@Override
public void onEvent(InboundEvent inboundEvent) {
System.out.println(inboundEvent.getName() + "; "
+ inboundEvent.readData(String.class));
}
};
eventSource.register(listener, "message-to-client");
eventSource.open();
}
}
public class MyApplication extends ResourceConfig {
public MyApplication(){
super(ClientSSEEventManager.class, SseFeature.class);
}
// Set<Class<?>> classes = new HashSet<Class<?>>() {
// /**
// *
// */
// private static final long serialVersionUID = 1L;
//
// { add(ClientSSEEventManager.class);
// }};
//
// @Override
// public Set<Class<?>> getClasses() {
// return classes;
// }
}
中的一個
然後操作方法,我只是初始化事件監聽如下
//Start listening to event from server
ClientSSEEventManager clientSSEEventManager = new ClientSSEEventManager();
clientSSEEventManager.WaitForEvents();
///
客戶的web.xml已經INIT-PARAM如下
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.framework.MyApplication</param-value>
</init-param>
服務器代碼 -
@Path("events")
public class ServerSSEServerEventManager {
@GET
@Produces(SseFeature.SERVER_SENT_EVENTS)
public EventOutput getNotificationEvents(){
final EventOutput eventOutput = new EventOutput();
new Thread(new Runnable() {
@Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
// ... code that waits 1 second
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);
}
} catch (IOException e) {
throw new RuntimeException(
"Error when writing the event.", e);
} finally {
try {
eventOutput.close();
} catch (IOException ioClose) {
throw new RuntimeException(
"Error when closing the event output.", ioClose);
}
}
}
}).start();
return eventOutput;
}
}
在客戶期望的輸出方如下
message-to-client; Hello world 0!
message-to-client; Hello world 1!
message-to-client; Hello world 2!
message-to-client; Hello world 3!
message-to-client; Hello world 4!
message-to-client; Hello world 5!
message-to-client; Hello world 6!
message-to-client; Hello world 7!
message-to-client; Hello world 8!
message-to-client; Hello world 9!
但客戶端沒有打印任何東西。 我在這裏錯過了什麼嗎? 我有疑問,客戶端。目標,它應該有「http://:8080 /服務器/事件」?或者它應該只是「http://:8080/events」
你的服務器的URL是依賴於應用程序的'語境Path'。如果你部署爲'server',那麼你的路徑應該是'http:// localhost:8080/server/events'。我會在服務器端添加一些日誌記錄,並將Jackson日誌過濾器添加到客戶端client.register(新的LoggingFilter(LOG,true));'這樣你就可以看到你的客戶端正在發送/接收什麼。 – Baldy
如果我在http:///server/events中直接在瀏覽器中打開url,則會調用服務器端getNotificationEvents方法。但如果我通過運行上面的代碼中顯示的客戶端應用程序來完成相同的事情,服務器端getNotificationEvents不會被調用。 –
Sadanand
好吧,看着你的客戶端代碼,你正在設置事件處理程序,但你永遠不會發出你的GET請求。 – Baldy