The arhitecture:
console application that contains a wcf duplex service;
windows app consumers; every app subscribe to Duplex, so we have a list of subscribers
and the service must send notifications to some of them in case that some events apper;
The problem:
how to maintain the connection alive continuously so that the service can send notifications to clients ?
I found that there are 2 channels for this binding. I need to have permanently the channel from service (for callbacks) open.
Thanks;
I had the same problem than you, to solve it you need to implement a keep alive method. A dummy call to your service is kind of stupid to have a 24/7 WCF service because is not really the best architecture way of WCF but we know sometimes what we need is not always the best thing.
So yep, just implement a call to the WCF service every 5 minutes and by doing that you keep alive the connection. Maybe you can have others problems too, in my case I don't have a lot of subscribers of the WCF service so this solution was fine.
As long as a client is connected to the service, the callback channel will be alive. Once the client disconnects (or the channel gets faulted), the callback channel will close.
Related
I have system like this:
Windows service (WCF, data/events) <-> Web app <-> Web client
I need simultaneous response for clients requests. I have some events from service for clients too. So duplex channel is the way to go. But I need high throughput, because clients calls simultaneously.
Request/reply approach
In order not to serialize channel requests I need more channels for parallel calls, right? But how to handle callback channel then? Ho to keep it still open for receiving events, even on channel errors?
OneWay approach
On channel should be enough (no waiting for data preparation), but how to link data sent to callback with original request, to be able to compose response for client?
What is the way to go? Thank you.
In a simple case, when a web client sends a request to the web app, and web app (possibly) sends a request(s) to WCF service, there's no need in duplex binding at all.
As for events, raised by the service to be fired in Web client, I'd suggest to use a message broker which supports WebSockets - for example RabbitMQ. It has a plugin compatible with WebSockets and WCF binding.
Putting things together, one can create a RabbitMQ server, which accepts messages from WCF service and sends it to Web client, which subscribes to the event feed from Javascript.
I have a WCF service with duplex binding hosted within a windows service. The service has to continuously poll for changes in a datasource (Azure service bus to be specific, but type of datasource isn't really important). If there is any new change in the datasource, the service should immediately notify one or more clients.
I have gone through many different potential approaches of achieving this such as Broadcasting, Publish/Subscribe with WCF, and List based publish subscribe
But in all these approaches, the chain of events is initiated explicitly by a client/publisher. For example in case of Pub-Sub, the whole chain of events is initiated when a publisher publishes something.
But in my scenario, there is no publisher. Service must itself poll onto a datasource and look for any new changes.
How do I achieve this in my scenario? Where should I have the polling logic?
One option is to have the polling logic in hosting environment (windows service) and call the publish of service whenever there is new data.
I am not sure how we can have the polling logic within the WCF service itself! Any leads/thoughts regarding this would be very helpful.
I have a duplex wcf service which holds (in memory) list of callback references to its clients. There are two methods Subscribe and Unsubscribe on wcf service.
Its all working fine with One wcf server and multiple clients. Problem started when I introduced two wcf server with load balancing using Wcf router service.
For eg- I have two wcf servers(wcf1 and wcf2) and one router server (r1). When client call "Subscribe" to router endpoint, it broadcasts that request to both the wcf1 and wcf2 servers. So that both of them hold a callback reference to client. Problem starts when one of the wcf server is down. If wcf1 server goes down then all the subscriptions are lost. So when it comes back alive then there are no subscriptions available for it to do the callbacks and there is no way to notify clients to resubscribe.
I tried listening to fault event on the client side. That doesnt get triggered because its connecting to the router endpoint. That event will fire only if router server is down.
Has anyone faced similar issue to mine? Am I doing something wrong?
The only way of handling this is to persist the callback list in some kind of share-able resource, such as a database, a cache, or even a file on a shared drive. This can be accessed by each instance of your service on startup, so all callbacks are loaded back in in the event of failure.
Sorry this is probably not what you want to here.
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 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.