Working With Messages


Typically, three steps are required when constructing a message:

  1. Create a message of a particular type (TipcMsgCreate, TipcMsgClone)
  1. Set the properties of the message (TipcMsgSet*)
  2. Append fields to the message data (TipcMsgAppend*)

There are many different types of fields that can be appended to a message’s data. These field types include four sizes of integers, three sizes of real numbers, character strings, XML, and arrays of the scalar field types, such as an array of four-byte integers. These field types are listed the messages chapter of the TIBCO SmartSockets User’s Guide. Messages themselves can even be used as fields within other container messages; this allows operations such as large transactions to be represented with a single message. Once a message is constructed, it can be published to other processes using the TIBCO SmartSockets function TipcSrvMsgSend.

Next you slightly alter your example from Lesson 2 and replace the call to TipcSrvMsgWrite with calls to the TIBCO SmartSockets API for working with messages.

Step 1

Copy the send.c program

Copy the file send.c into your working directory. Under Windows you also need the makefile sendw32m.mak in your working directory. Use the command chmod 777 * to allow write access to the sample programs you copy.

The contents of the file send.c are:

   /* send.c - send a INFO message with "Hello World!" */ 
   /* $RTHOME/examples/smrtsock/tutorial/lesson3/send.c */ 
 
1   #include <rtworks/ipc.h> 
 
2   int main(int argc, char **argv) 
    { 
3     T_OPTION option; 
4     T_IPC_MSG msg; 
 
      /* Set the name of the project */ 
5     option = TutOptionLookup("project"); 
6     TutOptionSetEnum(option, "smartsockets"); 
 
      /* Connect to RTserver */ 
7     if (!TipcSrvCreate(T_IPC_SRV_CONN_FULL)) { 
8       TutOut("Could not connect to RTserver!\n"); 
9       TutExit(T_EXIT_FAILURE); 
      } 
 
       /* Create a message of type INFO */ 
10     msg = TipcMsgCreate(TipcMtLookupByNum(T_MT_INFO)); 
 
       /* Set the destination subject of the message */ 
11     TipcMsgSetDest(msg, "/tutorial/lesson3"); 
 
       /* Build the message with one string field: "Hello World!" */ 
12     TipcMsgAppendStr(msg, "Hello World!"); 
 
       /* Send the message */ 
13     TipcSrvMsgSend(msg, TRUE); 
14     TipcSrvFlush(); 
 
       /* Destroy the message */ 
15     TipcMsgDestroy(msg); 
 
16     TipcSrvDestroy(T_IPC_SRV_CONN_NONE); 
    } /* main */ 

Some things you should notice about this program are:

Lines 7-9
Check to see if the program properly connected to RTserver, and if it did not, exit out.
Lines 10-13
The call to TipcSrvMsgWrite has been replaced with calls to these TIBCO SmartSockets message functions:
  • TipcMsgCreate to create a new message (that can be reused)
  • TipcMsgSetDest to set the destination of the message to the /tutorial/lesson3 subject.
  • TipcMsgAppendStr to add the "Hello World!" string to the data part of the message.
  • TipcSrvMsgSend to send the message to RTserver to be delivered to all processes subscribing to the /tutorial/lesson3 subject.
Line 15
Destroys the message because you are not reusing it.

Step 2

Compile and link the sending program

Compile and link the sending program.

Before running this program to be sure it works, you need to modify your receiving program so that it subscribes to messages sent to the /tutorial/lesson3 subject.

Step 3

Edit the receiving program from Lesson 2 or copy it

Edit the receiving program from the previous lesson so that it subscribes to the /tutorial/lesson3 subject by changing this line:

TipcSrvSubjectSetSubscribe("/tutorial/lesson2", TRUE); 

to

TipcSrvSubjectSetSubscribe("/tutorial/lesson3", TRUE); 

Or copy it from /tutorial/lesson3/receive.c. Under Windows you also need the makefile recvw32m.mak in your working directory. The contents of the file receive.c are:

   /* receive.c - read an INFO message and print out its contents */ 
   /* $RTHOME/examples/smrtsock/tutorial/lesson3/receive.c */ 
 
1  #include <rtworks/ipc.h> 
 
2  int main(int argc, char **argv) 
   { 
3    T_OPTION option; 
4    T_IPC_MSG msg; 
5    T_STR msg_text; 
 
6    option = TutOptionLookup("project"); 
7    TutOptionSetEnum(option, "smartsockets"); 
 
8    if (!TipcSrvCreate(T_IPC_SRV_CONN_FULL)) { 
9      TutOut("Could not connect to RTserver!\n"); 
10     TutExit(T_EXIT_FAILURE); 
     }/* if */ 
 
11   TipcSrvSubjectSetSubscribe("/tutorial/lesson3", TRUE); 
 
12   msg = TipcSrvMsgNext(T_TIMEOUT_FOREVER); 
 
13   TipcMsgSetCurrent(msg, 0); 
14   TipcMsgNextStr(msg, &msg_text); 
  
15   TutOut("Text from INFO message = %s\n", msg_text); 
 
16   TipcSrvDestroy(T_IPC_SRV_CONN_NONE); 
   } /* main */ 

As you can see, lines 13 and 14 make calls to the TIBCO SmartSockets message API. To access the data part of a message, you must set the current field of the message to the one you want to extract. By default, the fields of a message are accessed in the order they are appended. On line 13, the call to TipcMsgSetCurrent sets the current field of the message to zero (the first field). On Line 14, the call to TipcMsgNextStr accesses the string field of the message. The fields of a message are accessed by making calls to the TIBCO SmartSockets TipcMsgNextType functions, where Type is replaced by the field type, such as Str for string. Throughout this tutorial you use these API functions to access the fields of your messages. See the TIBCO SmartSockets Application Programming Interface reference for details on the access functions.

Because TIBCO SmartSockets comes out of the shipping box with pre-defined structured message types, it provides you with a complete and extensive API for operating on messages. Most other messaging products only provide a mechanism for moving a block of memory, and it is then up to you to provide the mechanisms for creating, building, accessing, and destroying the messages.

Step 4

Compile and link the receiving program

Compile and link the receiving program.

Step 5

Start the RTserver

To prove everything is still working, start the receiving and sending programs in separate windows as you did in Lesson 2. If RTserver is not running, start it:

UNIX:
$ rtserver 
OpenVMS:
$ run rtserver 
Windows:
$ rtserver 

On platforms that support both 32- and 64-bit, use the rtserver64 command to run the 64-bit RTserver.

Step 6

Start the receiving program

Then start the receiving program:

UNIX:
$ receive.x 
OpenVMS:
$ run receive 
Windows:
$ receive 

Step 7

Start the sending program

Then, after a few moments, start the sending program:

UNIX:
$ send.x 
OpenVMS:
$ run send 
Windows:
$ send 

You should see this message output from the receiving program:

Text from INFO message = Hello World! 

To get a better feel for working with the TIBCO SmartSockets API for building and sending messages, enhance your sending program to send a NUMERIC_DATA message. The data part of a NUMERIC_DATA message consists of one or more variable-value pairs, where a variable is a text string and a value is a floating point number.

Step 8

Copy the send2.c program

Copy the file send2.c into your working directory. Under Windows copy the makefile snd2w32m.mak into your working directory. The contents of the file send2.c are:

    /* send2.c - send a NUMERIC_DATA message with 3 variables set */ 
    /* $RTHOME/examples/smrtsock/tutorial/lesson3/send2.c */ 
 
1   #include <rtworks/ipc.h> 
 
2   int main(int argc, char **argv) 
    { 
3     T_OPTION option; 
4     T_IPC_MSG msg; 
 
      /* Set the name of the project */ 
5     option = TutOptionLookup("project"); 
6     TutOptionSetEnum(option, "smartsockets"); 
 
      /* Connect to RTserver */ 
7     if (!TipcSrvCreate(T_IPC_SRV_CONN_FULL)) { 
8       TutOut("Could not connect to RTserver!\n"); 
9       TutExit(T_EXIT_FAILURE); 
      }/* if */ 
 
      /* Create a message of type NUMERIC_DATA */ 
10    msg = TipcMsgCreate(TipcMtLookupByNum(T_MT_NUMERIC_DATA)); 
 
      /* Set the destination subject of the message */ 
11    TipcMsgSetDest(msg, "/tutorial/lesson3"); 
 
      /*  
       * Build a NUMERIC_DATA message with 3 variable-value pairs,  
       *   set as follows: (X, 10.0), (Y, 20.0), and (Z, 30.0)  
       */ 
12    TipcMsgAppendStr(msg, "X"); 
13    TipcMsgAppendReal8(msg, 10.0);  
14    TipcMsgAppendStr(msg, "Y"); 
15    TipcMsgAppendReal8(msg, 20.0);   
16    TipcMsgAppendStr(msg, "Z"); 
17    TipcMsgAppendReal8(msg, 30.0); 
 
      /* Send the message */ 
18    TipcSrvMsgSend(msg, TRUE); 
19    TipcSrvFlush(); 
 
      /* Destroy the message */ 
20    TipcMsgDestroy(msg); 
 
      /* Disconnect from RTserver */ 
21    TipcSrvDestroy(T_IPC_SRV_CONN_NONE); 
 
    } /* main */ 

Some things you should notice about this program:

Line 10
Now creates a message of type NUMERIC_DATA instead of type INFO.
Lines 12-17
The call to TipcMsgAppendStr is replaced with multiple calls to TipcMsgAppendStr and TipcMsgAppendReal8 to build the data part of the message.

Step 9

Compile and link the send2.c program

Compile and link the send2.c program.

You now need to modify your receiving program so that it can read and print out the contents of the NUMERIC_DATA message you are sending.

Step 10

Copy the receive2.c program

Copy the file receive2.c into your working directory. Under Windows copy the makefile rcv2w32m.mak into your working directory. The contents of the file receive2.c is:

    /* receive2.c - read a NUMERIC_DATA message and print contents */ 
   /* $RTHOME/examples/smrtsock/tutorial/lesson3/receive2.c */ 
 
1  #include <rtworks/ipc.h> 
 
2  int main(int argc, char **argv) 
   { 
3    T_OPTION option; 
4    T_IPC_MSG msg; 
5    T_STR var_name; 
6    T_REAL8 var_value; 
   
     /* Set the name of the project */ 
7    option = TutOptionLookup("project"); 
8    TutOptionSetEnum(option, "smartsockets"); 
 
     /* Connect to RTserver */ 
9    if (!TipcSrvCreate(T_IPC_SRV_CONN_FULL)) { 
10     TutOut("Could not connect to RTserver!\n"); 
11     TutExit(T_EXIT_FAILURE); 
     } 
 
     /*  
      * Subscribe to receive any messages sent to the  
      * "/tutorial/lesson3" subject  
      */ 
12    TipcSrvSubjectSetSubscribe("/tutorial/lesson3", TRUE); 
 
      /* Get the next message from the message queue */ 
13    msg = TipcSrvMsgNext(T_TIMEOUT_FOREVER); 
 
      /* 
      * You now have a message to work with. The following call sets  
      * the message pointer (i.e., the current field) to the first  
      * field in the data part of the message  
      */ 
14    TipcMsgSetCurrent(msg, 0); 
 
      /*  
       * Move through the data part of the message; print out each  
       *   variable name, variable value pair in the message  
       */ 
15    TutOut("Contents of NUMERIC_DATA message:\n"); 
16    TutOut("---------------------------------\n"); 
 
17    while (TipcMsgNextStr(msg, &var_name)) { 
18      TipcMsgNextReal8(msg, &var_value); 
19      TutOut("Var name = %s, Var Value = %s\n", var_name,  
              TutRealToStr(var_value)); 
20    } 
 
      /* Disconnect from RTserver */ 
21    TipcSrvDestroy(T_IPC_SRV_CONN_NONE); 
 
    } /* main */ 

As you can see, lines 17 and 18 make calls to the TIBCO SmartSockets message API to access the data part of the NUMERIC_DATA message. The call to TipcMsgNextStr retrieves the variable name and the call to TipcMsgNextReal8 retrieves the variable value. When TipcMsgNextStr fails, there are no more fields to access in the message. See the TipcNext* functions in the TIBCO SmartSockets Application Programming Interface reference for more details.

Step 11

Compile and link the new receiving program

Now compile and link your new receiving program.

Step 12

Start the new receiving program

To demonstrate everything is still working, start the new receiving and sending programs in separate windows as you did earlier. First start the new receiving program:

UNIX:
$ receive2.x 
OpenVMS:
$ run receive2 
Windows:
$ receive2 

Step 13

Start the new sending program

Then, after a few moments, start the new sending program:

UNIX:
$ send2.x 
OpenVMS:
$ run send2 
Windows:
$ send2 

You should see this message output from the new receiving program:

Contents of NUMERIC_DATA message: 
--------------------------------- 
Var name = X, Var Value = 10 
Var name = Y, Var Value = 20 
Var name = Z, Var Value = 30 

Because many TIBCO SmartSockets applications work with variable-value pairs as found in the NUMERIC_DATA message, TIBCO SmartSockets offers two convenience functions for writing and reading these pairs: TipcMsgAppendStrReal8 and TipcMsgNextStrReal8. Each of these can operate on a variable-value pair with a single call.

Step 14

Copy the send3.c program or edit the send2.c program

Copy the program send3.c into your working directory or replace lines 12-17 of send2.c with these calls:

TipcMsgAppendStrReal8(msg, "X", 10.0); 
TipcMsgAppendStrReal8(msg, "Y", 20.0); 
TipcMsgAppendStrReal8(msg, "Z", 30.0); 

Step 15

Copy the makefile snd3w32m.mak

Under Windows copy the makefile snd3w32m.mak into your working directory.

Step 16

Copy the receive3.c program or edit the receive2.c program

Copy the program receive3.c into your working directory or modify lines 17-20 of receive2.c to retrieve variable-value pairs with one call:

while (TipcMsgNextStrReal8(msg, &var_name, &var_value)) { 
  TutOut("Var name = %s, Var Value = %s\n", var_name,  
          TutRealToStr(var_value)); 
} 

Step 17

Copy the makefile rcv3w32m.mak

Under Windows copy the makefile rcv3w32m.mak into your working directory.

Step 18

Compile and link the receive3. c and send3.c programs

Compile and link the receive3.c and send3.c programs.

Step 19

Start the new receiving program

Start the new receiving and sending programs in separate windows as you did earlier. First start the new receiving program:

UNIX:
$ receive3.x 
OpenVMS:
$ run receive3 
Windows:
$ receive3 

Step 20

Start the new sending program

Then, after a few moments, start the new sending program:

UNIX:
$ send3.x 
OpenVMS:
$ run send3 
Windows:
$ send3 

You should see this message output from the new receiving program:

Contents of NUMERIC_DATA message: 
--------------------------------- 
Var name = X, Var Value = 10 
Var name = Y, Var Value = 20 
Var name = Z, Var Value = 30 


TIBCO SmartSockets™ Tutorial
Software Release 6.8, July 2006
Copyright © TIBCO Software Inc. All rights reserved
www.tibco.com