问题
I have a working Jersey/Atmosphere/Guice application which has two Atmosphere Resources. The first is pretty much a clone of the example chat application:
@Path("/chat")
@AtmosphereService(broadcaster = JerseyBroadcaster.class, path = "/chat")
public class ChatResource {
@Suspend(contentType = "application/json")
@GET
public String suspend() {
return "";
}
@Broadcast(writeEntity = false)
@POST
@Produces("application/json")
public Response broadcast(Message message) {
return new Response(message.author, message.message);
}
}
The second is a test notification resource which will be sent server-side events:
@Path("/notifications")
@AtmosphereService(broadcaster = JerseyBroadcaster.class, path = "/notifications")
public class NotificationsResource {
@Suspend(contentType = "application/json")
@GET
public String suspend() {
return "";
}
}
Everything is wired up correctly and works fine. However in order for me to send a server side event I issue:
MetaBroadcaster.getDefault().broadcastTo("/*", new Response(...));
Clearly, this will send the broadcast message to both resources. What I want to do is send the server side events only to the notifications resource:
MetaBroadcaster.getDefault().broadcastTo("/notifications", new NotificationResponse(...));
However, that doesn't work. I always receive the following error:
org.atmosphere.cpr.MetaBroadcaster - No Broadcaster matches /notifications.
That's because there is only one broadcaster registered; the JerseyBroadcaster on /*.
The question is: how do I make it so that these two resources have different broadcasters with different IDs/Names?
回答1:
In the resource, suspend using the channel you want (the 'true' parameter to lookup() forces the channel to be created if it doesn't exist):
@Suspend( contentType = MediaType.APPLICATION_JSON, period = MAX_SUSPEND_MSEC )
@GET
public Broadcastable suspend( @Context final BroadcasterFactory factory )
{
return new Broadcastable( factory.lookup( MY_CHANNEL, true ) );
}
In the other code, which can be pretty much anywhere, broadcast to that channel:
Broadcaster broadcaster = BroadcasterFactory.getDefault().lookup( MY_CHANNEL );
if( broadcaster != null ) {
broadcaster.broadcast( message );
}
If you're going to be broadcasting from a resource method, you can annotate it instead (as shown in ChatResource's broadcast() method).
回答2:
Just inject Broadcaster using the @PathParam annotation:
private @PathParam("topic") Broadcaster topic;
You can also use the @Context annotation. Hope that help.
-- Jeanfrancois
来源:https://stackoverflow.com/questions/21650032/atmosphere-jersey-how-do-i-have-multiple-broadcasters