无法使用Atmosphere运行时广播到单个连接

时间:2010-12-28 05:15:35

标签: atmosphere

我正在使用Atmosphere runtime 0.6 Snapshot。 Tomcat 7正确记录我正在使用Http11 Nio连接器,并且没有警告将使用BlockingIO。

我正在尝试向三种频道发送消息。

  1. Global Broadcaster - 向所有已暂停的资源广播。 (全部)
  2. 向特定资源(例如,合作伙伴)广播
  3. 向当前资源(自我)广播
  4. 当发生登录操作时,为了实现这种广播,我必须在会话中存储什么?

    我的代码的一些细节如下:

    1. 我的处理程序实现了AtmosphereHandler
    2. 在构造函数中,我按如下方式实例化globalBroadcaster:

      globalBroadcaster = new DefaultBroadcaster();

    3. 登录时,

      resource.getAtmosphereConfig().getServletContext().setAttribute(name, selfBroadcaster); 其中name是request参数的用户名,selfBroadcaster是DefaultBroadcaster的新实例。

    4. 以下是sendMessageToPartner的代码,

    5. 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条消息后一直发生

      是否存在某些线程问题?我做错了什么?

      我希望有人帮助我解决这个问题。

1 个答案:

答案 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");

要向合作伙伴发送消息,只需查找合作伙伴的广播公司,并按照上述方式进行单一连接。

希望这可以帮助那些试图达到同样目标的人。 可能有更好的方法来做到这一点。 我想我必须使用这种方法,直到有人提出更好的解决方案。