我在使用Atmosphere时使用websocket
传输有问题。代码如下所示:
当我使用long-polling
作为传输时,一切工作正常。我能够在没有任何问题的情况下调用注入类的方法。然而,当我配置客户端使用websocket
时,我最终得到一个异常,说IllegalStateException: Singleton not set for org.glassfish.main.core.kernel
,方法调用失败。我怀疑这是由于Atmosphere/Glassfish在正常servlet(因此,ApplicationContext)环境之外处理WebSockets的方式。
@ManagedService(path = "/rt/test/{id}")
public class TestWebService {
private @Inject TestWebController controller;
@Get
public void onGet(AtmosphereResource r) {
Broadcaster b = controller.getBroadcaster(r.getRequest().getPathInfo(), true);
if(b != null)
r.setBroadcaster(b);
else
r.getResponse().setStatus("Invalid parameter", 400);
}
}
现在控制器:
@ApplicationScoped
public class TestWebController {
private @Inject IdValidator validator;
public void eventHandler(@Observes MyEvent myEvent) {
Broadcaster b = getBroadcaster(myEvent.getId(), false);
if(b != null)
b.broadcast(myEvent.getMessage());
}
public Broadcaster getBroadcaster(String id, boolean create) {
if(validator.validate(id)) {
Broadcaster b = BroadcasterFactory.getDefault().lookup(id);
if(b == null && create)
b = BroadcasterFactory.getDefault().get(id);
return b;
}
return null;
}
}
我已经尝试了不同的范围的控制器和几乎所有的东西。如果我将广播器创建逻辑移动到web服务类中,它工作得很好(没有注释),但是我失去了验证id的能力,这在某种程度上很重要。
我使用玻璃鱼4和大气2.1.7与atmosphere-runtime
, atmosphere-annotations
和atmosphere-cdi
罐子加载。
我打算尝试最新的2.2候选版本,但是在bug跟踪器中没有提到任何类似的问题,所以我不乐观。
更新:同样的问题出现在Atmosphere 2.2 RC3.
更新:我能够通过用@javax.ejb.Stateful注释类来完成这项工作。我还没有进行任何实质性的测试,看看是否有任何副作用,但我能够连接到一个websocket,并确认注入正确发生。我用的是Atmosphere 2.2.0
这实际上是由于CDI规范中的一个缺点:https://java.net/jira/plugins/servlet/mobile问题/glassfish - 20468
遗憾的是,我现在不得不求助于长时间的投票。