| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java EE (J2EE) и Spring > JMS Listener на базе Servlet Container |
| Автор: Girin 17.12.2009, 21:24 |
| Есть проблема - необходимо реализовать аналог Message Driven Bean на базе сервлет контейнера, в моем случае Jetty. То есть наличие полноценного J2EE сервера приложений не подразумевается. В качестве провайдера очереди сообщений на которую нужно настроить слушатель предполагается использовать либо Websphere MQ либо ActiveMQ. Можно установить дополнительно на Jetty реализации EJB контейнеров, такие как OpenEJB, но хотелось бы узнать есть ли другие варианты реализации слушателя очереди сообщений. Каким образом можно реализовать аналог метода onMessage() в контексте вышеозвученного вопроса ? |
| Автор: COVD 18.12.2009, 07:03 |
| http://activemq.apache.org/hello-world.html . В примере HelloWorldConsumer выполняет функцию МДБ. А куда этот код вставлять непринципиально. |
| Автор: Girin 18.12.2009, 11:32 | ||
Да, спасибо интересный вариант. Но в приведенном примере как я понимаю standalone приложение, т.е. запускаемое вне контекста сервера. Есть ли варианты реализовать подобное в виде серверного ПО или можно просто задеплоить пример из ссылки на сервер (сервлет-контейнер) |
| Автор: COVD 18.12.2009, 16:53 | ||
| Это всего лишь простой пример, как создать издателя и потребителя для очереди сообщений ActiveMQ. Если вы хотите, чтобы приложение ( в вашем случае это, очевидно, веб-приложение) получало из очереди сообщения, значит надо в приложение добавить класс, который создаст обьект потребителя (consumer) и зарегистрирует его во внешней очереди. Там должен быть также запущен поток, который в цикле ожидает нового сообщения из очереди:
Метод receive(..) и есть аналог метода onMessage(Message m). |
| Автор: Girin 22.12.2009, 20:58 | ||
Собственно сделал, как вы советовали. То есть создал класс реализующий MessageListener интерфейс, переопределил в нем onMessage(). Создал поток, в методе run() которого инициализирую MQConnectionFactory , MQManager , MQQueue и соотвественно устанавливаю вызовом для MQSession.createConsumer(MyMessageListenerImpl) своего слушателя очереди Сообщения приходящие в очередь нормально обрабатываются, получаются и т.д. Но для постоянной связи с очередью необходимо чтобы тред, в котором устанавливается Consumer для очереди был перситентным, то есть постоянно в запущенном состоянии. Для этого я поставил в конце тела метода run() бесконечный цикл , это приводит к 100% загрузке процессора тредом. Есть ли еще какие то варианты реализации JMS Listener ? Заранее благодарен за помощь |
| Автор: COVD 22.12.2009, 22:39 |
| Для чего вы сделали бесконечный цикл? Если вы используете onMessage(Message m), то этот метод вызывается внешним потоком при получении нового сообщения. Бесконечный цикл здесь не нужен. Если же вы используете Message message = consumer.receive(..); , то, действительно, это надо делать в бесконечном цикле. Но метод receive(..) блокирующий, и поток ждет в методе, пока не придет сообщение. Поэтому 100% занятости cpu здесь не будет. |
| Автор: Girin 23.12.2009, 09:43 | ||
Можно поподробнее про внешний поток? После вызова регистрирующего метода MQSession.createConsumer(MyMessageListenerImpl) слушатель MyMessageListenerImpl(в котором переопределен onMessage()) функционирует до тех пор пока не завершиться поток, зарегистрировавший его. То есть сам по себе отдельно MyMessageListenerImpl не функционирует |
| Автор: COVD 24.12.2009, 17:35 | ||
А какое отношение может иметь к функционированию этого обьекта регистрирующий поток? Обьект MyMessageListenerImpl зарегистрирован, т.е. передана ссылка на него кому-то. У обьекта есть метод onMessage(Message message). Какой-то внешний поток должен вызывать этот метод и передавать в виде аргумента новое сообщение. По определению лисенера. Если у вас после завершения регистрации все умирает, то может вы используете локальные переменные для создаваемых обьектов и они просто становятся добычей gc ? |