Nirvana C# .NET: Responder - Request/Response

This example shows how to respond to a request in performed in a request/response fashion.

Usage

response <channel name>

<Required Arguments> 

<request queue> - Queue onto which request are published
<response queue> - Queue onto which responses are published
<channel name> - Channel name parameter for the channel to subscribe to

[Optional Arguments] 

[asynchronous] - Whether to use asynchronous producing and consuming - true/false, default false.
[transactional] - Whether to use transactional production and consumption of events - true/false, default false.


Note: -? provides help on environment variables

Application Source Code

See also:

/*
 *  ----------------------------------------------------------------------------------
 *
 *  PCB Systems Limited License Version 1.1
 *  Copyright ? PCB Systems Limited. All rights reserved
 *
 *  In the event that you should download or otherwise use this software
 *  ( the "Software" ) you hereby acknowledge and agree that:
 *
 *  1. The Software is the property of PCB Systems Limited: Title, Copyright and all
 *  other proprietary rights, interest and benefit in and to the Software is and
 *  shall be owned by PCB Systems Limited;
 *
 *  2. You will not make copies of the Software whatsoever other than, if you should
 *  so wish, a single copy for archival purposes only;
 *
 *  3. You will not modify, reverse assemble, decompile, reverse engineer or otherwise
 *  translate the Software;
 *
 *  4. You will not redistribute, copy, forward electronically or circulate the Software
 *  to any person for any purpose whatsoever without the prior written consent of
 *  PCB Systems Limited;
 *
 *  5. You will not charge for, market or provide any managed service or product that
 *  is based upon or includes the Software or any variant of it; and
 *
 *  6. You will not use the Software for any purpose apart from your own personal,
 *  noncommercial and lawful use;
 *
 *  You hereby agree that the software is used by you on an "as is" basis, without
 *  warranty of any kind. PCB Systems Limited hereby expressly disclaim all warranties
 *  and conditions, either expressed or implied, including but not limited to any
 *  implied warranties or conditions or merchantability and fitness for a particular
 *  purpose.
 *
 *  You agree that you are solely responsible for determining the appropriateness of
 *  using the Software and assume all risks associated with it including but not
 *  limited to the risks of program errors, damage to or loss of of data, programs or
 *  equipment and unavailability or interruption of operations.
 *
 *  PCB Systems Limited will not be liable for any direct damages or for any, special,
 *  incidental or indirect damages or for any economic consequential damages ( including
 *  lost profits or savings ), or any damage howsoever arising.
 *
 *  ------------------------------------------------------------------------ 
 */
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using com.pcbsys.nirvana.client;
using System.Threading;
namespace com.pcbsys.nirvana.apps
{
    class responder : nSampleApp, nEventListener
    {
        private static responder myself;
        private nQueue respQueue;
        private nQueue reqQueue;
        private bool async = false;
        private bool transactional = false;
        private nQueueReader queueReader = null;
        String reqQueueName;
        String respQueueName;
        String rname;
        private static readonly UTF8Encoding encoding = new UTF8Encoding();
        /**
        * @param args
        */
        public static void Main(String[] args) {
        myself = new responder();
        // Process input variables.
        myself.processArgs(args);
        responder.processEnvironmentVariables();
        // Construct realm properties.
        String[] rproperties = new String[4];
        rproperties = parseRealmProperties(myself.rname);
        myself.doit(rproperties, myself.reqQueueName, myself.respQueueName);
        }
        private void doit(String[] rproperties, String requestQueueName,
        String responseQueueName) {
        try {
        //Create session
        myself.constructSession(rproperties);
        //Connect to response queue.
        nChannelAttributes respAtr = new nChannelAttributes();
        respAtr.setName(responseQueueName);
        respQueue = mySession.findQueue(respAtr);
        //Connect to request queue.
        nChannelAttributes reqAtr = new nChannelAttributes();
        reqAtr.setName(requestQueueName);
        reqQueue = mySession.findQueue(reqAtr);
        setQueueReader(respQueue);
        if (async) {
        Console.WriteLine("Beginning to listen asynchronously...");
        } else {
        //Set up a thread to process incoming synchronous events.
        Console.WriteLine("Beginning to listen synchronously...");
        ThreadStart ts = new ThreadStart(run);
        Thread reader;
        reader = new Thread(ts);
        reader.IsBackground = true;
        reader.Start();
        }
        Console.Read();
        Console.WriteLine("Finished.");
        // Destroy the queue reader
        nQueue.destroyReader(queueReader);
        } catch (Exception ex) {
            ex.ToString();
        }
        Environment.Exit(0);
        }
        // Set the appropriate type of queue listener.
        private void setQueueReader(nQueue respQueue) {
                try {
                if (async) {
                    if (transactional) {
                        Console.WriteLine("transational");
                        this.queueReader = reqQueue
                        .createAsyncTransactionalReader(new nQueueReaderContext(
                        this));
                    } else {
                        this.queueReader = reqQueue
                        .createAsyncTransactionalReader(new nQueueReaderContext(
                        this));
                    }
                } else {
                    if (transactional) {
                    Console.WriteLine("transactional");
                        this.queueReader = reqQueue
                        .createTransactionalReader(new nQueueReaderContext(
                        this));
                    } else {
                        this.queueReader = reqQueue
                        .createTransactionalReader(new nQueueReaderContext(
                        this));
                    }
                }
                } catch (Exception ex) {
                    Console.WriteLine("Could not create reader");
                    Environment.Exit(1);
                }
                }
                void processArgs(String[] args) {
                if (args.Length > 5) {
                Usage();
                UsageEnv();
                } else {
                switch (args.Length) {
                case 5:
                        transactional = Convert.ToBoolean(args[4]);
                        goto case 4;
                case 4:
                        async = Convert.ToBoolean(args[3]);
                        goto case 3;
                case 3:
                        respQueueName = args[2];
                        goto case 2;
                case 2:
                    reqQueueName = args[1];
                    goto case 1;
                case 1:
                    if (args[0].Equals("-?")) {
                        Usage();
                        UsageEnv();
                        }
                            rname = args[0];
                            break;
                        }
            }
        }
        private void Usage() {
            Console.WriteLine("Usage ...\n");
            Console.WriteLine("response <channel name>\n");
            Console.WriteLine("<Required Arguments> \n");
            Console.WriteLine("<request queue> - Queue onto which request are published");
            Console.WriteLine("<response queue> - Queue onto which responses are published");
            Console.WriteLine("<channel name> - Channel name parameter for the channel to subscribe to");
            Console.WriteLine("\n[Optional Arguments] \n");
            Console.WriteLine("[asynchronous] - Whether to use asynchronous producing and consuming - true/false, default false.");
            Console.WriteLine("[transactional] - Whether to use transactional production and consumption of events - true/false, default false.");
            Console.WriteLine("\n\nNote: -? provides help on environment variables \n");
        }
            public void go(nConsumeEvent req) {
            Console.WriteLine("Recieved request");
            //Retrieve username of request sender.
            String requester = req.getPublishUser();
            Console.WriteLine("Requester :" + requester);
            //Construct reply message.
            String text = "Response: " + encoding.GetString(req.getEventData());
            Console.WriteLine("Reply:\"" + text + "\"");
            //Construct reply event
            nEventProperties atr = new nEventProperties();
            nConsumeEvent resp = new nConsumeEvent("tag",encoding.GetBytes(text));
            //Set recipient of the event to the requester's tag to reply.
            resp.setSubscriberName(encoding.GetBytes(requester));
            try {
                if (transactional) {
                //Pack events transactionally if necessary (only one message in this simple example however).
                Console.WriteLine("Transactional");
                List<nConsumeEvent> vEvents = new List<nConsumeEvent>();
                nTransactionAttributes TXAttrib;
                try {
                    TXAttrib = new nTransactionAttributes(respQueue, 1000);
                    new nTransactionFactory();
                    nTransaction tx = nTransactionFactory.create(TXAttrib);
                    vEvents.Add(resp);
                    tx.publish(vEvents);
                    tx.commit();
                } catch (Exception e) {
                    Console.WriteLine("Could not publish transaction.");
                    Environment.Exit(1);
                }
                } else {
                    //Otherwise simply publish the event.
                    respQueue.push(resp);
                }
            } catch (Exception e) {
                Console.WriteLine("Could not publish to queue");
                Environment.Exit(1);
            }
            Console.WriteLine("Published response");
        }
        void run() {
            //Deal with synchronous events i.e. each client request.
            Console.WriteLine("Running Thread");
            nConsumeEvent evt;
            while (true) {
            try {
            if (transactional) {
            evt = ((nQueueSyncTransactionReader) queueReader).pop(-1);
            } else {
            evt = ((nQueueSyncReader) queueReader).pop(-1);
            }
            if (evt != null) {
            go(evt);
            }
            } catch (Exception e) {
            Console.WriteLine("Exception in pop....exiting!");
            Console.WriteLine(e.StackTrace);
            break;
            }
            }
            Environment.Exit(1);
            }
        }
    }
EXAMPLE_SOURCE_END
Share this page with others:
Tell Your Tweets Facebook It! Add to Delicious Reddit! Digg It! Stumble Upon Add to Your Faves Mixx it
Follow Us:
Keep up with my-Channels on Twitter Become a fan on Facebook LinkedIn Profile Recent Highlights RSS Feed