A Program to Read a Message


The next program, receive.java, reads and prints out the contents of the message being published from the send program described in A Hello World! Program.

Step 4

Enter or copy the receive.java program

As before, enter this program interactively using your favorite editor, or copy it from the receive.java file.

This is the receive.java program:

//---------------------------------------------------- 
// Program 2: receive.java 
 
1 import java.io.*; 
2 import com.smartsockets.*; 
 
3 public class receive { 
 
4   public static void main(String[] argv) { 
5     TipcMsg msg = null; 
6     String text = null; 
 
7     TipcSrv srv = TipcSvc.getSrv(); 
      try { 
8       srv.setSubjectSubscribe("/ss/tutorial/lesson1", true); 
9       msg = srv.next(TipcDefs.TIMEOUT_FOREVER); 
 
10      msg.setCurrent(0); 
11      text = msg.nextStr(); 
12    } catch (TipcException e) { 
13      Tut.fatal(e); 
      } // try-catch 
 
14  System.out.println("Text from INFO message = " + text); 
    } // main 
  } // receive 

As with the sending program, notice how the receiving program consists of so few lines of code. Compare this with a similar program written using pipes, sockets, or shared memory. SmartSockets programs are typically much shorter than those developed with traditional low-level technologies and are instantly able to leverage the power of the publish-subscribe paradigm.

Let’s take a look at the key lines of this program:

Line 2
The SmartSockets Java package is imported. This step is required.
Line 7
A reference to the RTserver object is placed in the srv object.
Line 8
Subscribing to the /ss/tutorial/lesson1 subject allows receipt of messages published by the send program.
Line 9
The srv object’s next method is used to wait for a message to be received. This line blocks forever, as indicated by the TipcDefs.TIMEOUT_FOREVER parameter. (The next method takes only one parameter, the time in seconds to wait.)
Line 10
Now that a message has been received into the msg object, the setCurrent method is used to position the field pointer. Note that the first data field of the message is specified by the value 0.
Line 11
The string data contained in the message is extracted with the nextStr method and copied into the text String object.
Line 14
The text data is printed on the console with the println method.

Step 5

Compile the receiving program

After you write the program, you need to compile it:

$ javac receive.java  

Running the Application

Now that both the sending and receiving programs have been created and compiled, you can run the complete application to see if the message is successfully transmitted.

Step 6

Start the RTserver

Two windows need to be open, both set to the working directory, to see the application properly. In one window, start RTserver:

$ rtserver -check 

On platforms that support both 32- and 64-bit, use the rtserver64 command to run the 64-bit version of the rtserver script.

Specifying the -check argument starts the non-optimized version of RTserver, which performs additional validation and checking. The optimized version is faster because there is no checking, but it is much harder to diagnose a problem. During all your development and testing, you should run RTserver with the checking turned on. Even in your production environment, you might prefer to run the check version of RTserver. The optimized version is best for enterprise applications where speed is the most important factor.

Step 7

Start the sending program

Start the sending program in the other window:

 $ java send 

Step 8

Start the receiving program

To read and output the message, start the receiving program using this command in the second window:

$ java receive 

The receiving program is waiting for a message. This is because the sending program was executed first. It sent its message, and because the receiving program had not yet been started, there were no subscribers wishing to receive the message. RTserver does not send out messages if there are no processes available to receive them.

Step 9

Start the sending program again

This time, start the sending program while the receiving program is already running. Go back to the first window and re-execute the sending program. (Remember, the receiving program is still running and waiting for the message.)

$ java send 

This output is displayed in the window where the receiving program is running:

Text from INFO message = Hello World! 

This indicates the message was read, and its field was accessed and displayed properly.

An important lesson here is that synchronizing processes at startup is critical. Make sure your receiving processes are started first. This is a common error for first-time developers of network programs.

In just a short time, you have written your first successful SmartSockets application in Java!

What’s Going On

Notice that nowhere do we call the constructor for TipcSrv or TipcMsg, despite the obvious fact that instances of each class are being created. Instead, the TipcSvc class is used to "get" instances of each. Looking at the online reference, notice that TipcSrv and TipcMsg aren’t classes at all. They are interfaces. Why aren’t we creating an instance of TipcSvc?

This concept is known as the abstract factory pattern. In this model, instances of classes aren’t created directly. Instead, a factory class is used to create them indirectly. TipcSvc is that factory class. You never have to create an instance of TipcSvc because all of the methods in it are static. When you create a message with TipcSvc.createMsg, it creates an instance of a non-public class that implements the TipcMsg interface and returns a reference to that class to your program, which you manipulate through the abstract TipcMsg interface. The abstract factory model allows SmartSockets developers more freedom in altering the structure of the library without impacting end-user code. The TipcMsg interface could be implemented by several classes, or only one. The inheritance hierarchy can be rearranged, and classes could be removed or renamed, without affecting your code. Indeed, due to Java dynamic linking, you shouldn’t even have to recompile your code when such changes are made.

Also note that the online reference does not list the methods send or flush under TipcSrv. This is because TipcSrv extends TipcConnClient, and most of the methods dealing with sending and reading messages are handled by that class.

Finally, it’s important to note that TipcSvc.getSrv does not actually create a connection to RTserver. SmartSockets uses a "lazy" scheme when making connections, deferring the process until the connection is actually required. For the sender, this doesn’t happen until flush is called. The receiver creates a new connection when next is called. You can also explicitly create a new connection with the TipcSrv.create method.


TIBCO SmartSockets™ Java Library User’s Guide and Tutorial
Software Release 6.8, July 2006
Copyright © TIBCO Software Inc. All rights reserved
www.tibco.com