Как я могу отправлять сообщения XMPP после успешной транзакции?

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

У меня есть зарегистрированный ServletContextListener, который отправляет мои пакеты xmpp (библиотека smack). Когда я получаю пакет, я нахожу свой диспетчерский сеансовый компонент с отслеживанием состояния и начинаю обработку запроса.

public void processPacket(Packet packet) {
    try{
        if(packet instanceof RawRequest){
            DispatchIQService service = Core.lookup(DispatchIQService.class);
            service.process(connection, (RawRequest)packet);
            // sending of the messages should happen here, because transaction completed successful.
        }else{
            log.debug("Packet ignored: " + packet.toXML());
        } 
    }catch(Exception e){
        log.error(e, e);
    }
}
  1. Как я могу собирать эти сгенерированные сообщения во время рабочего процесса через несколько компонентов? Я бы вернул этот список из компонента отправки и впоследствии отправил бы сообщения. Моим простым решением было бы маршрутизировать список, в который я добавляю свои сообщения, но есть ли более элегантный способ?

  2. У меня есть ресурс XMPP (список http://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware/smack/Roster.html), к которому у меня есть доступ со всех компонентов. Как я могу это сделать? Хранить его в статической переменной и синхронизировать доступ к нему звучит не очень хорошо.


person mkuff    schedule 06.09.2011    source источник


Ответы (1)


Маркус, я не гуру J2EE, но для ваших целей рекомендую взглянуть на JMS. Это поможет вам реализовать подход, основанный на сообщениях. Что касается меня, я использовал систему RabbitMQ. Это был отличный опыт, но для запуска системы требуется дополнительное программное обеспечение.

person Andrey Atapin    schedule 06.09.2011
comment
Проблема в том, что в случае ошибки и отката я не хочу отправлять это сгенерированное сообщение и должен удалить его из очереди. Могу ли я сделать это с помощью jms? У меня нет опыта. - person mkuff; 06.09.2011
comment
Извините, я могу вас неправильно понять... Вы имеете в виду, что вы не хотите, чтобы сообщение было доставлено в случае ошибки или отката? - person Andrey Atapin; 06.09.2011
comment
Правильный. :) Сообщения следует отправлять только после успешного завершения транзакции. После того, как будет достаточно метода service.process(). Поэтому моим прямым решением было бы передать список через рабочий процесс и добавить в него сообщения. Затем диспетчерская служба возвращает его, и я отправляю сообщения. - person mkuff; 06.09.2011
comment
Что мешает вам отправлять JMS-сообщение строго в случае успешного выполнения service.process()? - person Andrey Atapin; 06.09.2011
comment
Когда очередь предназначена исключительно для моего потока, я думаю, она будет работать нормально. Это возможно? - person mkuff; 06.09.2011
comment
Если вы отправляете сообщения из одного потока, то у вас нет проблем. Если вы хотите отправлять сообщения из нескольких потоков, вам придется синхронизировать доступ к некоторому объекту (в случае RabbitMQ таким объектом является канал). Но там тоже не так много работы (насколько я помню, даже простой синхронизированный блок работает нормально). Обратите внимание, что фактическая очередь принадлежит не JVM, а реализации службы обмена сообщениями, поэтому вам нужно самостоятельно синхронизировать Java-объект - person Andrey Atapin; 06.09.2011