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
