🎄 Happy Holidays! 🥳
Most of Solace is closed December 24–January 1 so our employees can spend time with their families. We will re-open Thursday, January 2, 2024. Please expect slower response times during this period and open a support ticket for anything needing immediate assistance.
Happy Holidays!
Please note: most of Solace is closed December 25–January 2, and will re-open Tuesday, January 3, 2023.
URGENT-Iterate through Solace Message Queue
We have read data from SOLACE queue in .Net using C# . However we are unable to iterate through SOLACE queue messages as we are not receiving Message ID or datetime.
Hence if any one could able to loop through the QUEUE message then please share the code snippet.
Thanks in advance
Sumeet
Best Answers
-
From the code snippet you have shown, can I assume that this originates from the
SolaceSamples/solace-samples-dotnet
GitHub repository, perhaps fromQueueConsumer.cs
? (here).If so, then this sample is designed to only receive one message from a queue before exiting. This due to the fact that
QueueConsumer.Run
method is executed on the main application thread. As soon as his method exits, the application will close. TheRun
method is put in a suspended state while waiting for the wait handle to complete:WaitEventWaitHandle.WaitOne()
.The message handler method,
HandleMessageEvent
, is invoked on a separate dispatcher thread and it callsWaitEventWaitHandle.Set()
which signals theRun
method to continue, causing the application to terminate.If you wish to continue reading messages from the queue, do not signal the wait handle or exit the application: simply comment out or delete the
.Set
call at the end of that method. You must keep one foreground thread alive at all times, as the Solace dispatcher thread runs as a background thread.I also observe you have commented out the Ack call - and that is fine if you wish to receive the messages without removing them from the queue, up to a point. Eventually, the broker will stop delivering messages when there are too many unacknowledged messages on a single consumer. If you wish to see all the messages and leave them on the broker, the preferred pattern is a queue browser instead.
0 -
Hello again @sumeet,
What does the publisher look like? (Is it also .NET?) What you may be seeing is a payload header which is automatically inserted when the publisher has specified a "text" payload or SDT (struct) payload instead of a raw, binary one.
Do you have access to the publisher code and can verify or modify it? Otherwise, there is a way of decoding this information correctly on receiver side in C#. I will have to look it up, though.
0
Answers
-
Greetings Sumeet,
A few questions: when you say iterate through the queue messages, are you looking to consume messages off the queue (e.g. to dequeue them), or do you mean you would like to read messages within a queue and leave them in place?
If are are receiving data from the queue, then the requisite headers should also be available within the same message received callback - assuming the headers were set in the first place. Do note that the majority of the ID and timestamp fields are unused by default, and must be specified by the publisher either at connection time or when the message was first published. The one exception to this is
IMessage.ReplicationGroupMessageId
which is assigned by the broker for all guaranteed (queued) messages.Can you provide some more clarity on what you are trying to do and perhaps share some minimal code showing what is not working?
1 -
Hi Nicholas,
When I say Iterate It means- say for example there are 10 messages in SOLACE queue(having Mesaage ID and dateTimestamp visible on Solace Management Console ) and we need to loop through them from oldest to Newest. Then what should be the ideal approach.
(Also consume messages off the queue or leave msgs. in queue after reading is what we have achieved already)
1)Best Approach to reading message list
What could be the correct way to loop as currently we tried is session.createflow. Below is the code snippetAlong with below session property
SocketReceiveBufferSizeInBytes = 8000000 to receive all the queue messages.Also we are trying to explore QueueBrowser. Can you pls let us know if this is a better technique of reading a list of multiple messages(
)
If possible can you share code snippet for c#.
*************************************************************************
Thanks a lot for sharing below information :)Thanks,
Sumeet0 -
From the code snippet you have shown, can I assume that this originates from the
SolaceSamples/solace-samples-dotnet
GitHub repository, perhaps fromQueueConsumer.cs
? (here).If so, then this sample is designed to only receive one message from a queue before exiting. This due to the fact that
QueueConsumer.Run
method is executed on the main application thread. As soon as his method exits, the application will close. TheRun
method is put in a suspended state while waiting for the wait handle to complete:WaitEventWaitHandle.WaitOne()
.The message handler method,
HandleMessageEvent
, is invoked on a separate dispatcher thread and it callsWaitEventWaitHandle.Set()
which signals theRun
method to continue, causing the application to terminate.If you wish to continue reading messages from the queue, do not signal the wait handle or exit the application: simply comment out or delete the
.Set
call at the end of that method. You must keep one foreground thread alive at all times, as the Solace dispatcher thread runs as a background thread.I also observe you have commented out the Ack call - and that is fine if you wish to receive the messages without removing them from the queue, up to a point. Eventually, the broker will stop delivering messages when there are too many unacknowledged messages on a single consumer. If you wish to see all the messages and leave them on the broker, the preferred pattern is a queue browser instead.
0 -
Please find a modified version of the QueueConsumer sample, below, which will read all messages from a queue until the user presses a key to close the application:
static void Run(string host, string vpnname, string username, string password) { try { // Initialize Solace Systems Messaging API with logging to console at Warning level var props = new ContextFactoryProperties() { SolClientLogLevel = SolLogLevel.Warning }; props.LogToConsoleError(); ContextFactory.Instance.Init(props); // Define context and session properties var contextProperties = new ContextProperties(); var sessionProperties = new SessionProperties() { Host = host, VPNName = vpnname, UserName = username, Password = password, ConnectRetries = DefaultConnectRetries, }; var queueName = "Q/tutorial"; var flowProperties = new FlowProperties() { AckMode = MessageAckMode.ClientAck }; // Create context and session instances using (var context = ContextFactory.Instance.CreateContext(contextProperties, null)) using (var session = context.CreateSession(sessionProperties, null, null)) { // Connect to the Solace messaging router Console.WriteLine($"Connecting as {username}@{vpnname} on {host}..."); var connectResult = session.Connect(); if (connectResult == ReturnCode.SOLCLIENT_OK) { Console.WriteLine("Session successfully connected."); using (var queue = ContextFactory.Instance.CreateQueue(queueName)) using (var flow = session.CreateFlow(flowProperties, queue, null, HandleMessageEvent, HandleFlowEvent)) { flow.Start(); Console.WriteLine($"Waiting for a message in the queue '{queueName}'..."); Console.WriteLine($"Press any key to exit. ----------------------"); Console.WriteLine(); Console.ReadKey(true); } } else { Console.WriteLine($"Error connecting, return code: {connectResult}"); } } } finally { // Dispose Solace Systems Messaging API ContextFactory.Instance.Cleanup(); } Console.WriteLine("Finished."); } static void HandleMessageEvent(object source, MessageEventArgs args) { var flow = source as IFlow; // Received a message Console.WriteLine("Received message."); using (IMessage message = args.Message) { // Expecting the message content as a binary attachment Console.WriteLine($"Message content: {Encoding.UTF8.GetString(message.BinaryAttachment)}"); // ACK the message flow.Ack(message.ADMessageId); } }
0 -
Hi Nicholas,
Yes the code sample belongs fron Solacesample-dotnet.
Have tried commenting // WaitEventWaitHandle.Set();
And could able to loop through.
Will also Analyse the above queueconsumer sample and keep you posted.
Well Thanks you for all the help and support!
Thanks,Sumeet
0 -
hi @nicholasdgoodman ,
Hope you are fine.
I am facing illegal character issue while Deserialize the queue message at my end .how to overcome it. Please suggest
Below is the string in bold
\u001f\0\u0004�y{"eThanks,
Sumeet Joshi
0 -
hi @nicholasdgoodman ,
Hope you are fine.
I am facing illegal character issue while Deserialize the queue message at my end .how to overcome it. Please suggest
Below is the string in bold\u001f\0\u0004�y
{"eThanks,
Sumeet Joshi
0 -
Hello again @sumeet,
What does the publisher look like? (Is it also .NET?) What you may be seeing is a payload header which is automatically inserted when the publisher has specified a "text" payload or SDT (struct) payload instead of a raw, binary one.
Do you have access to the publisher code and can verify or modify it? Otherwise, there is a way of decoding this information correctly on receiver side in C#. I will have to look it up, though.
0 -
Hi @nicholasdgoodman ,
Publisher is on JAVA.
Not having access to pub code. Have decode it using ASCII characters list for now. Thanks for the assistance.Regards,
Sumeet
0