Search code examples
pythonpython-2.7message-queuestomp

Retain Messages until a Subscription is Made using Python + Stomp


I am currently writing two scripts to subscribe to a message server using the stomp client library, write.py to write data and read.py to get data.

If I start read.py first and then run write.py, write.py receives the messages correctly.

However, if I run write.py first and then run read.py, read.py does not retrieve any messages previously sent to the server.

Below are relevant parts of the scripts.

How can I achieve that messages put into the queue by write.py are being retained until read.py subscribes and retrieves them?

write.py

def writeMQ(msg):
    queue = '/topic/test'
    conn = stomp.Connection(host_and_ports=[(MQ_SERVER, MQ_PORT)])
    try:
        conn.start()
        conn.connect(MQ_USER, MQ_PASSWD, wait=True)
        conn.send(body=msg, destination=queue, persistent=True)
    except:
        traceback.print_exc()
    finally:
        conn.disconnect()

    return

read.py

class MyListener(stomp.ConnectionListener):    
    def on_error(self, headers, message):    
        print ('received an error {0}'.format(message))    

    def on_message(self, headers, message):    
        print ('received an message {0}'.format(message))    


def readMQ():                                                
    queue = '/topic/test'     
    conn = stomp.Connection(host_and_ports=[(MQ_SERVER, MQ_PORT)])    
    try:                                                              
        conn.set_listener("", MyListener())                           
        conn.start()                                                  
        conn.connect(MQ_USER, MQ_PASSWD, wait=True)    

        conn.subscribe(destination=queue, ack="auto", id=1)                       


        stop = raw_input()                  
    except:                   
        traceback.print_exc()    
    finally:                     
        conn.disconnect()        

    return                   

Solution

  • The problem is that the messages are being sent to a topic.

    The Apollo Documentation describes the difference between topics and queues as follows:

    Queues hold on to unconsumed messages even when there are no subscriptions attached, while a topic will drop messages when there are no connected subscriptions.

    Thus, when read.py is startet first and listening, the topic recognizes the subscription and forwards the message. But when write.py is startet first the message is dropped because there is no subscribed client.

    So you can use a queue instead of a topic. If the server is able to create a queue silently simply set

    queue = '/queue/test' .
    

    I don't know which version of stomp is being used, but I cannot find the parameter

    send(..., persistent=True) .
    

    Anyway persisting is not the right way to go since it still does not allow for messages to simply be retained for a later connection, but saves the messages in case of a server failure.

    You can use the

    retain:set
    

    header for topic messages instead.