开发者

Atmosphere Request Scoped Broadcasts

I'm having trouble restricting the scope of my broadcasts, using Atmosphere 0.7.2.

I have a Jersey POJO, with an open method, and I want to pass the broadcaster to a non-webservice class. This is to allow separation between WAR and EJB layers.

@Path("/")
public class MyJerseyPojo {
    @Context
    private Broadcaster broadcaster;

    @GET
    @Suspend
    public String open() {
        Manager.register(/* Session ID */, new NonWebservice(this.broadcaster));
        return "";
    }
}

public class NonWebService implements Sender {
    private Broadcaster broadcaster;

    public NonWebService(Broadcaster b) {
        this.broadcaster = b;
    }

    @Override
    public void send(String thing) {
        this.broadcaster.broadcast(thing);
    }
}

The idea is that update events will call send, and this will notify the client with the suspended response. Each client should be associated with a separate broadcaster.

The problem is, this solution uses the same broadcaster for all clients. I have tried adding @Suspend(scope = Suspend.SCOPE.REQUEST) to the open method, but this causes no broadcast messages to be received.

I also tried the following in the open method:

@GET
@Suspend
public String open() {
    Broadcaster b = BroadcasterFactory.getDefault().get(JerseyBroadcaster.class, UUID.randomUUID());
    b.setScope(Broadcaster.SCOPE.REQUEST);
    Manager.register(/* Session ID */, new NonWebservice(b));
}

This didn't work, either using @Suspend or @Suspend(scope = Suspend.SCOPE.REQUEST). In each case, the client didn't receive any broadcast messages. I did once get a message that the broadcaster had been destroyed and couldn't be used, but I can't remember how I did this!

I have seen a similar question but I'm not su开发者_开发百科re how to translate it to my POJO, as I'm not extending AtmosphereHandler.

Thanks


It turns out, after a lot of digging, that it's not safe to cache broadcasters, as the AtmosphereFilter was creating a new, Request-scoped broadcaster after my open() method completed.

Hence, in the NonWebservice class now looks like this:

public class NonWebService implements Sender {
    private Class<? extends Broadcaster> clazz;
    private Object broadcasterId;

    public NonWebService(Class<? extends Broadcaster> clazz, Object broadcasterId) {
        this.clazz = clazz;
        this.broadcasterId = broadcasterId;
    }

    @Override
    public void send(String thing) {
        Broadcaster b = BroadcasterLookup.getDefault().get(this.clazz, this.broadcasterId);
        b.broadcast(thing);
    }
}

Now I could do with figuring out how to schedule request-scoped fixed broadcasts...


Actually, in the end I found that I needed to return a broadcastable from my suspended method. The broadcaster was recreated as session-scoped but kept available for later broadcasts. Just make sure that you don't broadcast anything until the suspended method has returned, as that might get lost.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜