WCF: Detect when service contract has changed - wcf

I have a Silverlight application which connects to a WCF service. Sometimes the WCF service contract gets updated while a user is still using the application, in which case the user would need to refresh the page to download the latest Silverlight client.
I would like to detect when the service contract gets updated and display a prompt in the browser that says something to the effect of "New update detected - please refresh the page." I could use a try/catch block to handle CommunicationException, however that is a very generic exception that could happen for any number of reasons.
What is the best way to detect a contract mismatch?

the best is if you could have some operation GetServiceVersion() which the client can periodically poll (if you can push it to the client even better). If the server cannot "cooperate" then the client has to download the wsdl and see if it changed, try to avoid that.

Related

Publish event from service layer composed of web applications using service bus

I have read Why not publish NServiceBus messages from a web application and another similar question about this but I am not clear if this applies to service layer as well. For example, if the service layer is composed of web services or REST services built using WCF or Web API or any other way, should those services publish events or send commands? If those services are hosted in load balanced web servers, the problems outlined in the articles apply to this layer as well. How would the recommendation change or not change?
If I look from the definition of Event vs Command, the messages I am talking about are Events e.g. "a user was created" and so an event should be published. As a matter of fact, the service that created the user doesn't even know what else to do i.e. may be another application is supposed to create a customized portal for it and yet another application is supposed to send a welcome kit to the user. This would be an event and not a command. I guess I am hung up on the definition of a web application and application service when application service itself is composed of one or many web applications.
The definition of Web Application
A web application is an application that is accessed by users over a
network such as the Internet or an intranet.
However, to me, the users can be computers and thus web services are web applications and that is the reason for this question.
EDIT:
Let's consider a concrete example. An ASP.NET website (MVC or Web form - doesn't matter) displays the form to the operator, gets a post with data about user creation (Name, UserName, Password) and invokes a WCF service to create the user. In between website and WCF service we can put ServiceBus and send command to create the user (Request/Response) so that we get all the benefits described in the first article. WCF service is the actual business processing layer i.e. it would create the user. That is where I have the question. After the user is created, it should announce that a user has been created and other systems can react to it and do whatever they are supposed to do. So it fits perfectly the pattern of publish the message. However, the WCF service itself is a web application and thus has most of the traits of the web applications and thus the confusion.
As mentioned in the answer to the SO question you linked to, publishing event has more to do with where the actual processing takes places. Just as a side-note: it is not a matter of Send instead of Publish since that would imply that the two are interchangeable whereas they have rather different intentions. When you want to publish, you want to publish.
The same questions should arise if you find yourself publishing from your web-exposed integration layer: should you be performing the business processing in that code or rather sending it off to another endpoint for processing? Typically you should just send it off to another endpoint. You may even consider how you would perform the relevant action should anyone wish to invoke it. For instance, if you are publishing a UserCreatedEvent message it implies that you created a user. How would a user be created? Would I be forced to use the WCF / Web-Api layer or can I send a CreateUserCommand message on the bus that is processed by some application endpoint? If it is the former then you may need to rethink your design. However, if the latter you should be sending the command from your WCF / Web-Api anyway and the processing endpoint will perform the Publish bit :)
update:
My take on it is that it is more about cohesion / concerns. You would typically interact with your domain, from within your business, via a service bus for commands and events, and a simple query layer for reads. If you need to expose anything to a third-party (or simply via the web) then you use WCF / WS / Web-APi. The point is that you should try to avoid business processing in an integration endpoint (or in a front-end like a website). Business processing is better suited to application servers. There are usually exceptions to the rule but if you are in a position to influence the structure then you are in a better space.
The fact is, whatever code is truly responsible for performing the action should be the same which publishes the event. If you've got a MVC app and in the controller itself you're using Entity Framework to insert the User record, then that is exactly where the Publish should be, right after the SaveChanges call. If however, the controller calls a referenced binary or service which does the actions involved in the "add user" call, then the Publish should be there. My thought is the event should be right alongside the code that does the action whose event you are trying to publish.

NServiceBus, WCF Architecture

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.

WCF Service calling another WCF service fails with web error 400 Bad Request

We have a web service that is called when user clicks save button on web form. The 'save' web service then makes a call into another web service (different machine). The call always fails and as far as I can tell does not even attempt to cross the network because the Fiddler traffic is empty. This problem only occurs when we call the second web service from the first web service. If we call the second web service straight from the client or on page load, it works. We are using WebHTTPBinding with REST type services.
I used the WCF trace to come up with the error 'Envelope Version 'EnvelopeNone (http://schemas.microsoft.com/ws/2005/05/envelope/none)' does not support adding Message Headers.', but I don't know how to resolve it.
Any suggestions?
Possible fixes:
Check #ServiceHost directive( in
. svc file) is set to
"WebServiceHostFactory" source
WebHttpBeahvior element is added in
the endpoint behavior source
Put ORDER information in the XML
schema Class source
Check that your Data Transfer objects are
serrializable source
Check if Skype installed and make sure it
doesn't overtake the port
source
Remove SOAP message header (it is not supported for REST
WCF) source

Validate that WCF Callback Client is still listening

I've setup an example in which a client calls a WCF service that has a Callback registered. It all works perfectly, but I want to test the scenario in which the client is closed, but the Service is still doing it's thing. Then when it comes time for the Service to call back to the client, I get an error because the client ain't there anymore. Is there a recommended way for me to validate in the Service that that the client is still there before trying to call back to it via the CallBack channel? I've tried accessing OperationConext.Current(), but this is null in the context of the callback method.
--Shawn.
You have already found one recommended method - call the client and see if it works.
TCP/IP can't always detect client shutdown. In particular, it's often necessary to send a packet to the other side to see if it is still there.

wcf service stops after few requests

I am working on an application where i am using a wcf service. I am currently hosting my service on localhost and accessing it from there only by adding the service reference in my project. On one of my page i am sending request on change of selected index on dropdown list. It works fine for first few requests but suddenly stops after that giving following excsption
"Failed to invoke the service. Possible causes: The service is offline or inaccessible; the client-side configuration does not match the proxy; the existing proxy is invalid. Refer to the stack trace for more detail. You can try to recover by starting a new proxy, restoring to default configuration, or refreshing the service."
How can service stop without any reason and that too from my localhost. It only works for first 3-4 requests. In service i am just sending a integer and getting back the records on its basis using a class in a generic list.
Thanks in advance
What protocol / bindings are you using? Can you show us the config? Anything inside the <system.serviceModel> on both the server and the client side.
Do you maybe create a client proxy and call the service method and not properly close and dispose of the client proxy? In that case, you might run out of connections at some point - but that's next to impossible to tell without some code to see what you're doing. Can you show us the service contract in question, and the code how you call it from the client side?