5 Replies Latest reply on Aug 24, 2011 8:46 AM by ataylor

    createDurableSubscriber from JavaEE context

    agattik

      Hello,

       

      I am developing an application where several clients are subscribing to a JMS topic, via a Servlet in JBoss AS 6.

       

      My idea was to assign each client a subscription id, and create one durable subscriber on the topic per client.

       

      However, creating the durable subscriber results in:

       

      javax.jms.InvalidClientIDException: Cannot create durable subscription - client ID has not been set

              at org.hornetq.jms.client.HornetQSession.createConsumer(HornetQSession.java:562) [:6.0.0.Final]

              at org.hornetq.jms.client.HornetQSession.createDurableSubscriber(HornetQSession.java:481) [:6.0.0.Final]

       

      I cannot set the session's client ID, however, as this is forbidden in a Java EE context.

       

      I do not see anywhere in the Java EE spec that Session.createDurableSubscriber is forbidden however. Is there a way to achieve this with HornetQ?

        • 1. Re: createDurableSubscriber from JavaEE context
          ataylor

          you can't create the client id on a connection because it is pooled and shared between JEE components. It sounds to me as if you need to rethink your application, firing a servlet which then calls receive for a message doesnt sound right. What is it exactly you are trying to acheive, from an application pov that is

          • 2. Re: createDurableSubscriber from JavaEE context
            agattik

            Thanks for the reply. I want to allow a number of clients to connect to a JMS topic, by first performing a subscription request (that would lead to the creation of a durable subscriber per client), then issue regular HTTP requests to fetch pending messages. It seemed a good idea to leverage the message queue rather than developing something from scratch.

            • 3. Re: createDurableSubscriber from JavaEE context
              ataylor

              Although your allowed to use consumers in a web component its not good practice, this is becasue a blocking receive (or even a receive with a timeout) will tie up server resources.

               

              I understood from a code pov what you are trrying to acheive i meant from a business pov so i could suggest an alternative solution. You could consume message asynchronously using MDB's or if your tied to http you could use the http transport.

              • 4. Re: createDurableSubscriber from JavaEE context
                agattik

                Thanks a lot for taking the time to help me. I would like to allow a number of client applications of various kinds and platforms, to subscribe to a topic, providing a filter that would exceed the rather basic filtering capabilities of the JMS API (although I could probably squeeze my requirements into it if need be). The clients would then retrieve the messages via HTTP (as it is the most easily accessible transport on a heterogeneous environment).

                 

                So my idea was that once a client subscribes, a servlet creates a durable subscriber with an id assigned to the client. Then, when the client connects with a retrieval query, a durable subscriber with the same id would be created. In my understanding, this would allow to retrieve all pending messages (with a receiveNoWait loop), do some custom filtering and return them to the client.

                 

                A useful addition to this would then be to allow push or long-poll capability, but as you point out it should be done without hogging threads. However, that also looks difficult to implement. I could write an async servlet and have an MDB receive messages and return the response, but I would then only send back a single message at a time. I could also have a thread pool doing receiveNoWait, but that might cause a significant delay between the message being posted and the response being sent. In my dreams, I could also dynamically create an MDB per subscription, but that is clearly impossible...

                 

                A possibility might be to create a queue per subscriber, and have an MDB dispatch messages to those queues. Is it feasible to manage queues dynamically in that manner, or would that cause too much overhead?

                 

                So my business problem is pretty general. How can I allow dynamic clients (say, a chat room in a web browser) to reliably subscribe to a topic via HTTP, when the message queue is accessed through a Java EE container? The HornetQ HTTP transport is powerful but I'd like to avoid tying in my client apps to one particular provider.

                • 5. Re: createDurableSubscriber from JavaEE context
                  ataylor

                  A possibility might be to create a queue per subscriber, and have an MDB dispatch messages to those queues. Is it feasible to manage queues dynamically in that manner, or would that cause too much overhead?

                  Internally a subscriber uses a queue anyway.

                   

                  So my business problem is pretty general. How can I allow dynamic clients (say, a chat room in a web browser) to reliably subscribe to a topic via HTTP, when the message queue is accessed through a Java EE container? The HornetQ HTTP transport is powerful but I'd like to avoid tying in my client apps to one particular provider.

                  The stomp websockets example does exactly this, altho currently web sockets arent available in all browsers.

                   

                  Rather than use JMS, you could use the core API, the client could create the durable queue and then the consumer and if your servlet calls receiveNoWait then this wouldnt lock threads.