I created a Azure Topic and a subscription with Session-Enabled to be true. I can send a message to the topic with a non empty SessionId. But When I tied to read the message with the following code, it throws the timeout execption at subClient.AcceptMessageSession. Did I do anything wrong? The similar code (with QueueClient) works fine for a direct session enabled Azure Queue.
SubscriptionDescription subscriptionDescription = namespaceManager.GetSubscription(Topic_Name, Subscription_Name);
SubscriptionClient subClient = SubscriptionClient.CreateFromConnectionString(connectionString, Topic_Name, Subscription_Name);
if (subscriptionDescription.RequiresSession)
{
msgSession = subClient.AcceptMessageSession(TimeSpan.FromSeconds(120));
if (msgSession != null)
{
message = msgSession.Receive(TimeSpan.FromSeconds(5));
}
}
else
message = subClient.Receive(TimeSpan.FromSeconds(5));
Related
I'm creating a sample .net core solution in local and IIS larger message consuming in a queue within a second but I'm deployed in Linux server to could take more time to consume a message in a queue. I don't know how to resolve it kindly help me. Below I attached my sample code here.
string topic = "QueueTest";
QueueConnectionFactory.OptimizeAcknowledge = true;
QueueConnectionFactory.AlwaysSyncSend = false;
using (IConnection connection = QueueConnectionFactory.CreateConnection("admin", "admin"))
{
connection.Start();
Apache.NMS.ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge);
using (IDestination dest = session.GetQueue(topic))
using (IMessageConsumer consumer = session.CreateConsumer(dest))
{
// TimeSpan span4 = TimeSpan.FromSeconds(3);
IMessage msg = consumer.Receive();
if (msg != null)
{
ITextMessage message = msg as ITextMessage;
string data = message.Text;
}
}
}
Check for receiveBufferSize and sendBufferSize and you can add this to your connection url :
?transport.receiveBufferSize=65536&transport.sendBufferSize=16384
How to read the message from the service bus dead-letter queue? I'm able to read message-id and a sequence number of the message, but I need the actual message. Can someone help me with this? Is it possible to read the actual message?
Before reading message form deadletter queue, you should check what was the reason of fail? If some service was not available then Create WebJob and try below code and process messages.
public void GetDeadLetterMessagesAsync(string connectionString, string queueName)
{
var queueClient = QueueClient.CreateFromConnectionString(connectionString, QueueClient.FormatDeadLetterPath(queueName));
while (true)
{
BrokeredMessage bmessgage = queueClient.Receive();
if (bmessgage != null)
{
string msg = new StreamReader(bmessgage.GetBody<Stream>(), Encoding.UTF8).ReadToEnd();
//Custom business logic to prcess your message
bmessgage.Complete();
}
else
{
break;
}
}
}
If message having an issue then you should read and display message on UI so back office team can correct message otherwise it will fail again.
I am creating a sample Azure Service Bus application. I created a namespace, topic and Subscription. I have written test messages to the topic and if I go to the subscription in the portal, I see that I have a new message every time I write a new one using the writer application.
But when I go to pull the message, nothing is retrieved. In troubleshooting, I changed the subscription name to an incorrect value and received an error. I changed it back and I get no output and none of the messages are removed when I look in Azure portal. I'm stuck... this seems easy, but it isn't working.
string connectionString = "Endpoint=sb://redacted for obvious reasons";
SubscriptionClient Client = SubscriptionClient.CreateFromConnectionString(connectionString, "NewOrders", "AllOrders");
// Configure the callback options.
OnMessageOptions options = new OnMessageOptions();
options.AutoComplete = false;
options.AutoRenewTimeout = TimeSpan.FromMinutes(1);
Client.OnMessage((message) =>
{
try
{
Console.WriteLine("Body: " + message.GetBody<string>());
message.Complete();
Console.ReadLine();
}
catch (Exception)
{
// Indicates a problem, unlock message in subscription.
message.Abandon();
}
}, options);
It seems that it is not the code issue. I create a demo to retrieve message from topic, it works correctly.
Before I try to retrieve message from topic, I send the message to the topic or make sure that there are messages for subscription. We could check that from the portal
Send message code demo.
private static void SendMessages()
{
topicClient = TopicClient.Create(TopicName);
List<BrokeredMessage> messageList = new List<BrokeredMessage>
{
CreateSampleMessage("1", "First message information"),
CreateSampleMessage("2", "Second message information"),
CreateSampleMessage("3", "Third message information")
};
Console.WriteLine("Sending messages to topic...");
foreach (BrokeredMessage message in messageList)
{
while (true)
{
try
{
topicClient.Send(message);
}
catch (MessagingException e)
{
if (!e.IsTransient)
{
Console.WriteLine(e.Message);
throw;
}
}
Console.WriteLine($"Message sent: Id = {message.MessageId}, Body = {message.GetBody<string>()}");
break;
}
}
topicClient.Close();
}
I also try your mentioned code, it also works correctly for me.
We also could get the demo project from the cloud Project from the template. We also could get more info about How to use Service Bus topics and subscriptions from the document.
I have an application subscribed on Azure Servicebus Topic who is constantly receiving messages from Stream Analytics. But this application isn't every time subscribed on this Topic. How do I receive only the last message from the topic when the application do the subscription?
Based on your question and your comments, this is what I can advice you:
When your application starts, connect to the Azure ServiceBus Subscription and get all messages in the queue.
Remove all the previous messages (just complete it) and process the last message.
Then you can start listening to new incoming messages.
Based on this answer (Clearing azure service bus queue in one go) :
// Get the message receiver
var messagingFactory = MessagingFactory.CreateFromConnectionString("ServiceBusConnectionString");
var messageReceiver = messagingFactory.CreateMessageReceiver(SubscriptionClient.FormatSubscriptionPath("TopicName", "SubscriptionName"));
BrokeredMessage lastMessage = null;
while (messageReceiver.Peek() != null)
{
if(lastMessage != null)
{
// This was not the last message so complete it.
lastMessage.Complete();
}
// Batch the receive operation
var brokeredMessages = messageReceiver.ReceiveBatch(300).ToList();
//Get the last message and remove it from the list
lastMessage = brokeredMessages.Last();
brokeredMessages.RemoveAt(brokeredMessages.Count -1);
// Complete all the other messages
var completeTasks = brokeredMessages.Select(m => Task.Run(() => m.Complete())).ToArray();
// Wait for the tasks to complete.
Task.WaitAll(completeTasks);
}
if (lastMessage != null)
{
// Process your message
}
// Start listening to new incoming message
messageReceiver.OnMessage(message =>
{
// Process new messages
}, new OnMessageOptions());
I've written some code to delete test messages off a service bus topic. I'm the only one using this topic. It's using ReceiveAndDelete mode so I am assuming it's going to delete them, but every time I run the code it goes through this cycle of receiving messages, so I know it's not deleting them. What am I doing wrong?
public void TruncateTopic()
{
// reset topic for testing..
SubscriptionClient client = SubscriptionClient.CreateFromConnectionString(
connStr, QUEUENAME, "AllMessages",ReceiveMode.ReceiveAndDelete);
BrokeredMessage message = client.Peek();
while (message != null)
{
client.Receive();
message = client.Peek();
}
client.Close();
}
In your code you only do Peek on the Topic/Queue. Peek action never deletes the messages.
As you can clearly read from documentation Peek method only peeks into the subscription without actually receiving the message.
The ReceiveAndDelete receive mode will well work when you not just Peek the messages but Receive them instead! That is why it is named ReceiveAndDelete but not PeekAndDelete.
Change your code to:
BrokeredMessage message = client.Receive();
while (message != null)
{
message = client.Receive();
}
And everything will be fine.