问题描述
我正在尝试Jersey SSE官方文档中给出的示例示例
I am trying with a sample example given in the official documentation of Jersey SSE
在下面的链接中引用"14.5.2.与EventSource进行异步SSE处理" https://jersey.github.io/documentation/2.8/user-guide.html#example-simple-sse
Refer " 14.5.2. Asynchronous SSE processing with EventSource " in the below linkhttps://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;
// }
}
然后在一种动作方法中,我只是按照以下方式初始化事件监听
Then in one of the action method, I am just initialising the event listening as follows
//Start listening to event from server
ClientSSEEventManager clientSSEEventManager = new ClientSSEEventManager();
clientSSEEventManager.WaitForEvents();
///
客户端的Web.xml具有init-param,如下所示
Client's Web.xml has init-param as follow
<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!
但是客户端没有打印任何内容.我在这想念什么吗?我怀疑client.Target,它应该有"http://:8080/server/events"吗?或者应该只是"http://:8080/events"
But nothing is printing at client side.Am I missing something over here ?I have a doubt, the client.Target , it should have "http://:8080/server/events" ? OR it should be just "http://:8080/events"
推荐答案
SSE最终对我来说很好.我们需要做几件事
SSE worked fine for me finally.there are couple of things we need to do
-
Springs中的SSE侦听器
SSE listener in Springs
@Singleton
@Path("/events")
public class NotificationHandler {
@Path("/register/{userName}")
@Produces(SseFeature.SERVER_SENT_EVENTS)
@GET
public @ResponseBody EventOutput registerForAnEventSummary(
@PathParam("userName") String userName) {
}
}
致电服务以通知所有客户的服务
Call a service that make a call to notify all clients
PostMethod postMethod = null;
postMethod = new PostMethod(
resourceBundle.getString("localhost:8080")
+ resourceBundle.getString("applicationnotifier")
+ resourceBundle
.getString("sse/events/broadcast/"));
广播公司
A broadcaster
@Path("/broadcast")
@POST
@Produces(MediaType.TEXT_PLAIN)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String broadcastNotifications(@FormParam("message") String message) { }
Javascript-通过注册监听所有SSE事件
Javascript - listen to all SSE events by registering
var notificationBaseURL = ""; //The URL Where your services are hosted
function listenAllEvents() {
if ( (EventSource) !== "undefined") {
var source = new EventSource(
notificationBaseURL+"applicationnotifier/sse/events/register/"+loggedInUserName);
source.onmessage = notifyEvent;
} else {
console.log("Sorry no event data sent - ");
}
}
function notifyEvent(event) {
var responseJson = JSON.parse(event.data);
alert("... Notification Received ...");
}
这篇关于使用SSE在Jersey 2.8中不触发服务器端事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!