Where did my Message Queue sent messages go? - c#

I have an application that uses MSMQ that is working very well when both the producer and consumer are on
the same machine.
Yesterday, for the first time, I tried to create another producer that would run on a separate machine. The
queue is a private queue, and before, both sides referenced it as
string strQueueName = ".\Private$\MyQueue";
I tried several ways to reference this queue from the remote machine. My server name is "groucho",
so I tried
string strQueueName = "groucho\Private$\MyQueue";
but this consistently threw an "invalid queue path name" exception.
A fellow developer suggested I try the following, which avoids the exception:
string strQueueName = "FORMATNAME:DIRECT =OS:grouch\\private$\\SDVQueue";
This no longer throws the exception, but it does not seem to work, either, as I do not
see the messages in the queue.
The server is Windows Server 2008 R2. The queue is set up (I just noticed) so that
"Everyone" can Receive and Peek, but not Send, but when I try to add "Send", I get
an error dialog that says "The security descriptor cannot be set, Error: Access is denied".
I do have Admin privileges on this box.
I know from reading other posts that there is all kinds of security that comes into play,
but I do not see any errors in the event logs on either the sender or the host machine.
If this is a security issue, how can I see what the issue is?
Thanks!
Here is the complete test code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Messaging;
namespace RemoteQueue
{
class Program
{
static void Main(string[] args)
{
string name = "FORMATNAME:DIRECT =OS:groucho\\private$\\SDVQueue";;
string input = null;
MessageQueue queue = null;
try
{
queue = new MessageQueue(name);
string key = "key";
for (int i = 0; i < 200; i++)
{
Message msgToSend = new Message();
string value = "value_" + i;
msgToSend.Body = string.Format("{0},{1}", key, value);
Console.WriteLine("Sending message " + i);
queue.Send(msgToSend, "otherpart");
}
}
catch (MessageQueueException me)
{
Console.WriteLine("ERROR: caught message queue exception: " + me.Message);
}
Console.WriteLine("Type any key to exit...");
input = Console.ReadLine();
}
}
}

If you send a message from one server and then look in your outbound queues, you should see a temporary queue which has been created with the intention of transmitting your message. You should be able to see your message on the queue.
Now go onto the receiving server.
In order to set permissions on the queue you need to take ownership of it.
In the queue properties -> Security tab -> Advanced -> Owner tab -> Change Owner to. You should see your windows principal in the list.
This will enable you to set the send permissions. Once this has been done check the outbound queues on the sending server and the message should now have been transmitted.
Hope this helps.

Add the following to your example. It should show up in the dead letter queue, if its not getting processed by the server.
...
queue = new MessageQueue(name);
queue.DefaultPropertiesToSend = new DefaultPropertiesToSend();
queue.DefaultPropertiesToSend.UseDeadLetterQueue = true;
....

Could be a security issue on your msmq server.
Try setting the 'everyone full control' on the queue

Related

NetMQ multiple publishers

I am running a pub-sub set-up that works very well for a single publisher and multiple subscribers.
But I now wish to have several publishers publishing to the same "Channel", when I try this, the second time I try to Bind I get an address-already-used error.
Why can't I have a second publisher?
This is for a high-throughput application approx 250K messages/sec and a quick read of xPub-xSub suggests an intermediary will add overhead.
private void BackgroundProcess()
{
int msgSeqNum = 0;
using (var server = new PublisherSocket())
{
server.Options.SendHighWatermark = 1000;
server.Bind(Connection);
var address = Key;
string txt;
while (true)
{
if (O.TryTake(out txt, 60000))
{
msgSeqNum++;
server.SendMoreFrame(address).SendMoreFrame(msgSeqNum.ToString()).SendMoreFrame(DateTime.UtcNow.ToString("yyyyMMddTHHmmssffffff")).SendFrame("Whatever");
}
}
}
}
Netmq either works with a one on one socket set or a one to many socket set. You are getting close, you will need the xpub xsub to work as a proxy netmq actually provides one for this purpose.
https://netmq.readthedocs.io/en/latest/xpub-xsub/
As for why, this is a limitation of the underlying tcp layer, you can’t bind multiple tcp listeners to a single port afaik

RabbitMQ throws Shared Queue closed error

We have been using RabbitMQ as messaging service in the project. We will be pushing message into a queue and which will be received at the message consumer and will be trying to make entry into database. Once the values entered into the database we will be sending positive acknowledgement back to the RabbitMQ server if not we will be sending negative acknowledgement.
I have created Message Consumer as Windows service.Message has been successfully entered and well received by the message consumer(Made entry in table)but with an exception log "Shared Queue closed".
Please find the code block.
while (true)
{
try
{
if (!Connection.IsOpen || !Channel.IsOpen)
{
CreateConnection(existConnectionConfig, QueueName);
consumer = new QueueingBasicConsumer(Channel);
consumerTag=Channel.BasicConsume(QueueName,false,consumer);
}
BasicDeliverEventArgs e = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
IBasicProperties props = e.BasicProperties;
byte[] body = e.Body;
bool ack = onMessageReceived(body);
if (ack == true)
{
Channel.BasicAck(e.DeliveryTag, false);
}
else
Channel.BasicNack(e.DeliveryTag, false, true);
}
catch (Exception ex)
{
//Logged the exception in text file where i could see the
//message as "Shared queue closed"
}
}
I have surfed in net too but couldn't able to what the problem. It will be helpful if anyone able to help me out.
Thanks in advance,
Selva
In answer to your question, I have experienced the same problems when my Web Client has reset the connection due to App Pool recycling or some other underlying reason the connection has been dropped that appears beyond your scope. You may need to build in a retry mechanism to cope with this.
You might want to look at MassTransit. I have used this with RabbitMQ and it makes things a lot easier by effectively providing a management layer to RabbitMQ. MassTransit takes away the headache of retry mechanisms - see Connection management. It also provides a nice multi threaded concurrent consumer configuration.
This has the bonus of your implementation being more portable - you could easily change things to MSMQ should the requirement come along.

Cant consume message from Topic in activemq

I am new to activemq. T want to ask a question about the topics of Activemq. I succeed to get a message from a queue. Also I can send message to topic/Queue, but I can't get a message from Topic.
I have tried using Java Code. The result is the same.
The following is my core code:
connection.ClientId = clientId;
connection.Start();
using (ISession session = connection.CreateSession())
{
ITopic topic = new Apache.NMS.Commands.Topic(topicName);
IDestination destination = SessionUtil.GetDestination(session, topicName,
DestinationType.Topic);
using (IMessageConsumer consumer = **session.CreateDurableConsumer**(topic, "news", null, false))
{
**consumer.Listener += new MessageListener(consumer_Listener);**
//**IMessage iMsg = consumer.Receive();**
// if (iMsg != null)//{
// ITextMessage msg = (ITextMessage)iMsg;
// return msg.Text;
// }
//else
//return iMsg;
}
}
I also using: IMessage iMsg = consumer.Receive();
IMsg always null(topicname has messages. How can I consume topic's message?
The Messages would need to have been sent after the Topic consumer was created. A Topic is fire and forget, if there are no consumers then the message is discarded. Any consumer that comes online will only receive message sent after that time unless it is either a Durable Topic consumer or a Queue consumer.
In the case of a durable consumer you must have created an instance of it so there is a subscription record before those message were sent to the Topic. So I would guess your problem is that you didn't subscribe this consumer before and so the Broker was not storing any Messages for it.
I was so stupid about the phrase "using".Beacause I use "using" open connection and session. when the code block was excuted, the connnection/session is disappear. Now I dont use "using" block to cerate connection. just like normal code. It works. also I build "Global.asax" file. The program can listener Topic once started up. At the same time, I write a function to colse the connection.I tested. Once a message was sent to the topic, the Onessage() function would be exectued.
just resolve my problem.maybe you would have better answer.Thanks Tim.

MSMQ Remote Private: UnsupportedFormatNameOperation after one use

I am new to MSMQ and suspect I either have my queues configured wrong or programmatically (is that a word?)causing them to get hung up.
When everything starts I can send one message and that works wonderfully. I can see (ie via mmc on that machine) the message in the remote machine queue. I then go to access it and I get my UnsupportedFormatNameOperation error. If I try to send another message I get the same error in the send method that just worked a few seconds earlier.
What is even more frustrating is that my catch is NOT picking up the exception so I was unaware and looking elsewhere (read wasting time) till I explored the queue object in the debugger.
Now if I reset the Message Service on remote I lose my message in the queue and still get the same error. If I reboot same result.
On local (dev machine) if I reset the Message Service I still get the error. If I reboot something gets recycled and I can send exactly one message again.
Further after reboot of dev machine and exploring the queue object on the first run I find that I am getting the error the FIRST time around but it still sends the message.
So I am clearly doing something wrong but clueless as to what.
Here is my send code:
private void SendLoginMessage(...bunch of parms)
{
//hardcoded path? yup!!
MessageQueue msmq = new MessageQueue(#"FormatName:DIRECT=OS:W2K8R2_SQL2K8R2\private$\best_simulator");
try
{
LoginStatusMessage LgnMsg = new LoginStatusMessage()
{
...assign parms to my
};
msmq.Send(LgnMsg);
}
catch (MessageQueueException msmqex)
{
MessageBox.Show(msmqex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
msmq.Close();
}
}
The description for UnsupportedFormatNameOperation is
The requested operation for the specified format name is not supported.
Message Queuing returns this error when the requested operation is not supported for the specified format name. Operations include trying to open a queue to receive messages by specifying a direct format name.
So I guess your problem may be at your receive code.

Resend to MSMQ after exception

I'm trying to put a Message back into an MSMQ when an exception is thrown. The following code appears to work but the Message is not put back in the queue?
Message msg = null;
try
{
MessageQueue MQueue = new MessageQueue(txtMsgQPath.Text);
msg = MQueue.ReceiveById(txtQItemToRead.Text);
lblMsgRead.Text = msg.Body.ToString(); // This line throws exception
}
catch (Exception ex)
{
lblMsgRead.Text = ex.Message;
if (msg != null)
{
MessageQueue MQ = new MessageQueue(txtMsgQPath.Text);
MQ.Send(msg);
}
}
Couple of points: The best way to do this would be using a transaction spanning both queues; that way you'll know you won't lose a message.
The second part of it is to be careful about how the queues are created and how you submit messages to the second queue. In particular, MSMQ sometimes appears to "fail silently" when sending a message (though in reality an error message is recorded elsewhere in the dead letter queues), particularly if the transactional options of the send don't match the transactional nature of the target queue.
Is it really your intention to send that message back to the originator? Sending it back to yourself is very dangerous, you'll just bomb again, over and over.
I believe that you're looking to "Peek" at the message. Use: MessageQueue.Peek and if you succeed, then consume the message.
I managed to get the code above to work by creating a new queue and pointing the code at the new queue.
I then compared the 2 queues and noticed that the new queue was multicast (the first queue wasn't) and the new queue had a label with the first didn't. Otherwise the queues appeared to be the same.

Categories

Resources