2010-12-28 4 views
4

Я использую среду работы Atmosphere 0.6 Снимок. Tomcat 7 правильно регистрирует, что я использую разъем Http11 Nio, и нет предупреждения о том, что BlockingIO будет использоваться.Невозможно транслировать до одного соединения с использованием среды Atmosphere

Я пытаюсь отправить сообщения на три вида каналов.

  1. Global Broadcaster - трансляция всех приостановленных ресурсов. (Все)
  2. Broadcast для конкретного ресурса (скажем, партнер)
  3. Broadcast для текущего ресурса (Self)

Когда происходит действие Логин, то, что все я должен хранить в сессии для того, чтобы добиться такого рода вещания?

Некоторые детали моего кода следующим образом:

  1. Мой Handler реализует AtmosphereHandler
  2. В конструкторе я экземпляр globalBroadcaster следующим образом:

    globalBroadcaster = new DefaultBroadcaster();

  3. При входе в систему ,

    resource.getAtmosphereConfig().getServletContext().setAttribute(name, selfBroadcaster); где имя - это имя пользователя из параметра запроса, а selfBroadcaster - это новый экземпляр DefaultBroadcaster.

  4. Вот код для 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 сообщений.

Есть некоторые проблемы с резьбой? Что я делаю не так?

Я надеюсь, что кто-то поможет мне с этим.

ответ

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

Чтобы отправить сообщение партнеру, просто найдите передатчик для партнера и выполните то же самое, что и выше для однократного подключения.

Надеюсь, это поможет кому-то, кто пытается достичь того же. Там могут быть лучшие способы сделать это. Думаю, мне придется использовать этот подход, пока кто-то не предложит лучшее решение.