protected virtual void SubscribeToTopic(ISession session, string topicName, string clientName, string subscriptionQueueName = null, SubscriptionOptions options = null) { if (string.IsNullOrEmpty(subscriptionQueueName)) { subscriptionQueueName = $"{clientName}_{typeof(TContent)}"; } this.subscriptionQueueName = subscriptionQueueName; log.Debug("Subscribing to topic {0} on {1} endpoint named {2}", topicName, options.Durable ? "durable" : "non-durable", subscriptionQueueName); ITopicEndpoint endpoint = null; if (options.Durable) { endpoint = ContextFactory.Instance.CreateDurableTopicEndpointEx(subscriptionQueueName); session.Provision(endpoint, new EndpointProperties { DiscardBehavior = EndpointProperties.EndpointDiscardBehavior.NotifySenderOn, AccessType = options.Exclusive ? EndpointProperties.EndpointAccessType.Exclusive : EndpointProperties.EndpointAccessType.NonExclusive }, ProvisionFlag.WaitForConfirm | ProvisionFlag.IgnoreErrorIfEndpointAlreadyExists, null); } else { endpoint = session.CreateNonDurableTopicEndpoint(subscriptionQueueName); } try { this.flow = session.CreateFlow( new FlowProperties { AckMode = (options?.SubscriptionType ?? SubscriptionType.PeekAndLock) == SubscriptionType.PeekAndLock ? MessageAckMode.ClientAck : MessageAckMode.AutoAck }, endpoint, ContextFactory.Instance.CreateTopic(topicName), HandleMessage, FlowEventHandler); flow.Start(); this.workerThread = new Thread(new ThreadStart(RunMessageLoop)); workerThread.Start(); } catch (global::SolaceSystems.Solclient.Messaging.OperationErrorException ex) { log.Error($"Failed to subscribe to topic. ErrorInfo: {ex.ErrorInfo}"); throw; } }
/// <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(); } }