Click here to Skip to main content
15,881,413 members
Articles / Programming Languages / C#
Article

C# and WebSphere MQ (formerly MQSeries) Client/Server examples

Rate me:
Please Sign up or sign in to vote.
4.45/5 (12 votes)
7 Mar 200410 min read 161K   4.4K   42   11
Examples to PUT and GET messages to and from MQSeries using four different methods which build on each other.

Overview

With the .NET support pack to access MQSeries, C# developers can easily access IBM MQSeries which is especially important for front-end developers wishing to access the mainframe (CICS, DB2).

The non-connected database classes within ADO make C# very attractive compared to other languages available today for front-end development especially considering the pseudo conversational nature of CICS as the mainframe transaction server. Unfortunately, IBM supplies only a few very basic examples of accessing MQSeries using C# with the .NET support pack. For other languages, e.g. C, there is an abundance of helpful examples available.

Another difficulty is that the examples are designed to run on an MQ client with a corresponding MQ server program running on a separate machine supplying the replies etc., although many developers would prefer to develop and test on the same machine (as I do on my laptop).

In this article, I am going to give four examples (eight programs) to put and get messages to and from MQSeries using four different methods which build on each other:

  1. Programs exmqput1 and exmqget1:

    Simple PUT message and GET message program pair.

  2. Programs exmqreq1 and exmqrep1:

    Simple PUT REQUEST/GET RESPONSE and GET REQUEST/ PUT REPLY program pair.

  3. Programs exmqreq2 and exmqrep2:

    PUT REQUEST/GET RESPONSE and GET REQUEST/ PUT REPLY program pair, using a dynamic queue to hold the reply (suitable for database queries with result sets).

  4. Programs exmqreq3 and exmqrep3:

    PUT REQUEST/GET RESPONSE and GET REQUEST/ PUT REPLY program pair, using a dynamic queue to hold the reply in which the GET REQUEST/PUT REPLY program is triggered by the calling program.

All the examples only use the Queue name(s) and Queue Manager name. I don't use the channel definition as all the examples are running on the same machine.

Examples of how to use the channel definitions are shown in the sample programs supplied with the .NET Support Pack.

First, you need to install the .NET support pack in the PC where I assume you have already installed MQSeries Client/Server. This can be downloaded here.

To create the example QueueManager, Queues and the Process used in Example 4, run the batch file exqmansetup.bat supplied with the source code.

To remove the example QueueManager and all associated objects, run the batch file exqmanremove.bat. Afterwards, it may be necessary to remove the entry for the QueueManager in Websphere MQ Explorer by right clicking the EXQMAN entry and then clicking "delete".

Environment tips/problems.

I have included a batch file "setpath" which will extend the path to include the directory where the csc.exe file resides, normally path C:\WINNT\Microsoft.NET\Framework\v1.1.4322 and the path to the Websphere MQ libraries, normally C:\programme\IBM\Websphere MQ\bin. These may not be necessary depending on how your path variables are already set up.

I had a problem compiling as the compiler could not find the amqmdnet.dll library. I copied this DLL into the directory where the examples were running and all was well. To save any trouble, I have also copied this DLL into the zip file.

You may not have this problem but at least you now know where the IBM.WMQ classes are.

One deficiency I found was in exception handling. The MQException class returns the completion code and a reason code but there is no way to display the associated error text. This meant that I had to look up the reason code (in the Application Programmers Guide, page 605) to find the message text and then page through the error messages which are in alphabetic order to get the explanation.

I decided to create a class (MQRCText) which has a static array containing all 360 error message texts and one method (getMQRCText) which accepts the reason code and returns the message text. I made this into a DLL and all the example programs include this library in the compile statement. This saved me a lot of time as it was much easier to see my typos when I had a message about them rather than just a code which meant nothing to me. I hope you also get some benefit out of this and the source and DLL are included here (MQRCText.cs and MQRCText.dll).

I have built unique dynamic queue name using a text "dynam" concatenated with the user ID and time of day in the form hhmmssmmm. According to the MQ documentation, it should be possible to enter either a name of under 33 characters ending with an "*" or just an "*" and MQ should automatically build a unique name. I could not get this feature to work.

Creating MQ Objects for the Example Programs.

Run the batch file exqmansetup.bat. This creates the following objects:

EXQMAN               -      Example QueueManager

LEXQ1                -      Example Local Queue 1

LEXQ2                -      Example Local Queue 2

LEXAQ3               -      Example Local Application Queue

LEXIQ3               -      Example Local Initiation Queue

EXPROC               -      Example Process

The generated objects are used as follows:

EXQMAN               -      used in all examples

LEXQ1                -      used in examples 1, 2 and 3

LEXQ2                -      used in example 2

LEXAQ3               -      used in example 4

LEXIQ3               -      used in example 4

EXPROC               -      used in example 4

Example 4 shows how to use the "Triggering" function of MQ. This requires a monitor to be listening on the initiation queue which, when a message is received, starts a process (EXPROC) which in turn starts the REPLY program (exmqrep3). To start the monitor, run batch file runlexiq3.bat.

Compiling the Example Programs:

The example programs are already compiled and can be used as is. If you wish to change a program, just do the following to recompile:

To compile the example programs, run batch file bldexprogs.bat.

If you get a message saying that it cannot find csc.exe (compiler) or it cannot find the amqmdnet.dll reference library, then see "Environment tips/problems" above.

Running the example programs:

  • Example 1. Open a DOS box and go to the directory where you have the example programs.

    Enter: "exmqput1 LEXQ1 EXQMAN".

    Type in the message you want to PUT on the queue when requested. The program writes to queue LEXQ1 and requests the next message. If you just hit return without typing anything in, then the program ends. You could now use WebSphere MQ Explorer to browse the queue where you will see the message.

    Enter: "exmqget1 LEXQ1 EXQMAN".

    The program reads from queue LEXQ1 and displays all the messages on the console, then the program ends. You could now use WebSphere MQ Explorer to browse the queue where you will see that the message has been read and the queue is empty.

  • Example 2. Open a DOS box and go to the directory where you have the example programs.

    Enter: "exmqreq1 LEXQ1 LEXQ2 EXQMAN".

    Type in the message you want to PUT on the queue when requested. The program writes to queue LEXQ1 and the program waits for a response on queue LEXQ2. When sending the request, the field ReplyToQueue contains the reply queue name (LEXQ2) and the field ReplyToQueueManager contains the reply queue manager name.

    When a response message is received or the GET times out (after 60 seconds), the program ends.

    Open a second DOS box and go to the directory where you have the example programs.

    Enter: "exmqrep1 LEXQ1 EXQMAN".

    The program reads from queue LEXQ1 and displays the message on the console, it then reads the ReplyToQueue and ReplyToQueueManager fields from the input message, uses these to fill the queue and queue manager names of the reply message and sends (PUTs) the reply message to the reply queue (LEXQ2), then the program ends.

    Note: both programs will wait 60 seconds for a message before timing out. This can be changed in the source code by setting mqGetMsgOpts.WaitInterval to "UNLIMITED" or the number of milliseconds to wait (e.g. 60000 -> 60 seconds).

  • Example 3. Open a DOS box and go to the directory where you have the example programs.

    Enter: "exmqreq2 LEXQ1 EXQMAN".

    Type in the message you want to PUT on the queue when requested. The program writes to queue LEXQ1 and the program waits for a response on a dynamic queue which is created at run time. When sending the request, the field ReplyToQueue contains the reply queue name (dynamic) and the field ReplyToQueueManager contains the reply queue manager name.

    When a response message is received or the GET times out (after 60 seconds), the program ends.

    Open a second DOS box and go to the directory where you have the example programs.

    Enter: "exmqrep2 LEXQ1 EXQMAN".

    The program reads from queue LEXQ1 and displays the message on the console, it then reads the ReplyToQueue and ReplyToQueueManager fields from the input message, uses these to fill the queue and queue manager names of the reply message and sends (PUTs) the reply message to the reply queue (dynamic), then the program ends.

    Note: both programs will wait 60 seconds for a message before timing out. This can be changed in the source code by setting mqGetMsgOpts.WaitInterval to "UNLIMITED" or the number of milliseconds to wait (e.g. 60000 -> 60 seconds).

    Careful: If exmqreq2 times out, it will leave a message on queue LEXQ1. If then exmqrep2 is started, it will read the message on LEXQ1 but will NOT find the dynamic queue name to send back to (as the dynamic queue is deleted when exmqreq2 is finished). If you get into this situation (check the queue with MQ Explorer Queue Browser), then run exmqget1 which will read and automatically remove messages from LEXQ1.

  • Example 4. Open a DOS box and go to the directory where you have the example programs.

    Run batch file runlexiq3.bat to start the MQ Monitor program. This will open its own DOS box in which you can see the trigger message which is sent when the example program runs.

    Enter: "exmqreq3 LEXAQ1 EXQMAN".

    Type in the message you want to PUT on the queue when requested to do so. The program writes to queue LEXAQ3 and the program waits for a response on a dynamic queue which is created at run time. When sending the request, the field ReplyToQueue contains the reply queue name (dynamic) and the field ReplyToQueueManager contains the reply queue manager name.

    LEXAQ3 is an Application Queue, i.e. it has the properties TRIGGER, TRIGTYPE(FIRST), INITQ(LEXIQ3) and PROCESS(EXPROC) set. This means that when the first message arrives on queue LEXAQ3, a trigger message is automatically sent to the Initiation queue (LEXIQ3). This trigger message is read from the Initiation queue by the Monitor program which was previously started by batch file runlexiq3.

    The monitor program picks up the process (EXPROC) and executes the application defined in field APPLICID ('start /wait exmqrep3.exe LEXAQ3 EXQMAN').

    When a response message is received or the GET times out (after 60 seconds), the program ends.

    Program exmqrep3 is started automatically by the triggering mechanism described above.

    The program reads from queue LEXAQ1 and displays the message on the console, it then reads the ReplyToQueue and ReplyToQueueManager fields from the input message, uses these to fill the queue and queue manager names of the reply message and sends (PUTs) the reply message to the reply queue (dynamic), then the program ends.

    Note: both programs will wait 60 seconds for a message before timing out. This can be changed in the source code by setting mqGetMsgOpts.WaitInterval to "UNLIMITED" or the number of milliseconds to wait (e.g. 60000 -> 60 seconds).

I hope these examples help you to get going with C# and MQSeries. I will be writing a follow up to this, describing the usage of transmission queues and triggering CICS transactions from C#.

Using a DataGrid to display the results of a SQL query over MQSeries will then be the logical follow up to that.

Conclusion

If you have any questions, corrections, comments etc., please contact me at johnconcannon@eircom.net and if you're interested, check my website where I will be putting up other information focusing on MQSeries, CICS, DB2, REXX, ISPF, COBOL and other mainframe stuff as well as, of course, C#.

Thank you and best wishes.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Switzerland Switzerland
Hello Folks,
My name is John Concannon and I am now based in Zurich, Switzerland. I am currently working on a follow up to this article describing how to define the whole round trip from frontend to MQ Windows server to zOS MQ server to CICS to DB2 and back.
If you want to contact me please use email address john.concannon@copperalley.com

Best wishes,

John

Comments and Discussions

 
Questionhow to write a trigger or continuous listener for an IBM queue Pin
Member 297937818-Jul-11 21:31
Member 297937818-Jul-11 21:31 
AnswerRe: how to write a trigger or continuous listener for an IBM queue Pin
morningstar171030-Aug-11 9:56
morningstar171030-Aug-11 9:56 
Questiondynamic queues --Performance Pin
kanthikp22-Dec-06 0:40
kanthikp22-Dec-06 0:40 
AnswerRe: dynamic queues --Performance Pin
John Concannon22-Dec-06 12:00
John Concannon22-Dec-06 12:00 
Questionexmqget1 Non-text message result Pin
Melissa Jones23-Oct-06 10:25
Melissa Jones23-Oct-06 10:25 
AnswerRe: exmqget1 Non-text message result Pin
John Concannon23-Oct-06 11:44
John Concannon23-Oct-06 11:44 
GeneralPut on a Transmission Queue Pin
Villanovich9-May-05 7:39
Villanovich9-May-05 7:39 
GeneralReason Codes Pin
Chris Durkin23-Aug-04 11:47
Chris Durkin23-Aug-04 11:47 
Generalamqmdnet.dll Pin
jfos9-Mar-04 3:42
jfos9-Mar-04 3:42 
GeneralRe: amqmdnet.dll Pin
John Concannon10-Mar-04 5:10
John Concannon10-Mar-04 5:10 
GeneralRegarding Example Usage Pin
Senguttuvan27-Aug-04 7:28
Senguttuvan27-Aug-04 7:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.