Example 2: Publisher to a variable topic
A WebSphere MQ program to illustrate publishing to a programmatically defined topic.
See the output in Figure 2.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cmqc.h>
int main(int argc, char **argv)
{
char topicNameDefault[] = "STOCKS";
char topicStringDefault[] = "IBM/PRICE";
char publicationDefault[] = "130";
MQCHAR48 qmName = "";
MQHCONN Hconn = MQHC_UNUSABLE_HCONN; /* connection handle */
MQHOBJ Hobj = MQHO_NONE; /* object handle sub queue */
MQLONG CompCode = MQCC_OK; /* completion code */
MQLONG Reason = MQRC_NONE; /* reason code */
MQOD td = {MQOD_DEFAULT}; /* Object descriptor */
MQMD md = {MQMD_DEFAULT}; /* Message Descriptor */
MQPMO pmo = {MQPMO_DEFAULT}; /* put message options */
MQCHAR resTopicStr[151]; /* Returned value of topic string */
char * topicName = topicNameDefault;
char * topicString = topicStringDefault;
char * publication = publicationDefault;
memset (resTopicStr, 0 , sizeof(resTopicStr));
switch(argc){ /* Replace defaults with args if provided */
default:
publication = argv[3];
case(3):
topicString = argv[2];
case(2):
if (strcmp(argv[1],"/")) /* "/" invalid = No topic object */
topicName = argv[1];
else
*topicName = '\0';
case(1):
printf("Provide parameters: TopicObject TopicString Publication\n");
}
printf("Publish \"%s\" to topic \"%-.48s\" and topic string \"%s\"\n", publication, topicName, topicString);
do {
MQCONN(qmName, &Hconn, &CompCode, &Reason);
if (CompCode != MQCC_OK) break;
td.ObjectType = MQOT_TOPIC; /* Object is a topic */
td.Version = MQOD_VERSION_4; /* Descriptor needs to be V4 */
strncpy(td.ObjectName, topicName, MQ_TOPIC_NAME_LENGTH);
td.ObjectString.VSPtr = topicString;
td.ObjectString.VSLength = (MQLONG)strlen(topicString);
td.ResObjectString.VSPtr = resTopicStr;
td.ResObjectString.VSBufSize = sizeof(resTopicStr)-1;
MQOPEN(Hconn, &td, MQOO_OUTPUT | MQOO_FAIL_IF_QUIESCING, &Hobj, &CompCode, &Reason);
if (CompCode != MQCC_OK) break;
pmo.Options = MQPMO_FAIL_IF_QUIESCING | MQPMO_RETAIN;
MQPUT(Hconn, Hobj, &md, &pmo, (MQLONG)strlen(publication)+1, publication, &CompCode, &Reason);
if (CompCode != MQCC_OK) break;
MQCLOSE(Hconn, &Hobj, MQCO_NONE, &CompCode, &Reason);
if (CompCode != MQCC_OK) break;
MQDISC(&Hconn, &CompCode, &Reason);
} while (0);
if (CompCode == MQCC_OK)
printf("Published \"%s\" to topic string \"%s\"\n", publication, resTopicStr);
printf("Completion code %d and Return code %d\n", CompCode, Reason);
}
X:\Publish2\Debug>PublishStock
Provide parameters: TopicObject TopicString Publication
Publish "130" to topic "STOCKS" and topic string "IBM/PRICE"
Published "130" to topic string "NYSE/IBM/PRICE"
Completion code 0 and Return code 0
X:\Publish2\Debug>PublishStock / NYSE/IBM/PRICE 131
Provide parameters: TopicObject TopicString Publication
Publish "131" to topic "" and topic string "NYSE/IBM/PRICE"
Published "131" to topic string "NYSE/IBM/PRICE"
Completion code 0 and Return code 0
char topicNameDefault[] = "STOCKS";- The default topic name
STOCKSdefines part of the topic string. You can override this topic name by providing it as the first argument to the program, or eliminate the use of the topic name by supplying / as the first parameter. char topicString[101] = "IBM/PRICE";IBM/PRICEis the default topic string. You can override this topic string by providing it as the second argument to the program.if (strcmp(argv[1],"/"))argv[1]is the optionally provided topicName.is invalid as a topic name; here it signifies that there is no topic name, and the topic string is provided entirely by the program. The output in Figure 2 shows the whole topic string being supplied dynamically by the program./
strncpy(td.ObjectName, topicName, MQ_OBJECT_NAME_LENGTH);- For the default case, the optional
topicNameneeds to be created beforehand, using IBM MQ Explorer or this MQSC command:DEFINE TOPIC(STOCKS) TOPICSTR(NYSE) REPLACE; td.ObjectString.VSPtr = topicString;- The topic string is a
MQCHARVfield in the topic descriptor
What does the second example demonstrate? Although the code is very similar to the first example - effectively there are only two lines difference - the result is a significantly different program to the first. The programmer controls the destinations to which publications are sent. In conjunction with minimal administrator input used to design subscriber applications, no topics or queues need to be predefined to route publications from publishers to subscribers.
In the point-to-point messaging paradigm, queues have to be defined before messages are able to flow. For publish/subscribe, they do not, although IBM MQ implements publish/subscribe using its underlying queuing system; the benefits of guaranteed delivery, transactionality and loose coupling associated with messaging and queuing are inherited by publish/subscribe applications.
A designer has to decide whether publisher, and subscriber, programs are to be aware of the underlying topic tree or not, and also whether subscriber programs are aware of queuing or not. Study the subscriber example applications next. They are designed to be used with the publisher examples, typically publishing and subscribing to NYSE/IBM/PRICE.