protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { if (Session != null) { Session.Dispose(); Session = null; } if (Queue != null) { Queue.Dispose(); Queue = null; } if (Flow != null) { Flow.Dispose(); Flow = null; } } disposedValue = true; } }
/// <summary> /// Dump messages received from a given Queue. /// </summary> /// <param name="session"></param> /// <param name="queue"></param> /// <param name="waitTimeout"></param> /// <param name="autoack">If true, messages will be automaticaly acked</param> private void DumpMessagesReceivedFromQueue(ISession session, IQueue queue, int waitTimeout, bool autoack) { FlowProperties flowProps = new FlowProperties(); if (autoack) { flowProps.AckMode = MessageAckMode.AutoAck; } else { flowProps.AckMode = MessageAckMode.ClientAck; } // Clear messages on the shared message list '_deliveredMessages' first. lock (_deliveredMessages) { _deliveredMessages.Clear(); } IFlow flow = session.CreateFlow(flowProps, queue, null, HandleMessageEvent, SampleUtils.HandleFlowEvent); // To keep the sample simple, it is good enough to use Thread.Sleep(). Thread.Sleep(waitTimeout); // Then dispose. flow.Dispose(); // Dump the received messages. Console.WriteLine(string.Format("\n@@@ Received {0} message(s) over queue {1}", _deliveredMessages.Count, queue.ToString())); foreach (IMessage deliveredMsg in _deliveredMessages) { Console.WriteLine(deliveredMsg.Dump() + "\n"); } }
private bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { Flow.Dispose(); } disposedValue = true; } }
/// <summary> /// /// </summary> private void Cleanup(IFlow flow, IEndpoint provisionedEndpoint, ISession session, IContext context) { if (flow != null) { flow.Dispose(); } if (provisionedEndpoint != null) { session.Deprovision(provisionedEndpoint, ProvisionFlag.WaitForConfirm, null); } if (session != null) { session.Dispose(); } if (context != null) { context.Dispose(); } // Must cleanup after. CleanupContext(); }
/// <summary> /// The main function in the sample. /// </summary> /// <param name="args"></param> public override void SampleCall(string[] args) { #region Parse Arguments ArgParser cmdLineParser = new ArgParser(); if (!cmdLineParser.Parse(args)) { // parse failed PrintUsage(INVALID_ARGUMENTS_ERROR); return; } cmdLineParser.Config.DeliveryMode = MessageDeliveryMode.Persistent; cmdLineParser.Config.DestMode = DestMode.QUEUE; #endregion #region Initialize properties from command line // Initialize the properties ContextProperties contextProps = new ContextProperties(); SessionProperties sessionProps = SampleUtils.NewSessionPropertiesFromConfig(cmdLineParser.Config); #endregion // Define IContext and ISession IContext context = null; ISession session = null; IFlow flow = null; try { InitContext(cmdLineParser.LogLevel); Console.WriteLine("About to create the context ..."); context = ContextFactory.Instance.CreateContext(contextProps, null); Console.WriteLine("Context successfully created. "); Console.WriteLine("About to create the session ..."); session = context.CreateSession(sessionProps, SampleUtils.HandleMessageEvent, SampleUtils.HandleSessionEvent); Console.WriteLine("Session successfully created."); Console.WriteLine("About to connect the session ..."); if (session.Connect() == ReturnCode.SOLCLIENT_OK) { Console.WriteLine("Session successfully connected"); Console.WriteLine(GetRouterInfo(session)); } if (!session.IsCapable(CapabilityType.SELECTOR)) { Console.WriteLine(string.Format("Capability '{0}' is required to run this sample", CapabilityType.SELECTOR)); return; } if (!session.IsCapable(CapabilityType.SUB_FLOW_GUARANTEED) || !(session.IsCapable(CapabilityType.TEMP_ENDPOINT))) { Console.WriteLine(string.Format("Capabilities '{0}' and {1} are required to run this sample", CapabilityType.SUB_FLOW_GUARANTEED, CapabilityType.TEMP_ENDPOINT)); return; } // The creation of the Queue object. Temporary destinations must be // acquired from a connected session, as they require knowledge // about the connected appliance. IQueue queue = session.CreateTemporaryQueue(); // The creation of a flow. A FlowReceiver is acquired for consuming // messages from a specified endpoint. // // The selector "pasta = 'rotini' OR pasta = 'farfalle'" is used to // select only messages matching those pasta types in their user // property map. FlowProperties flowProps = new FlowProperties(); flowProps.FlowStartState = true; // created in a started state; flowProps.Selector = "pasta = 'rotini' OR pasta = 'farfalle'"; flow = session.CreateFlow(flowProps, queue, null, SampleUtils.HandleMessageEvent, SampleUtils.HandleFlowEvent); // Now publish a number of messages to queue, the user should only get the ones with 'rotini' or 'farfalle'. // Note that this uses SDT and custom header properties, which could impact performance. IMessage message = SampleUtils.CreateMessage(cmdLineParser.Config, session); message.Destination = queue; string[] pastas = new string[] { "macaroni", "fettuccini", "farfalle", "fiori", "rotini", "penne" }; for (int i = 0; i < pastas.Length; i++) { IMapContainer userProps = message.CreateUserPropertyMap(); userProps.AddString("pasta", pastas[i]); if (session.Send(message) == ReturnCode.SOLCLIENT_OK) { Console.WriteLine(String.Format("- Sent {0}", pastas[i])); } } Console.WriteLine(string.Format("\nDone\n Sleeping for {0} secs before exiting. Expecting 2 messages to match the selector ", Timeout / 1000)); Thread.Sleep(Timeout); } catch (Exception ex) { PrintException(ex); } finally { if (flow != null) { flow.Dispose(); } if (session != null) { session.Dispose(); } if (context != null) { context.Dispose(); } // Must cleanup after. CleanupContext(); } }
/// <summary> /// Main function in the sample. /// </summary> /// <param name="args"></param> public override void SampleCall(string[] args) { #region Parse Arguments ArgParser cmdLineParser = new ArgParser(); if (!cmdLineParser.Parse(args)) { // parse failed PrintUsage(INVALID_ARGUMENTS_ERROR); return; } if (!SampleParseArgs(cmdLineParser)) { // parse failed for sample's arguments PrintUsage(INVALID_ARGUMENTS_ERROR); return; } #endregion #region Initialize properties from command line // Initialize the properties. ContextProperties contextProps = new ContextProperties(); SessionProperties sessionProps = SampleUtils.NewSessionPropertiesFromConfig(cmdLineParser.Config); #endregion // Define IContext and ISession. IContext context = null; ISession session = null; ITopicEndpoint topicEndpoint = null; try { InitContext(cmdLineParser.LogLevel); Console.WriteLine("About to create the Context ..."); context = ContextFactory.Instance.CreateContext(contextProps, null); Console.WriteLine("Context successfully created. "); Console.WriteLine("About to create the Session ..."); session = context.CreateSession(sessionProps, SampleUtils.HandleMessageEvent, SampleUtils.HandleSessionEvent); Console.WriteLine("Session successfully created."); Console.WriteLine("About to connect the Session ..."); if (session.Connect() == ReturnCode.SOLCLIENT_OK) { Console.WriteLine("Session successfully connected"); Console.WriteLine(GetRouterInfo(session)); } if (!session.IsCapable(CapabilityType.SUB_FLOW_GUARANTEED) || !(session.IsCapable(CapabilityType.TEMP_ENDPOINT))) { Console.WriteLine(string.Format("Capabilities '{0}' and '{1}' are required to run this sample", CapabilityType.SUB_FLOW_GUARANTEED, CapabilityType.TEMP_ENDPOINT)); return; } ITopic topic = null; if (cmdLineParser.Config.UseDurableEndpoint) { Console.WriteLine(string.Format("A durable topic endpoint with name '{0}' must be provisioned and accessible on the appliance in the same user's Message VPN.)", SampleUtils.SAMPLE_TOPICENDPOINT)); topicEndpoint = ContextFactory.Instance.CreateDurableTopicEndpointEx(SampleUtils.SAMPLE_TOPICENDPOINT); topic = ContextFactory.Instance.CreateTopic(SampleUtils.SAMPLE_TOPIC); } else { Console.WriteLine("Creating a temporary Topic"); topic = session.CreateTemporaryTopic(); topicEndpoint = session.CreateNonDurableTopicEndpoint(); } FlowProperties flowProps = new FlowProperties(); // The Flow is created in a started state, so it is ready to receive messages. flowProps.FlowStartState = true; // AutoAck means that the received messages on the Flow // will be implicitly acked on return from the message event handler // specified in CreateFlow(). flowProps.AckMode = MessageAckMode.AutoAck; // NON-BLOCKING FLOW CREATE: make sure that the flowProps.BindBlocking is set to false; flowProps.BindBlocking = false; // NON-BLOCKING FLOW CREATE: to demonstrate waiting on flow up event EventWaitHandle waitForFlowUpEvent = new AutoResetEvent(false); flow = session.CreateFlow(flowProps, topicEndpoint, topic, SampleUtils.HandleMessageEvent, new EventHandler <FlowEventArgs>( delegate(object source, FlowEventArgs evt) { if (evt.Event == FlowEvent.UpNotice) { waitForFlowUpEvent.Set(); } })); if (waitForFlowUpEvent.WaitOne(5000, false)) { // We got a FlowEvent.UpNotice. Console.Out.WriteLine("Flow created, we can proceed now"); } else { // We did not get a FlowEvent.UpNotice within five seconds. Console.Out.WriteLine("Did not get a FlowEvent.UpNotice within 5 secs, exiting ..."); return; } // Send a number of messages to the Topic. IMessage message = SampleUtils.CreateMessage(cmdLineParser.Config, session); message.Destination = topic; Console.WriteLine(string.Format("About to send {0} messages ...", cmdLineParser.Config.NumberOfMessagesToPublish)); for (int i = 0; i < cmdLineParser.Config.NumberOfMessagesToPublish; i++) { if (session.Send(message) == ReturnCode.SOLCLIENT_OK) { Console.Write("."); } Thread.Sleep(1000); // wait for 1.0 seconds. } Console.WriteLine(string.Format("\nDone\n Sleeping for {0} secs before exiting ", Timeout / 1000)); Thread.Sleep(Timeout); } catch (Exception ex) { PrintException(ex); } finally { bool flowWasConnected = (flow != null); if (flow != null) { flow.Dispose(); } // Durable Topic Endpoints will continue getting messages on the registered Topic // subscription if client applications do not unsubscribe. // Non-durable Topic Endpoints will be cleaned up automatically after client applications // dispose the Flows bound to them. // // The following code block demonstrates how to unsubscribe or remove a subscribed Topic on // the durable Topic Endpoint. // Two conditions must be met: // - The durable Topic Endpoint must have at least 'Modify Topic' permission enabled. // - No flows are currently bound to the durable Topic Endpoint in question. if (topicEndpoint != null && topicEndpoint.Durable && session != null && flowWasConnected) { Console.WriteLine(string.Format("About to unsubscribe from durable Topic Endpoint '{0}'", ((ITopicEndpoint)topicEndpoint).Name)); session.Unsubscribe(topicEndpoint, "Unsubscribe Operation Correlation ID"); } if (session != null) { session.Dispose(); } if (context != null) { context.Dispose(); } // Must cleanup after. CleanupContext(); } }
/// <summary> /// Main entry point to the sample /// </summary> /// <param name="args"></param> public override void SampleCall(string[] args) { // Parse command line arguments ArgParser cmdLineParser = new ArgParser(); if (!cmdLineParser.Parse(args) || !SampleParseArgs(cmdLineParser)) { // Parse failed. PrintUsage(INVALID_ARGUMENTS_ERROR); return; } // Create the API components: starting with the properties ContextProperties contextProps = new ContextProperties(); SessionProperties sessionProps = new SessionProperties(); sessionProps.Host = cmdLineParser.Config.IpPort.ip; sessionProps.UserName = cmdLineParser.Config.RouterUserVpn.user; sessionProps.Password = cmdLineParser.Config.UserPassword; sessionProps.SSLValidateCertificate = false; sessionProps.ReconnectRetries = 3; if (cmdLineParser.Config.RouterUserVpn.vpn != null) { sessionProps.VPNName = cmdLineParser.Config.RouterUserVpn.vpn; } if (cmdLineParser.Config.Compression) { /* Compression is set as a number from 0-9, where 0 means "disable * compression", and 9 means max compression. The default is no * compression. * Selecting a non-zero compression level auto-selects the * compressed SMF port on the appliance, as long as no SMF port is * explicitly specified. */ sessionProps.CompressionLevel = 9; } // Create and connect the API components: create the context, session and flow objects IContext context = null; try { // Creating the context InitContext(cmdLineParser.LogLevel); Console.WriteLine("Creating the context ..."); context = ContextFactory.Instance.CreateContext(contextProps, null); // Creating the session Console.WriteLine("Creating the session ..."); session = context.CreateSession(sessionProps, SampleUtils.HandleMessageEvent, SampleUtils.HandleSessionEvent); // Connecting the session Console.WriteLine("Connecting the session ..."); if (session.Connect() == ReturnCode.SOLCLIENT_OK) { Console.WriteLine("Session successfully connected"); } // Creating the temporary queue and corresponding flow IQueue replyToQueue = session.CreateTemporaryQueue(); FlowProperties flowProperties = new FlowProperties(); flow = session.CreateFlow(flowProperties, replyToQueue, null, /* null when binding to a queue*/ HandleReplyMessage, /* defined in this sample to handle receipt of reply message*/ SampleUtils.HandleFlowEvent); flow.Start(); doRequest(requestDestination, replyToQueue, Operation.PLUS, 5, 4); Thread.Sleep(1000); doRequest(requestDestination, replyToQueue, Operation.MINUS, 5, 4); Thread.Sleep(1000); doRequest(requestDestination, replyToQueue, Operation.TIMES, 5, 4); Thread.Sleep(1000); doRequest(requestDestination, replyToQueue, Operation.DIVIDE, 5, 4); } catch (Exception ex) { PrintException(ex); } finally { if (flow != null) { flow.Dispose(); } if (session != null) { session.Dispose(); } if (context != null) { context.Dispose(); } // Must cleanup after. CleanupContext(); } }
/// <summary> /// Main function in the sample. /// </summary> /// <param name="args"></param> public override void SampleCall(string[] args) { #region Parse Arguments ArgParser cmdLineParser = new ArgParser(); if (!cmdLineParser.Parse(args)) { // parse failed PrintUsage(INVALID_ARGUMENTS_ERROR); return; } if (!SampleParseArgs(cmdLineParser)) { // parse failed for sample's arguments PrintUsage(INVALID_ARGUMENTS_ERROR); return; } #endregion #region Initialize properties from command line // Initialize the properties. ContextProperties contextProps = new ContextProperties(); SessionProperties sessionProps = SampleUtils.NewSessionPropertiesFromConfig(cmdLineParser.Config); #endregion // Define IContext and ISession. IContext context = null; ISession session = null; IQueue queue = null; try { InitContext(cmdLineParser.LogLevel); Console.WriteLine("About to create the Context ..."); context = ContextFactory.Instance.CreateContext(contextProps, null); Console.WriteLine("Context successfully created. "); Console.WriteLine("About to create the Session ..."); session = context.CreateSession(sessionProps, SampleUtils.HandleMessageEvent, SampleUtils.HandleSessionEvent); Console.WriteLine("Session successfully created."); Console.WriteLine("About to connect the Session ..."); if (session.Connect() == ReturnCode.SOLCLIENT_OK) { Console.WriteLine("Session successfully connected"); Console.WriteLine(GetRouterInfo(session)); } if (!session.IsCapable(CapabilityType.SUB_FLOW_GUARANTEED) || !(session.IsCapable(CapabilityType.TEMP_ENDPOINT))) { Console.WriteLine(string.Format("Capabilities '{0}' and '{1}' are required to run this sample", CapabilityType.SUB_FLOW_GUARANTEED, CapabilityType.TEMP_ENDPOINT)); return; } #region Provision an exclusive queue EndpointProperties endpointProps = new EndpointProperties(); // Set permissions to allow all permissions to others. endpointProps.Permission = EndpointProperties.EndpointPermission.Delete; // Set access type to exclusive. endpointProps.AccessType = EndpointProperties.EndpointAccessType.Exclusive; // Set quota to 100 MB. endpointProps.Quota = 100; string queueName = "solclient_dotnet_sample_ActiveFlowIndication_" + (new Random()).Next(1000); queue = ContextFactory.Instance.CreateQueue(queueName); Console.WriteLine(String.Format("About to provision queue '{0}' on the appliance", queueName)); try { session.Provision(queue /* endpoint */, endpointProps /*endpoint properties */, ProvisionFlag.WaitForConfirm /* block waiting for confirmation */, null /*no correlation key*/); Console.WriteLine("Endpoint queue successfully provisioned on the appliance"); } catch (Exception ex) { PrintException(ex); Console.WriteLine("Exiting"); return; } #endregion FlowProperties flowProps = new FlowProperties(); // The Flow is created in a started state, so it is ready to receive messages. flowProps.FlowStartState = true; // AutoAck means that the received messages on the Flow // will be implicitly acked on return from the message event handler // specified in CreateFlow(). flowProps.AckMode = MessageAckMode.AutoAck; //Activate the active flow indication events flowProps.ActiveFlowInd = true; EventWaitHandle waitForFlowActiveEvent = new AutoResetEvent(false); flow1 = session.CreateFlow(flowProps, queue, null, SampleUtils.HandleMessageEvent, new EventHandler <FlowEventArgs>( delegate(object source, FlowEventArgs evt) { switch (evt.Event) { case FlowEvent.FlowActive: Console.Out.WriteLine("Flow 1 Active event received"); waitForFlowActiveEvent.Set(); break; } })); if (waitForFlowActiveEvent.WaitOne(5000, false)) { waitForFlowActiveEvent.Reset(); } else { // We did not get a FlowEvent.UpNotice within five seconds. Console.Out.WriteLine("Did not get a FlowEvent.FlowActive for flow 1 within 5 secs, exiting ..."); return; } flow2 = session.CreateFlow(flowProps, queue, null, SampleUtils.HandleMessageEvent, new EventHandler <FlowEventArgs>( delegate(object source, FlowEventArgs evt) { switch (evt.Event) { case FlowEvent.FlowInactive: Console.Out.WriteLine("Flow 2 Inactive event received"); break; case FlowEvent.FlowActive: Console.Out.WriteLine("Flow 2 Active event received"); waitForFlowActiveEvent.Set(); break; } })); Console.WriteLine("Flow 2 started."); Console.WriteLine("Stopping flow 1."); if (flow1.Stop() == ReturnCode.SOLCLIENT_OK) { Console.WriteLine("Flow 1 stopped."); } else { Console.WriteLine("Failure while stopping flow 1. Exiting ..."); return; } Console.WriteLine("Disposing of flow 1"); flow1.Dispose(); flow1 = null; Console.WriteLine("Flow 1 has been disposed"); if (waitForFlowActiveEvent.WaitOne(5000, false)) { waitForFlowActiveEvent.Reset(); } else { // We did not get a FlowEvent.UpNotice within five seconds. Console.Out.WriteLine("Did not get a FlowEvent.FlowActive for flow 2 within 5 secs, exiting ..."); return; } Console.WriteLine(string.Format("\nDone\n Sleeping for {0} secs before exiting ", Timeout / 1000)); Thread.Sleep(Timeout); } catch (Exception ex) { PrintException(ex); } finally { if (flow1 != null) { flow1.Dispose(); } if (flow2 != null) { flow2.Dispose(); } if (queue != null) { if (session != null) { session.Deprovision(queue, ProvisionFlag.WaitForConfirm, null); } queue.Dispose(); } if (session != null) { session.Dispose(); } if (context != null) { context.Dispose(); } // Must cleanup after. CleanupContext(); } }
/// <summary> /// Main function in the sample. /// </summary> /// <param name="args"></param> public override void SampleCall(string[] args) { #region Parse Arguments ArgParser cmdLineParser = new ArgParser(); if (!cmdLineParser.Parse(args)) { // Parse failed. PrintUsage(INVALID_ARGUMENTS_ERROR); return; } if (!SampleParseArgs(cmdLineParser)) { // Parse failed for sample's arguments. PrintUsage(INVALID_ARGUMENTS_ERROR); return; } #endregion #region Initialize properties from command line // Initialize the properties. ContextProperties contextProps = new ContextProperties(); SessionProperties sessionProps = SampleUtils.NewSessionPropertiesFromConfig(cmdLineParser.Config); #endregion // Define IContext and ISession. IContext context = null; ISession session = null; try { InitContext(cmdLineParser.LogLevel); Console.WriteLine("About to create the context ..."); context = ContextFactory.Instance.CreateContext(contextProps, null); Console.WriteLine("Context successfully created. "); Console.WriteLine("About to create the session ..."); session = context.CreateSession(sessionProps, SampleUtils.HandleMessageEvent, SampleUtils.HandleSessionEvent); Console.WriteLine("Session successfully created."); Console.WriteLine("About to connect the session ..."); if (session.Connect() == ReturnCode.SOLCLIENT_OK) { Console.WriteLine("Session successfully connected"); Console.WriteLine(GetRouterInfo(session)); } if (!session.IsCapable(CapabilityType.SUB_FLOW_GUARANTEED) || !(session.IsCapable(CapabilityType.TEMP_ENDPOINT))) { Console.WriteLine(string.Format("Capabilities '{0}' and '{1}' are required to run this sample", CapabilityType.SUB_FLOW_GUARANTEED, CapabilityType.TEMP_ENDPOINT)); return; } IQueue queue = null; if (cmdLineParser.Config.UseDurableEndpoint) { Console.WriteLine(string.Format("A non-temporary queue with name '{0}' must be provisioned and accessible on the appliance within the same user's Message VPN)", SampleUtils.SAMPLE_QUEUE)); queue = ContextFactory.Instance.CreateQueue(SampleUtils.SAMPLE_QUEUE); } else { Console.WriteLine("Creating a temporary queue"); queue = session.CreateTemporaryQueue(); } FlowProperties flowProps = new FlowProperties(); // The flow is created in a started state, so it is ready to receive messages. flowProps.FlowStartState = true; // ClientAck, which means that the received messages on the Flow // must be explicitly acked, otherwise they will be redelivered to the client // when the Flow reconnects. // ClientAck was chosen simply to illustrate ClientAck and that clients // can use AutoAck instead. flowProps.AckMode = MessageAckMode.ClientAck; flow = session.CreateFlow(flowProps, queue, null, // Demonstrates explicit client acknoweldgment of received messages. HandleMessageAndAck, SampleUtils.HandleFlowEvent); // Now publish a number of messages to the Queue. IMessage message = SampleUtils.CreateMessage(cmdLineParser.Config, session); message.Destination = queue; Console.WriteLine(string.Format("About to send {0} message(s) ...", cmdLineParser.Config.NumberOfMessagesToPublish)); // Send a number of messages to the Queue. for (int i = 0; i < cmdLineParser.Config.NumberOfMessagesToPublish; i++) { if (session.Send(message) == ReturnCode.SOLCLIENT_OK) { Console.Write("."); } Thread.Sleep(1000); // Wait for 0.5 seconds } Console.WriteLine(string.Format("\nDone\n Sleeping for {0} secs before exiting ", Timeout / 1000)); Thread.Sleep(Timeout); } catch (Exception ex) { PrintException(ex); } finally { if (flow != null) { flow.Dispose(); } if (session != null) { session.Dispose(); } if (context != null) { context.Dispose(); } // Must cleanup after. CleanupContext(); } }
public override void SampleCall(string[] args) { // Parse arguments and initialize Session properties. ArgParser cmdLineParser = new ArgParser(); if (!cmdLineParser.Parse(args)) { // Parse failed. PrintUsage(INVALID_ARGUMENTS_ERROR); return; } // Create Session properties from the command line options. SessionProperties sessionProps = SampleUtils.NewSessionPropertiesFromConfig(cmdLineParser.Config); try { InitContext(cmdLineParser.LogLevel); // Create and connect 'sessionA' with No Local delivery set to false. sessionProps.NoLocal = false; // No Local is set to 'false' by default. InitializeAndAssertCapabilities(ref context, ref sessionA, "sessionA", sessionProps); // Create and connect 'sessionB' with No Local delivery set to true. sessionProps.NoLocal = true; // <-- this is how we set NoLocal at the session level InitializeAndAssertCapabilities(ref context, ref sessionB, "sessionB", sessionProps); // Create a Flow to a temporary Queue within sessionA. IQueue queue = sessionB.CreateTemporaryQueue(); FlowProperties flowProps = new FlowProperties(); flowProps.NoLocal = true; // <-- this is how we set NoLocal at the flow level flowProps.BindBlocking = true; flowA = sessionA.CreateFlow(flowProps, queue, null, HandleMessageEvent, SampleUtils.HandleFlowEvent); flowA.Start(); // Add a Topic subscription to sessionB. ITopic topic = ContextFactory.Instance.CreateTopic(SampleUtils.SAMPLE_TOPIC); sessionB.Subscribe(topic, true /*wait for confirm*/); // Publish a Direct message to Topic T from each Session; verify it is not delivered locally. IMessage msg = ContextFactory.Instance.CreateMessage(); msg.BinaryAttachment = Encoding.ASCII.GetBytes(SampleUtils.MSG_ATTACHMENTTEXT); msg.Destination = topic; msg.DeliveryMode = MessageDeliveryMode.Direct; // Send from 'sessionA'. Console.WriteLine(string.Format("\nSending a direct message to topic '{0}' from sessionA", topic.ToString())); sessionA.Send(msg); Thread.Sleep(500); PrintCounters(); Console.WriteLine(string.Format("Expecting msgCounterForSessionB to be 1, it's '{0}'", msgCounterForSessionB)); Console.WriteLine(string.Format("Expecting msgCounterForSessionA to be 0, it's '{0}'", msgCounterForSessionA)); ResetCounters(); // Send from 'sessionB'. Console.WriteLine(string.Format("\nSending a direct message to topic '{0}' from sessionB", topic.ToString())); sessionB.Send(msg); Thread.Sleep(500); PrintCounters(); Console.WriteLine(string.Format("Expecting msgCounterForSessionA to be 0, it's '{0}'", msgCounterForSessionA)); Console.WriteLine(string.Format("Expecting msgCounterForSessionB to be 0, it's '{0}'", msgCounterForSessionB)); ResetCounters(); // Publish a message to the Queue on each Session; verify it is not delivered locally. msg.Destination = queue; msg.DeliveryMode = MessageDeliveryMode.Persistent; // Send from 'sessionA'. Console.WriteLine(string.Format("\nSending a persistent message to queue '{0}' from sessionA", queue.ToString())); sessionA.Send(msg); Thread.Sleep(500); PrintCounters(); Console.WriteLine(string.Format("Expecting msgCounterForFlowA to be 0, it's '{0}'", msgCounterForFlowA)); ResetCounters(); // Send from 'sessionB'. Console.WriteLine(string.Format("\nSending a persistent message to queue '{0}' from sessionB", queue.ToString())); sessionB.Send(msg); Thread.Sleep(500); PrintCounters(); Console.WriteLine(string.Format("Expecting msgCounterForFlowA to be 1, it's '{0}'", msgCounterForFlowA)); ResetCounters(); Console.WriteLine("\nDone"); } catch (Exception ex) { PrintException(ex); } finally { if (flowA != null) { flowA.Dispose(); } if (sessionA != null) { sessionA.Dispose(); } if (context != null) { context.Dispose(); } // Must cleanup after. CleanupContext(); } }