我正在使用Atmosphere runtime 0.6 Snapshot。 Tomcat 7正确记录我正在使用Http11 Nio连接器,并且没有警告将使用BlockingIO。
我正在尝试向三种频道发送消息。
当发生登录操作时,为了实现这种广播,我必须在会话中存储什么?
我的代码的一些细节如下:
在构造函数中,我按如下方式实例化globalBroadcaster:
globalBroadcaster = new DefaultBroadcaster();
登录时,
resource.getAtmosphereConfig().getServletContext().setAttribute(name, selfBroadcaster);
其中name是request参数的用户名,selfBroadcaster是DefaultBroadcaster的新实例。
以下是sendMessageToPartner的代码,
private synchronized void sendMessageToPartner(Broadcaster selfBroadcaster,
AtmosphereResource<HttpServletRequest, HttpServletResponse> resource,String name, String message) {
// this gives the partner's name
String partner= (String) resource.getAtmosphereConfig().getServletContext().getAttribute(name + PARTNER_NAME_TOKEN);
// get partner's broadcaster
Broadcaster outsiderBroadcaster = (Broadcaster) resource
.getAtmosphereConfig().getServletContext()
.getAttribute(partner);
if (outsiderBroadcaster == null) {
sendMessage(selfBroadcaster, "Invalid user " + partner);
return;
}
// broadcast to partner
outsiderBroadcaster.broadcast(" **" + message);
我希望我已经提供了所有必需的信息。如果需要,我可以提供更多信息。
问题是,全局消息被发送。当发送到合作伙伴的消息时,有时它会被阻止,根本不会在客户端中收到消息。这种情况在3-4条消息后一直发生
是否存在某些线程问题?我做错了什么?
我希望有人帮助我解决这个问题。
答案 0 :(得分:6)
好的,我想通过Atmosphere运行时如何实现这一点。 首先,我升级到0.7 SNAPSHOT,但我认为同样的逻辑也适用于0.6。
因此,要为单个用户创建广播公司:
在GET请求中,
// Use one Broadcaster per AtmosphereResource
try {
atmoResource.setBroadcaster(BroadcasterFactory.getDefault().get());
} catch (Throwable t) {
throw new IOException(t);
}
// Create a Broadcaster based on this session id.
selfBroadcaster = atmoResource.getBroadcaster();
// add to the selfBroadcaster
selfBroadcaster.addAtmosphereResource(atmoResource);
atmoResource.suspend();
调用登录操作时,
//Get this broadcaster from session and add it to BroadcasterFactory.
Broadcaster selfBroadcaster = (Broadcaster) session.getAttribute(sessionId);
BroadcasterFactory.getDefault().add(selfBroadcaster, name);
Now the global broadcaster. The logic here is, you create a broadcaster from the first resource and then add each resource as they log in.
Broadcaster globalBroadcaster;
globalBroadcaster = BroadcasterFactory.getDefault().lookup(DefaultBroadcaster.class, GLOBAL_TOKEN, false);
if (globalBroadcaster == null) {
globalBroadcaster = selfBroadcaster;
} else {
BroadcasterFactory.getDefault().remove(
globalBroadcaster, GLOBAL_TOKEN);
AtmosphereResource r = (AtmosphereResource) session
.getAttribute("atmoResource");
globalBroadcaster.addAtmosphereResource(r);
}
BroadcasterFactory.getDefault().add(globalBroadcaster,
GLOBAL_TOKEN);
最后,您可以按如下方式向所有连接广播到单个连接或全局广播:
// Single Connection/Session
Broadcaster singleBroadcaster= BroadcasterFactory.getDefault().lookup(
DefaultBroadcaster.class, name);
singleBroadcaster.broadcast("Only for you");
// Global
Broadcaster globalBroadcaster = BroadcasterFactory.getDefault().lookup(DefaultBroadcaster.class,GLOBAL_TOKEN, false);
globalBroadcaster.broadcast("Global message to all");
要向合作伙伴发送消息,只需查找合作伙伴的广播公司,并按照上述方式进行单一连接。
希望这可以帮助那些试图达到同样目标的人。 可能有更好的方法来做到这一点。 我想我必须使用这种方法,直到有人提出更好的解决方案。