Sending Delayed Messages

The standard JMS API's does not define a mechanism for sending delayed messages. However, certain types of applications require that messages can be sent to the messaging system, but not delivered to the consumers of a destination until some time has expired.

The Novell exteNd Messaging Platform's JMS defines the JMS_jbmq_Delay message property, which allows messages to be delayed. Persistent messages are still stored reliably when they enter the JMS server, but the server will not forward the message until the relative delay time has expired.

Below is the source code for the Scheduler class:

package delay;
                                                                           
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
                                                                           
import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
                                                                           
import javax.naming.InitialContext;
                                                                           
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.Message;
import javax.jms.TextMessage;
import javax.jms.QueueSession;
import javax.jms.QueueSender;
import javax.jms.MessageListener;
import javax.jms.QueueReceiver;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
                                                                           
/**
   This class ilustrates how to use the JMS_jbmq_Delay property to
   send delayed messages.
 */
                                                                           
public class Scheduler
{
    QueueReceiver receiver;
                                                                           
    JFrame     frame    = new JFrame("Scheduler");
    JButton    send     = new JButton("Send");
    JTextArea  incoming = new JTextArea();
    JTextField message  = new JTextField();
    JTextField delay    = new JTextField();
                                                                           
    public static void main(String[] args) throws Exception
    {
    |   Scheduler scheduler = new Scheduler();
    }
                                                                           
    public Scheduler() throws Exception
    {
    |   // create sender and receiver
    |   InitialContext ctx = new InitialContext();
    |   QueueConnectionFactory factory = (QueueConnectionFactory)
    |       ctx.lookup("queue/connectionFactory");
    |   final Queue queue = (Queue) ctx.lookup("queue/queue0");
    |   QueueConnection conn = factory.createQueueConnection();
    |   final QueueSession session = conn.createQueueSession(false,
    |       Session.AUTO_ACKNOWLEDGE);
    |   final QueueSender sender = session.createSender(queue); 
    |   receiver = session.createReceiver(queue);
    |                                                                      
    |   // create the gui
    |   incoming.setEditable(false);
    |                                                                      
    |   JPanel panel = new JPanel(new BorderLayout());
    |                                                                      
    |   JPanel p1 = new JPanel();
    |   JPanel p2 = new JPanel(new GridLayout(2,1));
    |   JPanel p3 = new JPanel(new BorderLayout());
    |   p3.add(new JLabel("Message:"), BorderLayout.WEST);
    |   message.setColumns(50);
    |   p3.add(message);
    |   p2.add(p3);
    |   JPanel p4 = new JPanel(new BorderLayout());
    |   p4.add(new JLabel("Delay:"), BorderLayout.WEST);
    |   message.setColumns(10);
    |   p4.add(delay);
    |   p2.add(p4);
    |   JPanel p5 = new JPanel();
    |   p5.add(send);
    |   p1.add(p2);
    |   panel.add(p1);
    |   panel.add(p5, BorderLayout.EAST);
    |                                                                      
    |   // replace receiver according to blocked user
    |   send.addActionListener(new ActionListener() {
    |   |   public void actionPerformed(ActionEvent ev) {
    |   |   |   try {
    |   |   |   |   TextMessage msg;
    |   |   |   |   msg = session.createTextMessage(message.getText());
    |   |   |   |   long time = Long.parseLong(delay.getText());
    |   |   |   |   msg.setLongProperty("JMS_jbmq_Delay", time*1000);
    |   |   |   |   sender.send(msg);
    |   |   |   } catch (Exception ex) {
    |   |   |   |   ex.printStackTrace();
    |   |   |   }
    |   |   }
    |   });
    |                                                                      
    |   receiver.setMessageListener(new MessageListener() {
    |   |   public void onMessage(Message m) {
    |   |   |   try {
    |   |   |   |   TextMessage msg = (TextMessage) m;
    |   |   |   |   incoming.append(msg.getText());
    |   |   |   } catch (Exception ex) { ex.printStackTrace(); }
    |   |   }
    |   });
    |                                                                      
    |   // now start the connection
    |   conn.start();
    |                                                                      
    |   // setup rest of gui
    |   JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
    |       panel, incoming);
    |   split.setOneTouchExpandable(true);
    |   split.setDividerLocation(205);
    |                                                                      
    |   frame.getContentPane().setLayout(new BorderLayout());
    |   frame.getContentPane().add(split);
    |   frame.setSize(new Dimension(400,300));
    |   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    |   frame.setVisible(true);
    }
}

The Scheduler application creates a GUI with an area for entering delayed messages and an area for displaying received messages. To send a message, you simply type the text and message delay and click the "send" button. Incoming messages appear in the bottom part of the GUI when the delay expires.



Copyright © 2003, 2004 Novell, Inc. All rights reserved. Copyright © 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved.