I have a WCF service that can receive several requests/minute (or seconds) that need to write information to the database. Rather than write it synchronously, I would like to place these requests in some sort of a queue on the server so that another proces can come along and process them. The client just needs an acknowledgement that the request was received. I have read a lot about MSMQ and WCF etc, but it seems that with MSMQ you write to the queue from client and not to the web service, which is not what I want.
Is there a way to do the following inside a WCF method that does not involve a database. Perhaps i have not grasped the concept of MSMQ right.
public bool ProcessMessage(string message)
{
if(IsValid(message))
return AddToQueue(message);
return false;
}
EDIT: I need to validate the message before writing to the queue.
I do this currently in an application I created. A WCF service is hosted as an HTTP Service on IIS. It accepts calls, and packets of data, I take that data, validate it (tell the caller it's wrong or not) then send the data to another WCF service that is using netMSMQ binding, that service then does the final writing to the database. The good thing about this is it will queue up on one MSMQ and the WCF Service that is bound to this MSMQ pops off one message at a time and processes it. The HTTP WCF service can then handle as many requests as it wants and does not have to worry about pooled up messages as that's the job of the WCF/MSMQ-bound service. The common name for this pattern is a Bridge framework.
ETA: the second service (the MSMQ-bound WCF Service) is run as a Windows service always on. It also handles separation of concerns. The HTTP service validates and does not care about the database, the other service handles writing to the Database.
The point of using MSMQ should be to remove the need for your service to worry about queueing anything. MSMQ will guarantee that your messages get delivered in the proper order and that your service processes them in the proper order.
Your service shouldn't maintain a queue at all if you set this up properly.
Related
I have an application that places messages on MSMQ, than I have a WCF service that I want to automatically read these messages from MSMQ.
I do not want to trigger my WCF service but I want it to be notified whenever a message is pushed on MSMQ. I have found some stuff related to WAS and netMSMQBinding, but the details seems a little unclear about automatic notifications from MSMQ to WCF.
Any help/direction in this regard? Thanks.
What is it that you're trying to achieve?
There is really no such thing as "be notified when a message is pushed on MSMQ". MSMQ uses a pull model to retrieve messages from a queue, so there always needs to exist some kind of "listener" that reads messages from the queue and processes them.
In this case, this "listener" is provided by the WCF NetMsmq or MsmqIntegration bindings automatically, so the programming model for a WCF service that is exposed over MSMQ is just like that of a regular one-way service.
As you state, you can either host that WCF service using your own custom host (such as a Windows service), or, in many cases, the preferred method will be to host that service in IIS 7.X/8.X through WAS.
The following sample shows how to host an MSMQ service in WAS: http://msdn.microsoft.com/en-us/library/ms752246(v=vs.110).aspx
Notice that you do need some specific configuration in IIS to be able to host non-HTTP services, which includes enabling the "Non-HTTP Service Activation" feature. The following articles will be useful to get this done:
http://blogs.msdn.com/b/tomholl/archive/2008/07/12/msmq-wcf-and-iis-getting-them-to-play-nice-part-1.aspx
http://blogs.msdn.com/b/tomholl/archive/2008/07/13/msmq-wcf-and-iis-getting-them-to-play-nice-part-2.aspx
http://blogs.msdn.com/b/tomholl/archive/2008/07/14/msmq-wcf-and-iis-getting-them-to-play-nice-part-3.aspx
http://blogs.msdn.com/b/tomholl/archive/2008/05/17/building-a-pub-sub-message-bus-with-wcf-and-msmq.aspx
So I'm looking into implementing NServiceBus in our current setup and just trying to get a better understanding of how things should be setup.
Our current setup consists of multiple clients (websites, scheduled tasks, etc..) calling a WCF service we have set up for handling the sending of emails. Of course, if the service goes down then our clients start getting errors and all of those messages are then lost (one of the reasons we want an ESB).
I've seen how you can configure your WCF service to handle nservicebus messages in a pub/sub setup. What I'm not sure on is what is the best way to set it up.
Setup 1:
Client (Publisher) -> NServiceBus handler (Subscriber) -> WCF Service
In this case, to scale you'd increase the number of handlers (hosted nservicebus services?), keeping just the one WCF service.
Setup 2:
Client (Publisher) -> WCF Service (Subscriber)
This one you just increase the number of WCF services to scale (updates would be a nightmare).
I just started looking into the ESB architecture in general so if I'm completely off let me know. I'm essentially just wanting to know what is working for you, and what the "best practice" tends to be.
Thanks!
I'm not completely clear on what you need WCF for anymore if you implement this via NServiceBus. Is the WCF component required for anything besides receiving messages (to send an email) from the multiple clients? If not, you could remove WCF from the equation.
From the sound of it, you will also want the Service to act as a single logical endpoint that handle requests to send emails. If that's the case, you will want to use Send (a command) instead of Publish (an event). Publish is used to broadcast an event, which means that something happened already; Send is used to instruct another component to do something. It sounds like you want the latter.
Scaling of an endpoint can be done via the Distributor. This may or may not be useful depending on where you expect the bottleneck to be.
Edit: Based on your comment, I would simply go with the second setup, and just add the handler to the WCF service. If you are hosting WCF in IIS, make sure you have something that wakes the process up if the app pool recycles (the incoming message won't wake it up the same way an incoming request to WCF will).
We do something similar internally where one NSB endpoint handles all the sending of email. The clients can either use NSB directly to Bus.Send() the command to send a message to the email endpoint or you can expose that endpoint via WCF as well (only to get the commands over to the endpoint). Once the endpoint has the commands, they would just call your existing service to maintain compatibility with your existing clients.
I have a wcf service and handle a lot of client (server document generation). This service should receive a lot of request and should be handle in queue. It also have a callback. (callback will return successfully generated document). I am still using PIA and will implement OpenXML in the future.
Is it wcf msmq is the way to implement this?
Is there any samples might be related? Previously its running in local machine but now want to change it as a so called "Server generated"
WCF MSMQ doesn't support callback directly - it supports only one-way operations. But for example this article discuss how to add this support. With default configuration you can send message back to original sender but it is not a callback. To support responses every client will have to expose queue and pass address of its queue as part of the request to be able to receive the message from the service. More about responses in MSMQ is in MSDN magazine.
I have a WCF service hosted as Windows Service with most of its methods currently defined as:
[OperationContract(IsOneWay = true)]
But, now I need to send response back to the calling Web application for these service methods.
Now, because service methods are bit heavy (FYI, they are reporting methods that needs to do mail merge for a no. of records), I am thinking to either queue them or to process asynchronously, so essentially when the request is sent to the service it should save the request to database/queue, returning Request-Id to calling Web application.
In the mean-time, WCF service can just process incompleted requests from the queue or database.
Then either calling Web application can ping WCF service for status of request because it has Request-Id or
WCF service can ping back to calling app when the process corresponding to a Request-Id is completed.
To achieve above, can anyone please guide what changes I need to make to my WCF service (which currently has all one way operation)?
Also, please guide me whether I need to go for Asynch operation or message queuing?
Thank you!
Of course, going Async is simple:
remove the OneWay on the OperationContract in question and regenerate your Service WITH Async methods. There's a reason why Silverlight forces you to use Async operations. They do force you to rethink your UI.
I have a windows service that picks up messages from various MSMQs. The service picks up the messages from the queues, and then executes a specific workflow based on the queue the message came in from. Is it possible to configure a WCF service to accept a message from an endpoint and place it in a queue? I would like for the service to have multiple endpoints, and depending on which endpoint received the message, the message would be placed in a different queue. I have seen things about netMsmqBinding but so far I haven't been able to determine if this is meant for the use I am thinking about.
Any help is appreciated,
Mike
Am I getting this correctly - you want to have
a WCF service exposed to the outside world using multiple endpoints
depending on which endpoint the message comes into the WCF service, it should put those messages into separate MSMQ queues?
You can definitely have a WCF service that will expose any number of endpoints to the outside and that would drop incoming messages into an MSMQ queue. I'm just not sure whether you'll be able inside the WCF service method to know which endpoint the request came in on..... typically, the WCF service class doesn't know anything about where the request came from (and typically doesn't need to know...).
I see a few approaches to this:
have multiple services, one for each (type of) endpoint; they can share all their code and everything, but if you separate this into separate service classes, then each service class would inherently know what endpoint it serves, and thus could know what MSMQ queue to put the info into
find a way to send some header information along with the message that somehow tells you where to put the messages
in WCF 4.0, you might be able to do something with the new WCF Routing Service.... not quite sure how that would work, however - since it would also require some kind of "hint" to know which endpoint it was called on and how to route the incoming message
The way I was able to go about this was by creating a custom ServiceHost class that I could pass a configuration name to. This is an alternative to the default implementation that uses the Service Implementation type name to locate the configuration. This allowed me to run multiple instances of the same implementation on the same machine. In addition to that, inside the custom service class I added a custom MessageInspector that would attach itself to every endpoint to listen for messages. I then use the IDispatchMessageInspector.AfterReceiveRequest() method to take the incoming message and then place it into a queue that I define inside my configuration. A little complicated, but it works perfectly for our scenario.
net.msmq bindings allow a WCF client to write directly to an MSMQ queue, even if the queue-reading WCF service is not live -- it doesn't even have to exist. net.msmq bindings also allows automagic reading from queues. No use of MessageQueue to write to, or read from, a queue.