我正在尝试开发一个小型gwt聊天应用程序Atmosphere的gwt扩展。应用程序的服务器端部分负责关联传入AtmosphereResource,关联广播公司并暂停它。 以下是暂停新传入的AtmosphereResource的代码段:
private void doGet(AtmosphereResource ar, String userId) {
if(BroadcasterFactory.getDefault().lookup(userId) != null) {
ar.setBroadcaster(BroadcasterFactory.getDefault().lookup(userId).addAtmosphereResource(ar));
} else {
ar.setBroadcaster(BroadcasterFactory.getDefault().get(userId).addAtmosphereResource(ar));
}
ar.suspend();
...
}
当我查找AtmosphereResource时,使用它先前存储的uuid,我总是发现它为null:
...
AtmosphereResource arTarget = AtmosphereResourceFactory.getDefault().find(uuid);
if (arTarget != null) {
arTarget.getBroadcaster().broadcast(msg,arTarget);
} else {
log.info("handleRawMessage:no broadcaster "+((RawMessage) msg).toString());
}
...
怎么了?我还注意到AtmosphereResources快速onResume,因为它们会立即超时,但超时设置为-1。我错过了什么?这是我的pom片段。
<dependency>
<groupId>org.atmosphere.extensions</groupId>
<artifactId>atmosphere-gwt20-client</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.atmosphere.extensions</groupId>
<artifactId>atmosphere-gwt20-common</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.atmosphere.extensions</groupId>
<artifactId>atmosphere-gwt20-server</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.atmosphere</groupId>
<artifactId>atmosphere-runtime</artifactId>
<version>2.1.1</version>
</dependency>
答案 0 :(得分:0)
要获得广播公司,您必须将客户端连接到服务器。你确定你的客户正在连接吗?
VERSION 2.0
为了在2.0中实现服务器,我已经完成了:(客户端ID可以从请求中获取)
public class AtmosphereHandler extends AbstractReflectorAtmosphereHandler {
private static Logger logger = Logger.getLogger(AtmosphereHandler.class);;
@Override
public void onRequest(final AtmosphereResource ar) throws IOException {
logger.info("Connecting to comet with: "
+ ar.getRequest().getRequestURI());
Broadcaster broadcaster = BroadcasterFactory.getDefault().lookup(
YOUR_CLIENT_ID, true);
if (broadcaster.getAtmosphereResources().size() > 0) {
logger.debug("Broadcaster recovered with name: "
+ broadcaster.getID());
} else {
logger.debug("Broadcaster created with name: "
+ broadcaster.getID());
}
ar.setBroadcaster(broadcaster);
ar.setSerializer(new Serializer() {
Charset charset = Charset.forName(ar.getResponse()
.getCharacterEncoding());
@Override
public void write(OutputStream os, Object o) throws IOException {
try {
logger.info("Writing object to JSON outputstream with charset: "
+ charset.displayName());
String payload = serializer.serialize(o);
os.write(payload.getBytes(charset));
os.flush();
} catch (SerializationException ex) {
throw new IOException("Failed to serialize object to JSON",
ex);
}
}
});
ar.suspend();
}
private ServerSerializer serializer = new JacksonSerializerProvider()
.getServerSerializer();
在客户端部分,你应该有类似的东西:
AutoBeanClientSerializer json_serializer = new AutoBeanClientSerializer();
json_serializer.registerBeanFactory(beanFactory, ActivityMessage.class);
AtmosphereRequestConfig jsonRequestConfig = AtmosphereRequestConfig.create(json_serializer);
jsonRequestConfig.setUrl(GWT.getHostPageBaseURL() + HANDLER_URL_PART);
jsonRequestConfig.setContentType("application/json; charset=UTF-8");
jsonRequestConfig.setTransport(AtmosphereRequestConfig.Transport.WEBSOCKET);
jsonRequestConfig.setFallbackTransport(AtmosphereRequestConfig.Transport.STREAMING);
jsonRequestConfig.setOpenHandler(new AtmosphereOpenHandler() {
@Override
public void onOpen(AtmosphereResponse response) {
GWT.log("JSON Connection opened");
}
});
jsonRequestConfig.setCloseHandler(new AtmosphereCloseHandler() {
@Override
public void onClose(AtmosphereResponse response) {
GWT.log("JSON Connection closed");
}
});
jsonRequestConfig.setMessageHandler(new AtmosphereMessageHandler() {
@Override
public void onMessage(AtmosphereResponse response) {
}
});
Atmosphere atmosphere = Atmosphere.create();
final AtmosphereRequest jsonRequest = atmosphere.subscribe(jsonRequestConfig);
版本1.1.0RC4
我扩展AtmosphereGwtHandler以实现这样的服务器:
private static Logger logger;
@Override
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
logger = Logger.getLogger(AtmosphereHandler.class);
}
@Override
public int doComet(GwtAtmosphereResource resource) throws ServletException, IOException {
logger.info("Connecting to comet with: " +resource.getRequest().getRequestURI());
Broadcaster broadcaster = BroadcasterFactory.getDefault().lookup(YOUR_CONNECTION_ID, true);
if(broadcaster.getAtmosphereResources().size()>0){
logger.debug("Broadcaster recovered with name: " + broadcaster.getID());
}
else{
logger.debug("Broadcaster created with name: " + broadcaster.getID());
}
resource.getAtmosphereResource().setBroadcaster(broadcaster);
return NO_TIMEOUT;
}
@Override
public void cometTerminated(GwtAtmosphereResource cometResponse, boolean serverInitiated) {
logger.info("Disconnecting from comet. Broadcaster : " + cometResponse.getBroadcaster().getID());
super.cometTerminated(cometResponse, serverInitiated);
}
@Override
public void doPost(HttpServletRequest postRequest, HttpServletResponse postResponse,
List<?> messages, GwtAtmosphereResource cometResource) {
broadcast(messages, cometResource);
}
您必须使用目标目录中META-INF文件夹中的atmosphere.xml文件对其进行初始化。
我希望有所帮助!