Невозможно транслировать на одно соединение, используя среду выполнения Atmosphere - PullRequest
4 голосов
/ 28 декабря 2010

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

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

  1. Global Broadcaster - трансляция на все приостановленные ресурсы.(Все)
  2. Передача на конкретный ресурс (скажем, Партнер)
  3. Передача на текущий ресурс (Сам)

Когда происходит вход в систему, что все делаютМне нужно хранить в сеансе, чтобы добиться такого рода трансляции?

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

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

    globalBroadcaster = new DefaultBroadcaster();

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

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

  4. Вот код для sendMessageToPartner,

private synchronized void sendMessageToPartner(Broadcaster selfBroadcaster, AtmosphereResource<HttpServletRequest, HttpServletResponse> resource,String name, String message) {<br> // this gives the partner's name<br> String partner= (String) resource.getAtmosphereConfig().getServletContext().getAttribute(name + PARTNER_NAME_TOKEN);<br> // get partner's broadcaster<br> Broadcaster outsiderBroadcaster = (Broadcaster) resource<br> .getAtmosphereConfig().getServletContext()<br> .getAttribute(partner);<br> if (outsiderBroadcaster == null) {<br> sendMessage(selfBroadcaster, "Invalid user " + partner);<br> return;<br> }<br> // broadcast to partner<br> outsiderBroadcaster.broadcast(" **" + message);

Надеюсь, я предоставил всю необходимую информацию.При необходимости могу предоставить больше информации.

Проблема в том, что глобальное сообщение отправлено.При отправке сообщения партнеру, иногда оно блокируется, сообщение вообще не принимается клиентом.Это происходит последовательно после 3-4 сообщений.

Есть проблема с многопоточностью?Что я делаю не так?

Надеюсь, кто-нибудь поможет мне с этим.

1 Ответ

6 голосов
/ 30 декабря 2010

Хорошо, я понял, как этого можно достичь с помощью среды Atmosphere. Сначала я обновил SNAPSHOT до 0,7, но я думаю, что та же логика будет работать и с 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");

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

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

...