It is possible have one MSMQ queue in one machine and read masseges from that queue from another machine?
If yes, what is the path i should use in Create method from MessageQueue class?
Thanks
It's definitely possible to read messages from a queue on another machine, depending on which version of Windows you're running. It seems you're also asking if it's possible to create message queues on another machine. According to the documentation here, you simply use the format "MachineName\Private$\QueueName" for a private queue or "MachineName\QueueName" for a public queue.
In my experience, getting the permissions set up to allow remote message queue reading is a bit tricky; getting the right permissions set for allowing the creation of message queues might be even trickier. You may want to consider using pre-created message queues.
Related
I'm doing a simple Messaging system for a Windows Mobile in C#. The application consists in sending and receiving simple text messages using a Web service communication. The messages queue should be persistent, avoiding data lost if the connection with the web service fail or the application crash.
I know about MSMQ, RabbitMQ, DotNetMQ, but they should be installed in the device and this are really simple devices, I don't want to install any other tool in each of the mobiles just for this simple task.
I already implemented the function to write an XML serialized queue with the messages into a file and I read and write all the time from this file.
I'd appreciate any better idea to solve this problem.
Thanks
MSMQ does not need to be installed is supported natively on Windows Mobile 6.5 devices. BTW: there are still many vendors in industrial area providing WM65 based devices, so this is not yet outdated.
The Windows Mobile (CE) based MSMQ is persistent and simple to use. It is normally used for interprocess-communication on the device or for client server communication (which requires MSMQ installed on the 'server').
So, the main thread creates a MSMQ, one thread in your process fills the MSMQ and another can 'peek' and, after successful transmission, 'dequeue' messages from the same MSMQ. See here for a simple example.
I don't really know what's available for Windows Mobile but you can try using basic queue (normal or concurrent, depends on your app) accompanied by two files. Write everything that is enqueued to one "Enqueue log" file and write everything that is dequeued to another "Dequeue log" file.
This two files can always give you enough information to restore your queue, and you don't need to fully rewrite/fully serialize your queue. It needs to be implemented by hand though.
About dequeue:
for example, lets say I have a queue with 3 messages: "one", "two", "three". Now I want to send the next (also the first) message "one". I append the line "one - starting removal from queue" to my "dequeue log", then I dequeue "one" from my queue object and send it where I want it to be sent to. When it is sent, I append " - finished removal from queue" to my "dequeue log". Now I have a line "one - starting removal from queue - finished removal from queue" in my log file.
It doesn't matter when do I crash, I'll always will be able to restore the state of queue object (at least for now I fail to see any logic mistakes in this process). So imho it's not tricky but still... some code should be coded. And it would be a few pages of code.
Sure, there is a better idea is to use SQLite.
I hope this will help you.
I'm working on a task where I'm trying to insure delivery of data to a database in the order in which it is written. The database will be located on another machine, and it's possible that the database machine could fail while the sending computer continues to queue up database messages.
I'm trying to use WCF for this task and from my initial reading believed that this might be possible using WCF with message queue and a ReceiveContext enabled channel. The documentation states that ReceiveContext 'enables an application to decide whether to access the message or leave it in the queue for further processing.'
The problem that I've encountered is that if I call the Abandon method indicating that the message has not been successful processed and should be left on the queue, WCF appears to place the message at the back of the queue instead of leaving it at the front of the queue. Since I need to write the messages to the database in the order they were originally sent this solution will not work.
Is there any way to force WCF to 'peek' at a message before removing it or cause an abandon message to be placed at the front of the queue? If not could anyone suggest a method of accomplishing what I'm attempting to do without having to write a lot of code from scratch.
Thanks,
Al
I create a queue on my local machine in some other process as follows:
MessageQueue.Create(#".\private$\sampleQueue");
And in my reader process, I attach to it as follows:
var queue = new MessageQueue(#".\private$\sampleQueue");
When I try to do queue.Peek(), I get an access denied exception. I'm not on a domain, this is just my local workgroup computer. Any ideas?
MSMQ uses different protocols for it's work:
Pushing information (sending messages) uses MSMQ protocol.
Pulling information (receiving messages, getting properties, etc) using RPC protocol.
If it is not a simple permissions issue (which it is very likely to be) then you need this blog post:
Understanding how MSMQ security blocks RPC traffic
http://blogs.msdn.com/b/johnbreakwell/archive/2010/03/24/understanding-how-msmq-security-blocks-rpc-traffic.aspx
Cheers
John
If you r-click on the queue in Computer Management and select properties, do you have the appropriate permissions set on the Security tab?
The credentials used by the process that creates the queue must be different from the credentials of the process used to read the queue. If that is the way it must be, then you will need to specifically grant the needed read permissions on the queue after you create it.
How do you 'verify' that a message sent using MSMQ to a private local queue was actually delivered? I'm especially thinking of a scenario where the listener (a C# service in my case) is not running and therefore delivery can't be successful.
You can only guarantee that it can get to the queue without taking extra steps. To deal with the "not running receiver" scenario, you would need to code the receiver to send a message back to the server when it processes the message. The original sender would be responsible for tracking the sent messages and verifying that the client has recieved them.
That's one of the decisions you should be taking when deciding whether or not to use MSMQ as opposed to a remoting or a web service scenario. For example, we had a project used for notifying all of our retail locations when an emergency occurred (such as a product recall/food safety issue.) We needed to know immediately if the store's listener was running so we chose remoting, and when the sender received an error indicating one of the listeners was not listenting, we would need to pick up the phone and call.
Just something to keep in mind.
Edit - clarification
I was really giving out two options above.
Code the client to send a message back to the sender when it receives a message.
Use another option, such as remoting, where you can detect if the client is running and receives the message.
It's always sent to the queue.
If your service isn't running to receive it, it just sits there, waiting patiently, until someone receives it.
You know it's been sent to the queue because .Send() returns without crashing.
You can probably pull this info out using administrative queues
When you send a message you can specify the AcknowledgeType which will allow you find out (through positive or negative acknowledgement) whether the message reached the queue and/or was received from the queue. Acknowledgements are sent as messages, by MSMQ, to the AdministrativeQueue so make sure you assign that property on the Message object.
You can check the administrative queue for acknowledgements by correlation ID which is ID of the original message.
How do I send a message to a public queue of another computer msmq in c#?
You use a queue name like this:
FormatName:DIRECT=OS:machine\queue
Where machine is the name of the machine and queue is the name of the queue. Note that this will bypass all of the Active Directory routing and stuff that MSMQ normally does. Depending on your requirements, that may or may not be OK.