I want to achieve the following:
Expose WCF endpoint to client from which they request a long-running operation.
Map the inbound request to a NServiceBus Message.
Publish the message to the bus for processing.
Send a reply to the client acking that their request has been received and we will begin processing it.
Bus works the message through a handler.
Can you help me with some examples here please?
Thanks in advance
You can check out the WcfIntegration sample that comes with NSB to see how to expose an endpoint via WCF. To hand off the message, you can simply call Bus.Send() to another endpoint to do processing, then use the Bus.Return() that is in the sample. From there, the other endpoint can look just like the Server part of the FullDuplex sample without the Bus.Reply() logic.
Awhile ago I created some example code that is similar to this, although it used a traditional ASMX web service and not a WCF one, but that is really just an implementation detail.
Check out NServiceBus External WebService Example on GitHub.
Related
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.
The goal I'm working toward is having a WCF routing service that can receive messages from clients, persist them to some type of data store, and then process/send them to their destination WCF services.
Things to consider:
You can create a routing service by using the ClientViaBehavior (outlined here and here)
The ClientViaBehavior will not work with basicHttpBinding, so I need to use wsHttpBinding (basicHttpBinding doesn't set the "To" header on the message, found out the hard way)
The WCF Message object itself is sent to the Routing Service, where it can be persisted as a serialized string
I don't want the Routing Service to know what's in the message - consequently, the service will not have a reference to the Data Contracts involved
When the time comes to route the Message to its destination, I need to be able to create a channel between the Routing Service and the Destination Service
It is not desirable for the Routing Service to be aware of each destination service - ideally, WCF could create the proper channel dynamically based on the content/headers of the message being processed.
Is this too much to ask of WCF? (I have a feeling it might be...)
Any advice on how to accomplish something like this would be appreciated.
If you're on .NET 4 (or can move to it), WCF 4.0 has introduced a RoutingService infrastructure of its own.
Check it out, before you re-invent the wheel!
See A Developer's Introduction to Windows Communication Foundation 4 for a great general intro to the new features (including RoutingService) in WCF 4
Yes, you can make your routing service accepts any message.
This link should help you: Building a WCF Router, Part 1
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.
Here is what I would like to do.
1. Service hosted in WCF
2. Client calls asking for a payload of messages
3. Service returns payload of messages and waits for client to respond
3.A. Client returns 200 (OK) status or something confirming messages received.
3.B. Client returns bad error status stating to not delete the messages on server.
4. Depending on 3.A or 3.B Service will take appropriate action.
I would like to do this by doing something like extending IDispatcher and writing extension methods. VS creating another service and having the client call that service to signal which messages it received. Unless that's best practices.
Thanks in advanced.
If acting on HTTP status codes is a requirement then WCF is probably not what you want to use. WCF was created to be able to write transport independent code so the bindings could be changed purely through configuration; no code changes required. The HTTP request handling is buried so deeply into HTTP-based bindings that you're better off using something like the OpenRasta framework to implement your HTTP (REST) style service. It is a very HTTP request aware framework.
Otherwise, look at this wsDualHttpBinding intro to accomplish something similar through the application API level.
How can I configure the service router to enable transactions, because the backend service uses them and this feature doesnt work since I introduced the ServiceRouter in the middle of the Client & Server dialog.
Thanks in advance
If you haven't figured it out, have a look at the IDuplexSessionRouter contract.
More information here.
Routing service is only intermediary. It doesn't participate in transaction. It is just something that should be as much transparent to client and service as possible.
Transactions in WCF are provided as additional messages send over wire. So my understanding is that if you are using router you must correctly route these messages as well. I have to say I have no idea how to do it without reading and fully understanding WS-AT protocol specification.
But maybe I'm wrong. In such case start with configuring routing service with transactional binding same as your client and service.