Polling for Information at Regular Intervals


The last example of this lesson shows you how to poll for information at a regular time interval.

Step 18

Copy the polltraf.c program

First, copy the polling traffic program, polltraf.c, into your working directory. Under Windows copy the makefile poltw32m.mak into your working directory. The contents of the file polltraf.c are:

    /* polltraf.c - Output message traffic info every 10 seconds */ 
    /* $RTHOME/examples/smrtsock/tutorial/lesson5/polltraf.c */ 
 
1   #include <rtworks/ipc.h> 
2   static void T_ENTRY DefaultReceiveFunc(T_IPC_CONN conn, 
                            T_IPC_CONN_PROCESS_CB_DATA data, 
                            T_CB_ARG arg); 
3   static void T_ENTRY ProcessTrafficPoll(T_IPC_CONN conn, 
                            T_IPC_CONN_PROCESS_CB_DATA data, 
                            T_CB_ARG arg); 
 
    /* =========================================================== */ 
    /*..DefaultReceiveFunc -- default callback */ 
4   static void T_ENTRY DefaultReceiveFunc 
    ( 
     T_IPC_CONN conn, 
     T_IPC_CONN_PROCESS_CB_DATA data, 
     T_CB_ARG arg 
    ) 
    { 
5   TipcMsgPrintError(data->msg); 
    } /* DefaultReceiveFunc */ 
 
    /* =========================================================== */ 
    /* ProcessTrafficPoll - callback to access and output a        */ 
    /*                  MON_CLIENT_MSG_TRAFFIC_POLL_RESULT message */ 
6   static void T_ENTRY ProcessTrafficPoll 
    ( 
     T_IPC_CONN conn, 
     T_IPC_CONN_PROCESS_CB_DATA data, 
     T_CB_ARG arg 
    ) 
    { 
7     T_IPC_MSG msg = data->msg; 
8     T_STR client_name; 
9     T_INT4 total_msg_recv; 
10    T_INT4 total_msg_send; 
11    T_INT4 total_byte_recv; 
12    T_INT4 total_byte_send; 
13    T_INT8 total_msg_recv_8; 
14    T_INT8 total_msg_send_8; 
15    T_INT8 total_byte_recv_8; 
16    T_INT8 total_byte_send_8; 
 
     /* Set current field */ 
17   TipcMsgSetCurrent(msg, 0); 
 
     /* Get the fields from the message */ 
18   TipcMsgRead(data->msg, T_IPC_FT_STR, &client_name, 
                            T_IPC_FT_INT4, &total_msg_recv, 
                            T_IPC_FT_INT4, &total_msg_send, 
                            T_IPC_FT_INT4, &total_byte_recv, 
                            T_IPC_FT_INT4, &total_byte_send, 
                            NULL); 
 
19   TutOut("Summary of message traffic for client <%s>\n", 
            client_name); 
20   if (TipcMsgRead(data->msg, 
         T_IPC_FT_INT8, &total_msg_recv_8, 
         T_IPC_FT_INT8, &total_msg_send_8, 
         T_IPC_FT_INT8, &total_byte_recv_8, 
         T_IPC_FT_INT8, &total_byte_send_8, 
         NULL)) { 
       /* Print out the new information received */ 
21     TutOut("   (Received 64-bit data)\n"); 
22     TutOut("   Total messages received = " T_INT8_SPEC "\n", total_msg_recv_8); 
23     TutOut("   Total messages sent     = " T_INT8_SPEC "\n", total_msg_send_8); 
24     TutOut("   Total bytes received    = " T_INT8_SPEC "\n", total_byte_recv_8); 
25     TutOut("   Total bytes sent        = " T_INT8_SPEC "\n", total_byte_recv_8); 
     } 
26   else { 
       /* Print out the new information received */ 
27     TutOut("   (Received 32-bit data)\n"); 
28     TutOut("   Total messages received = " T_INT4_SPEC "\n", total_msg_recv_4); 
29     TutOut("   Total messages sent     = " T_INT4_SPEC "\n", total_msg_send_4); 
30     TutOut("   Total bytes received    = " T_INT4_SPEC "\n", total_byte_recv_4); 
31     TutOut("   Total bytes sent        = " T_INT4_SPEC "\n", total_byte_recv_4); 
     } 
     TutOut("===================================================\n"); 
 
   } /* ProcessTrafficPoll */ 
 
     /* ========================================================== */ 
32   int main(int argc, char **argv) 
     { 
33     T_IPC_MT mt; 
 
      /* Set the project name and unique subject of the process */ 
34    TutCommandParseStr("setopt project smartsockets"); 
35    TutCommandParseStr("setopt unique_subject /traffic/poller"); 
36    TutCommandParseStr("setopt monitor_scope /..."); 
 
      /* Connect to RTserver */ 
37    if (!TipcSrvCreate(T_IPC_SRV_CONN_FULL)) { 
38       TutOut("Could not connect to RTserver.\n"); 
39       TutExit(T_EXIT_FAILURE); 
      } 
 
      /* Create callback to process CLIENT_MSG_TRAFFIC poll results */ 
40    mt = TipcMtLookupByNum(T_MT_MON_CLIENT_MSG_TRAFFIC_POLL_RESULT); 
41    TipcSrvProcessCbCreate(mt, ProcessTrafficPoll, NULL); 
 
      /* Setup callback to receive unwanted message types */ 
42    TipcSrvDefaultCbCreate(DefaultReceiveFunc, NULL); 
 
      /* Read and process all poll results every 10 seconds */ 
43    while (1) { 
44      TutOut("==> Polling all client for message traffic info\n"); 
45      TipcMonClientMsgTrafficPoll(T_IPC_MON_ALL); 
46      TipcSrvMainLoop(10.0); 
      } 
 
      /* Disconnect from RTserver */ 
47    TipcSrvDestroy(T_IPC_SRV_CONN_NONE); 
 
    } /* main */ 
 

This program retrieves information about the RTclients’s message traffic (input and output). The poll for traffic information is initiated by the call to TipcMonClientMsgTrafficPoll on line 45. Note the argument to this function is T_IPC_MON_ALL, which directs the request for information to all RTclients in the project. (Alternatively, you can supply a subject name, and the request is sent to all processes whose unique subject matches the subject name—which may contain wildcard elements.)

This example program polls all clients every 10 seconds (the call to TipcSrvMainLoop on line 46). The 10 second timeout causes TipcSrvMainLoop to read and process all incoming messages for 10 seconds before giving up control.

The call to TipcMonClientMsgTrafficPoll results in a series of T_MT_MON_CLIENT_MSG_TRAFFIC_POLL_RESULT messages (one for each client polled). Lines 40–41 define a message process callback, ProcessTrafficPoll, to process messages of that type.

The user-defined callback function ProcessTrafficPoll (lines 6-31) accesses the fields of the messages (lines 17–18, 20) and prints the results (lines 21–25, 27–31). Note that on line 18 a single call to TipcMsgRead is used to access multiple fields of the message instead of making multiple calls to the TipcMsgNext* access functions as done previously. TipcMsgRead is a convenience function, similar to TipcMsgWrite, allowing you to access all the fields of a message with a single call.

This example also demonstrates the INT8 traffic counters introduced in SmartSockets 6.7. Because older clients will not return these extended statistics, a second TipcMsgRead (line 20) is used to retrieve these fields, and the return value is used to test for their presence. If the INT8 fields are available, the call to TipcMsgRead will succeed, and the INT8 statistics will be displayed (lines 21–25). Otherwise, the INT4 statistics are displayed (lines 27–31).

Step 19

Compile, link, and start the polling program

To watch this program in action, compile, and link polltraf.c:

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

You should start to see output similar to this:

==> Polling all client for message traffic info 
Summary of message traffic for client </traffic/poller> 
   Total messages received = 1 
   Total messages sent     = 1 
   Total bytes received    = 64 
   Total bytes sent        = 64 
====================================================== 

Output similar to this is repeated every 10 seconds.

Currently, the only program running in the project is the sample program doing the polling on message traffic, polltraf. If you look at the second line of the output:

Summary of message traffic for client </traffic/poller> 

you see that you are currently monitoring this very process.

You also notice that the information output is cumulative. The T_MT_MON_CLIENT_MSG_TRAFFIC_POLL_RESULT message type returns cumulative information. Note that there are many poll requests that are not cumulative and give a current snapshot of information.

Step 20

Start the receiving program

To make things more interesting, start up the receiving program in another window:

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

Now look at the window where the polling traffic program is running and you should see output similar to this:

==> Polling all client for message traffic info 
Summary of message traffic for client </lesson5/receiver> 
   Total messages received = 1 
   Total messages sent     = 1 
   Total bytes received    = 120 
   Total bytes sent        = 120 
====================================================== 
Summary of message traffic for client </traffic/poller> 
   Total messages received = 57 
   Total messages sent     = 85 
   Total bytes received    = 9528 
   Total bytes sent        = 9528 
====================================================== 

You should notice that each poll (every 10 seconds) now returns messages traffic information about two clients: /lesson5/receiver and /traffic/poller.

Step 21

Start the sending program

Now start up the sending program in a third window:

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

If you look at the window where the polling traffic program is running, you notice that it is still only printing information out about the two clients started earlier: /lesson5/receiver and /traffic/poller. Why? You are not getting statistics about the sending program because it has been set up to only transmit messages. It has not been set up to read and process any messages. The main loop of the sending program looks like:

while (1) { 
  TipcSrvMsgWrite("/tutorial/lesson5", 
                  TipcMtLookupByNum(T_MT_INFO), TRUE, 
                  T_IPC_FT_STR, "Hello World!", NULL); 
  TipcSrvFlush(); 
  TutSleep(1.0); 
} 

As you can see, the program sends a message, sleeps for one second, and then repeats. If you want your sending program to respond to poll requests, you need to put in a call to TipcSrvMainLoop (or to TipcSrvMsgNext and TipcSrvMsgProcess) into its main loop.

Step 22

Stop the sending program

Stop the sending process by entering Ctrl-c in the window where it is running.

Step 23

Edit the sending program

  1. Replace the call to TutSleep with a call to TipcSrvMainLoop with a one second timeout. The main loop of the program should now look like this:
  2. while (1) { 
       TipcSrvMsgWrite("/tutorial/lesson5", 
                       TipcMtLookupByNum(T_MT_INFO), TRUE, 
                       T_IPC_FT_STR, "Hello World!", NULL); 
       TipcSrvFlush(); 
       TipcSrvMainLoop(1.0); 
    } 
     

    Each time through the loop, the program checks for the arrival of any messages and process them, timing out each second.

  1. In the same program, before the call to TipcSrvCreate, assign the process a unique subject of /lesson5/sender by adding this line:
  2. TutCommandParseStr("setopt unique_subject /lesson5/sender");

    This makes the program easier to identify as you view the results of your message traffic poller.

Step 24

Save the program as send2.c

From the editor, save the updated program under the name send2.c. Under Windows copy the makefile snd2w32m.mak into your working directory.

Step 25

Compile, link, and start send2.c

Compile and link send2.c. Start send2.c in a new window.

In the window where the polling traffic program is running, you should now see output similar to this each time a poll is initiated:

==> Polling all client for message traffic info 
Summary of message traffic for client </traffic_poller> 
   Total messages received = 47 
   Total messages sent     = 5 
   Total bytes received    = 5784 
   Total bytes sent        = 5784 
====================================================== 
Summary of message traffic for client </lesson5/receiver> 
   Total messages received = 2 
   Total messages sent     = 2 
   Total bytes received    = 376 
   Total bytes sent        = 376 
====================================================== 
Summary of message traffic for client </lesson5/sender> 
   Total messages received = 12 
   Total messages sent     = 2 
   Total bytes received    = 1536 
   Total bytes sent        = 1536 
====================================================== 

You are now getting message traffic statistics on all three programs at each polling interval. Also notice that in the window where the receiving program is running, it is printing the INFO ("Hello World!") messages being sent by the new sending program.

Step 26

Stop all the running client programs

Be sure to stop all running client programs by entering Ctrl-c in each of the three windows where the programs are running.


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