WCF with Windows service hosting for Host and Client - c#

I have a WCF with Windows service hosting for a background DB operation. I have included the client part also in the same windows service with a timer instead of creating a seperate windows service for the client part.
I would like to know is there any drawback with this approach.

Have to agree with #Kek why have a WCF service at all if there are no outside callers :) Other than that there is no real drawback compared to using 2 windows services, your approach uses less memory and there is only one service to manage (start, stop etc).

I agree with #Tommy Grovnes in most cases: no drawback if things are done correctly.
I'd like to point out something though:
If service and client are in the same process, certainly the later depends on the former... and you may be tempted to call service methods directly (without using WCF actually)... Try not to do that.
If you do, your data is not serialized : so it is faster, but it may not behave the exact same way compared to a client in another process.
This is particulary true if you use mechanisms such as EF Self tracking entities. These entities change their state when they are deserialized. Avoiding the serialization may lead to unexpected errors when you actually call your service from another process.

Related

Why can't a client speak directly (!) with a WCF server , instead of using a proxy class that does that?

I'm currently learning the basics of WCF , and I stumbled upon the following flow :
Meaning that my client needs to speak with a Proxy class , that communicates with the WCF server .
Why can't I (the client) speak directly with the server , instead of using a third party for the job ?
There's nothing stopping you from not using a c# WCF proxy client to communicate with a WCF service, you could always do without and use say raw TCP/HTTP/pipes/MSMQ. However, doing so generally requires alot of effort and time - time during which most people would generally prefer to spend reading the Hitchhiker's Guide to the Galaxy.
Heavy?
WCF proxies are actually not as heavy as it may sound. They're not really "3rd party" either. There're generally nothing more than light-weight classes compiled in with your application. They don't run say out-of-process as may happen in certain COM scenarios.
The notion of a "3rd party" proxy is not unique to WCF. DCOM also has the concept of proxies, but unlike WCF, they are created for you behind the scenes and are unable to be avoided. Sometimes, as mentioned, they even run in another process! WCF, or should I say SOAP services (generally), differs from DCOM because the client proxies are not required. They just make the use case of using a SOAP service easier. Luckily that part of Windows had to make way for a hyperspace bypass, so the use of DCOM in contemporary applications is essentially no more.
The client proxies help your life by:
encapsulating and serializing the method call into a request message (usually SOAP)
abstracting you from the underlying transport when the call to the service is made transmitting the request message from the prior step. i.e. using TCP; HTTP; MSMQ etc APIs. Want your TCP WCF service to accept a local named pipe client? Easy just change the config file, no code change is generally required!
deserializing the response message into a user friendly c# object(s)
handles all the tedious; complex and necessary security for you in the form of security tokens; cookies et al
When is WCF not WCF?
So going back to your question again:
Why can't a client speak directly (!) with a WCF server , instead of using a proxy class that does that?
...when you consider that WCF unifies all the comms APIs into a single API; abstracts and encapsulates a SOAP service, then we could say that all WCF clients by definition use WCF proxies to talk to a WCF service.
As soon as a client explicitly uses raw TCP; MSMQ; HTTP; named pipes APIs in code, it essentially stops being a WCF client (remember WCF is all about unified comms) and instead becomes a SOAP client (or perhaps REST). I would even argue that using the IRequestChannel interface with its Request() method, introduces a messaging concept that was not apparent with standard WCF client proxy code (even if it still abstracts transports from the user). By way of comparison, if I add a MSMQ binding to my pure WCF-client-proxy-using-app's WCF config, my code generally doesn't take on an asynchronous messaging model typically associated with MSMQ. That's the nice thing about WCF.
Of course the server, written in WCF, will be quite content in the knowledge that it considers itself "WCF" regardless of whether clients think it is WCF; SOAP or some scary XML payload being shot over TCP in much the same way as the deity that is Pluto, considers itself to be a planet regardless of what classification system happens to be in fashion at the time.
If you want to treat the service as a WCF service - use WCF client proxies (because we generally don't care about the underlying SOAP message being sent about)
If you want to talk to the service directly without proxies, then you should think about the remote service as a SOAP service and so arm yourself with not only low-level comms APIs but also how to construct and process SOAP messages
Are non-Proxy Approaches Recommended?
Whilst you could do without the proxy, it is not recommended because if you wanted to change security, transports, max message lengths, protocols such as JSON, add async methods, you would be required to perform a great deal of code changes to your non-proxy-using-app compared to the proxy approach.
Like the starship Heart of Gold, WCF is "Glad to be of service" but understands should you desire manual helm control.
Gratuitous references to Douglas Adam's fine radio play; TV mini-series and book The Hitchhiker's Guide to the Galaxy. Why not press the Don't Panic button and read it today?
So I'm pretty new to WCF myself, but I'm pretty sure the proxy class is there to give you the types you need your code to reference. When you make a WCF call, you are serializing data, so you need a class to define that. The proxy allows you to write code against it, acting like you know what its methods and data contracts are, but when the code is actually executed, a WCF call is made and serialized messages are sent back and forth.

Separate WCF Service Instance For Different Host Instance and Endpoint?

I have two applications using the same wcf service instance. These two applications will always be started in pairs, so I can have a second, third, or fourth instance of these two. Does this mean I need to have one wcf service being hosted by say a Windows Service, IIS, or console app using a common endpoint address for all four of the instance pairs? Or if I dynamically hardcode the endpoint addresses such that each individual pair has it's own and self host in one of the two applications, does that mean each pair has access to it's own service?
I could probably benchtop test this, but I figure someone with experience could save me quite a bit of coding time just trying to figure it out.
Update (for clarity):
The reason for this question is due to the particular situation I'm working with. The scenario is that the two applications involve one client exe that I am developing and a third-party exe that I have no control over. I can develop a dll that the third-party exe can load. Between my third-party app dll and the client exe the WCF service is intended to bridge the process space to allow the two to communicate transaction information. This will allow the client exe to control the third-party exe and the files it manages.
This is partly an answer partly a long comment. :)
One way to think of a WCF service is that it passes messages back and forth between two separate applications. At a very general level, although there are plenty of good reasons to make a stateful service, it is generally accepted that it is better to be stateless. This means that each time you call it you pass all the info it needs to do what it does, and the service does not need to remember what was done earlier.
The fact that you are worried about separate instances suggests to me that your service has state. I do not think multiple endpoints is the way to go for your situation.
I would suggest that when an application "pair" starts up the first thing it could do would be to request a unique ID from the service. From that point on all messages to the service would contain this ID and the service would process them accordingly. If the service application is maintaining state it would use this ID as a key to identify what information to access to process the call.
At this point you end up with One service application on one server and multiple client applications which is how most WCF systems are designed.
Updated, I think you should google "WCF: Instance Management Per-Call and Per-Session"
Your client should be able to open a connection from the client and keep it open. WCF will automagically create a new instance on the server for you. This would mean you don't need the "application pair ID" but you would need to keep the session open.

How does WCF actually work?

I have created a C# application that I want to split into server and client side. The client side should have only a UI, and the server side should manage logic and database.
But, I'm not sure about something: my application should be used by many users at the same time. If I move my application to a server, will WCF create another instance of the application for every user that logs in or there's only one instance of the application for all users?
If the second scenario is true, then how do I create separate application instances for every user that want to use my service? I want to keep my application logic on the server, to make users share the same database, but also to make every single instance independent (so several users can use the WCF service with different data). Someting like PHP does: same code, new instance of code for every user, shared database.
By default, WCF is stateless and instanceless. This basically means that any call may be issued by any client, without any clients or calls knowing about each other.
As long as you have kept that in mind while designing the service, you're good to go. What problems do you expect to occur, given how your service is built at this moment?
The server-side (handled by WCF) will usually not hold any state at all: all method calls would be self-contained and fairly atomic. For example, GetUsers, AddOrder etc. So there's no 'instance' of the app, and in fact the WCF service does not know that it's a particular app using it.
This is on purpose: if you wanted to write a web app, or simple query tool, it could use those same methods on the WCF service without having to be an 'app', or create an instance of anything on the server.
WCF can have objects with a long lifetime, that are stateful, a bit like remoting, but if you're following the pattern of 99.9% of other designs with WCF, you'll be using WCF as a web service.
Edit: from the sounds of your comments, you need to do some seriously and potentially in-depth reading about client-server architectures and the use of WCF. Start from scratch with something small, then try to apply it to your current application.

Are there any conflicts with a web service calling another web service?

While the intention of my solution isn't necessary, I have run into a situation where I need to write a web service as an intermediate step in between the client and another web service.
[client] => [my web service] => [3rd party web service]
I am looking to see if anyone has any experience with this situation who could offer any advise or advise on any caveats that I can expect.
Note: I am developing using .NET and VS2008
No, its fine. In fact, its a great method to avoid a client from calling two web services when those calls are expensive (say from a phone). I created a solution once upon a time where my phone app would call my own web service, which would call another one, strip away a lot of the data and return the rest. You can get some pretty impressive perf increases if the main web service returns a lot of data.
The only catch may be authentication and that depends on a lot of variables and such. Good luck!
I've done it. It works fine. The only real concern is the same concern you'd have anyway - if the connection is broken between the two web serices, it's just another possible point of failure.
You can definitely do this. But, remember if you are transmitting any kind of sensitive data, you need SSL for the webservices.
On the negative performance implication sides, just keep in mind that any calls to this will get you two expensive HTTP connections instead of one expensive HTTP connection. Might be good to think about caching results in each layer if at all possible.

Swapping ASP.NET DataProvider from RDBMS to WCF

I have a client that is pushing for all data access to go over SOAP web services. No, I don't know why; I guess they like to keep their processors warm with all the XML building and parsing. Anyway... I have to move an existing web app programmed using a DataProvider on Oracle to WCF. I haven't written the web service yet. Are their any tools/frameworks/ideas to help create a DataProvider that uses a WCF proxy (or any SOAP client) for data access? Is this even possible?
Hopefully the ASP.NET site has some kind of "Data Access Layer", this will make your job much easier as it will have calls that are easy to proxy, e.g. bool SaveOrder( Order order ), Customer GetCustomerWithOrders( int customerID ) etc.
If instead the ASP.NET is making direct calls to the DataProvider (as I suspect might be the case) then you've got a big job on your hands, since it's a chatty process where you open a connection, do a few things that might require multiple calls to the database, then close it... whereas WCF works best as stateless calls. You can create sessions and try to proxy a DataProvider but I think that would actually make the app more complex and less stable.
I strongly recommend going back to the client and asking "Why do you want to convert to using SOAP and WCF, and what do you hope to gain?".

Categories

Resources