Windows Message Queue, message does not arrive on server - c#

currently I am trying to write something in a transactual message queue on a remote machine:
string queueName = "FormatName:Direct=OS:servername\\private$\\testqueue";
var msgQueue = new MessageQueue(queueName);
var msg = new Message("Some body...");
msgQueue.Send(msg, MessageQueueTransactionType.Single);
My local machine shows me a new message in the outgoing folder (if I pause it), it shows the correct IP and the numbers of messages change to 0, if I unpause it. So I guess the code part is correct.
But it never appears on the target message queue.
Security on the target queue is set to "allow everyone everything".
edit:
End2End Tracing says:
On local machine:
Message with ID {...} queued in DIRECT=OS...
Message sent over network
On server:
Message came over network
But it's still not showing up the in message queue. Any ideas?

Related

Azure Service Bus - Leave message

(FYI - I am new ASB)
A couple of questions around Azure Service Bus:
How do you get a message from a Queue but leave it there until its' TTL expires? I would have thought simply not calling CompleteMessageAsync would do just that, but it appears to get removed regardless.
How do get a message from a Queue, but only dequeue (remove) it when received by a specific receiver?
Message.ApplicationProperties["ReceiverId"].ToString() == "123"
// now you can remove it
Thanks
How do you get a message from a Queue but leave it there until its' TTL expires?
You can peek at messages rather than receive them. The problem is that the message will be picked up again and again until the delivery count exceeds the maximum and the message will dead-letter, which you don't want to happen. I would review what you're trying to achieve here as it's a contradictory setup. You want the message to have a TTL in anticipation that it's not picked up, but then you want to probe it until TTL expires continuedly.
How do get a message from a Queue, but only dequeue (remove) it when received by a specific receiver?
My advice is don't use a queue for that. If you target a specific destination, express it with your entity topology. For example: publish a message on a topic and have different subscriptions based on the subscriber identification. That way you can have messages for specific subscribers, where a logical subscriber can be scaled out.
1-Use the PeekMessage:
You can peek at the messages in the queue without removing them from
the queue by calling the PeekMessages method. If you don't pass a
value for the maxMessages parameter, the default is to peek at one
message.
//-------------------------------------------------
// Peek at a message in the queue
//-------------------------------------------------
public void PeekMessage(string queueName)
{
// Get the connection string from app settings
string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];
// Instantiate a QueueClient which will be used to manipulate the queue
QueueClient queueClient = new QueueClient(connectionString, queueName);
if (queueClient.Exists())
{
// Peek at the next message
PeekedMessage[] peekedMessage = queueClient.PeekMessages();
// Display the message
Console.WriteLine($"Peeked message: '{peekedMessage[0].Body}'");
}
}
https://learn.microsoft.com/en-us/azure/storage/queues/storage-dotnet-how-to-use-queues?tabs=dotnet
2-you can also use PeekMessage, check for the property you want (ReceiverId), and it case it's the right one, just complete the message:
// ServiceBusReceiver
await receiver.CompleteMessageAsync(receivedMessage);

How to see new queue MSMQ messages in queue that is bigger than 800-1500 messages?

Does the following window:
Computer Management -> Message queueing -> Private queues -> {MyQueue} -> Queue messages
show all the messages from queue or some first 1000 ? And how to see all the messages?
In detail:
I have a private transactional MSMQ queue and it is displyed correctly in Queue messages window until the number of messages in the queue exceedes 800-1500. Then, when new message is added, it does not appear in the {MyQueue} -> Queue messages window, however, in Message Queueing -> Private Queues window I can see that the number of messages has grown in myqueue.
I tried to add a message via code (the behaviour is as described above):
// Create MSMQ message
var msg = new Message();
msg.Body = "Hello world";
msg.Label = "Now you see me";
msg.UseDeadLetterQueue = true;
msg.UseJournalQueue = true;
msg.AcknowledgeType = AcknowledgeTypes.FullReachQueue | AcknowledgeTypes.FullReceive;
msg.AdministrationQueue = new MessageQueue(#".\private$\audit");
// Send MSMQ message
var mq = new MessageQueue(#"FormatName:DIRECT=OS:.\private$\myqueue");
mq.Send(msg, MessageQueueTransactionType.Single);
What is more interesting, I can retrieve the "invisible" message in code:
// Retrieve MSMQ message
mq.MessageReadPropertyFilter.SetAll();
var allMessages = mq.GetAllMessages();
DateTime today = DateTime.Now.Date;
var messages = allMessages.Where(m => m.ArrivedTime > today).OrderByDescending(m => m.ArrivedTime).ToList();
There are no explicit limits on this queue set.
How could I see all the messages in the queue?
a) in Computer Management -> Message queueing -> Private queues -> {MyQueue} -> Queue messages
b) or in some other free tool ?
I think it's a limitation in windows.
However, I can suggest
MSMQ QXplorer
Free and Open source.
http://msmqqxplorer.svn.sourceforge.net/
latest download available at:
http://sourceforge.net/projects/msmqqxplorer/files/latest/download?source=files

TcpClient connection status issue on Network Down

I have a TcpClient which i am connecting to the machine and everything is working fine.Now one extra step i want to monitor the connection status on very 60 seconds by the help of timer.As per the basic research of the topic i got to know that there is no direct way to test it .So i tried to get it by the response of the recent message sent to the machine when the application goes out of the network.
Here is the code..
// Find out whether the socket is connected to the remote host.
//Send a message to Machine
try
{
byte[] notify = Encoding.ASCII.GetBytes("Hello");
stream.Write(notify, 0, notify.Length);
}catch { }
//Check if it reached to machine or failed
bool getConnectionStatus = client.Connected;
if (getConnectionStatus == true)
{
//Do nothing
}
else
{
//Stop the thread
_shutdownEvent.WaitOne(0);
_thread.Abort();
//Start Again
_thread = new Thread(DoWork);
_thread.Start();
}
But the most astonishing thing that is happening in this case is that if the machine is out of the network then also while writing the first time it is able to write and and that's why connection status is coming as connected although it is out of the network.Second time when it is trying to send data it is failing and like expected status is disconnected.
The main problem that i am facing is that once it is disconnected from the network why it is able to send the data .Due to this i loosing all the buffer data which is stored in the machine by that time when network goes off.
Please help me..
Under the hood, the Write operation just sends the data to the network layer; you may get a "success" result before an attempt is made to transmit the data. The network layer may even delay sending the data for a while if the data is small, in an attempt to send one batch of a few messages at once.
What Alex K. said with a few words is that the most reliable way to check a network connection is to wait for a response. If no such response is received within a certain amount of time, the connection is lost.
Lets say you keep using "Hello" and the server should respond with "Yeah!". On the client side, you could extend your current code with:
try
{
byte[] notify = Encoding.ASCII.GetBytes("Hello");
stream.Write(notify, 0, notify.Length);
byte[] notifyResult = new byte[5];
int bytesRead = stream.Read(notifyResult, 0, 5);
if (bytesRead == 0)
{
// No network error, but server has disconnected
}
// Arriving here, notifyResult should contain ASCII "Yeah!"
}
catch (SocketException)
{
// Network error
}
On the server, you should recognize the "Hello" being sent, and simply respond with "Yeah!". I don't know what your server currently does, but it could be something similar to:
switch (receivedMessage)
{
case "Hello":
stream.Write(Encoding.ASCII.GetBytes("Yeah!"), 0, 5);
break;
}
Note that you should consider wrapping your messages in information packets, ie:
<Message Type> <Message> <Terminator Character>
ie. "KHello\n"
Or
<Size of Message> <Message Type> <Message>
ie. "0005KHello"
Where message type 'K' is a Keep-alive message, the newline "\n" the terminator character and "0005" the message length excluding the message type.
This way the server will always be able to tell whether it has received the full message, and the message type could indicate whether "Hello" was sent as data or as a keep-alive packet.

How to use the MessageReceiver.Receive method by sequenceNumber on ServiceBus

I'm trying to resubmit a message from a deadletter queue.
I am can replay a message on a dead letter queue, thats fine.
The problem is when I want to now delete this from the deadletter queue.
Here is what I am trying to do:
var subscription = "mySubscription";
var topic = "myTopic";
var connectionString = "connectionStringOnAzure";
var messagingFactory = MessagingFactory.CreateFromConnectionString(connectionString);
var messageReceiver = messagingFactory.CreateMessageReceiver(SubscriptionClient.FormatDeadLetterPath(topic, subscription), ReceiveMode.ReceiveAndDelete);
long messageSequenceNumber = 835;
var brokeredMessage = messageReceiver.Receive(messageSequenceNumber); // this part fails
// mark message as complete to remove from the queue
brokeredMessage.Complete();
I get following error message:
Microsoft.ServiceBus.Messaging.MessageNotFoundException : Failed to lock one or more specified messages. The message does not exist..TrackingId:ae15edcc-06ac-4d2b-9059-009599cf5c4e_G5_B15,TimeStamp:8/13/2013 1:45:42 PM
However, instead of specifying a message sequence number and I just use the ReceiveBatch as shown below, it is fine.
// this works and does not throw any errors
var brokeredMessages = messageReceiver.ReceiveBatch(10);
Am I missing something? Or is there another way of reprocessing deadletters and removing them?
The deadletter queue is processed in sequence just like any other queue.
The Receive(seqNo) method is used in combination with Defer(), which puts the message into a different secondary Queue - the "deferral queue". The deferral queue exists for scenarios where you are getting messages out of the expected order (eg. in a state machine) and need a place to put the messages that arrived early. Those you can park with Defer() and make a note of that (probably even in session state) and then pull the messages once you're ready to do so. The Workflow Manager runtime used by SharePoint uses that feature, for instance.
After creating receiver you can politely start receiving all messages (without being picky) till you encounter message with your SequenceNumber, call Complete() on the message and stop iterating the queue. i.e
while (true)
{
BrokeredMessage message = receiver.Receive();
if (message.SequenceNumber == sequenceNumber)
{
message.Complete();
break;
}
}
Without completing message it remains in the queue and that's what you want (at least in .NET 4.5. Worth to note that if your Sequence Number is not found Receiver will loop the queue indefinitely.

clear Message Queue in C#

I use the Message Queue to send messages from one application to the other one (this has to work only on one particular machine)
I create the queue like this on the receiver side:
string queueName = ".\\private$\\WZMSGQ";
if (MessageQueue.Exists(queueName))
msgQueue = new MessageQueue(queueName);
else
msgQueue = MessageQueue.Create(queueName, false);
and after this I start the sender application, where I create the queue like that:
msgQueue = new MessageQueue(".\\private$\\WZMSGQ");
in the receiver Application I then retrieve new messages:
Message[] messages = msgQueue.GetAllMessages();
foreach (Message msg in messages){
doSomething();
}
Now I'd like to do two things:
I would like to clear the message queue when instantiating the new MessageQueue instance on the receiver machine such that all old messages are gone.
I'd like to delete the message queue when the program ends, such that it does not exist anymore if I start the application the next time
How can I do that?
MessageQueue.Purge and MessageQueue.Delete seem to be what you want, unless I have misread the question.

Categories