My WCF service library is hosted as a Windows Service and is supposed to handle requests from multiple clients.
One request that clients are going to make frequently is pretty resource intensive.
I have two doubts pertaining to above scenerio:
How a WCF service handles multiple client's request?
Is there any WCF configuration to make the process efficient?
Thank you!
In your default scenario, the WCF service host (the thing hosting your service class) will create a new instance of your service class for each request that comes in, and lets that handle the request ("per-call" activation).
You can tweak the maximum number of those concurrently active service class instances using the serviceThrottling behavior on your server.
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ThrottledServiceBehavior">
<serviceThrottling
maxConcurrentCalls="25"
maxConcurrentSessions="25"
maxConcurrentInstances="25"/>
</behavior>
</serviceBehaviors>
</behaviors>
There's a really good explanation of the options of the service throttling behavior and its default values in Kenny Wolf's blog post here.
Also, setting of the InstanceContextMode and ConcurrencyMode on your service class (that implements the service contract) have a strong influence on how your service will handle concurrency and multiple requests.
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall,
ConcurrencyMode=ConcurrencyMode.Single)]
class YourServiceClass : IYourService
{
.....
}
InstanceContextMode should be PerCall (each calling request gets a new, separate instance) and then ConcurrencyMode can be Single (which is the easiest to develop).
InstanceContextMode could also be PerSession if you need a session-based approach (not very common), or Single (your service class would a singleton - highly discouraged to use this, unless you absolutely, positively have to and know about all the quirks and problems with it!).
ConcurrencyMode could also be Reentrant (only relevant for duplex contracts and bindings) or Multiple (multithreaded singleton service class - highly risky and difficult to develop!).
Marc
Related
I think my question is rather simple, so I'll stick to the point:
Is it by any means possible to expose a service without specifying the services element and only the serviceHostingEnvironment element? I.e. would the below configuration be enough to host a WCF service? I'm asking because i've seen applications that - as far as I can tell - lack the services element, and I thought that was mandatory.
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
<serviceActivations>
<add relativeAddress="Service.svc" service="Namespace.To.My.Service" />
</serviceActivations>
</serviceHostingEnvironment>
With WCF 4.0 you don't need explicit service configuration as opposed to prior versions. It automatically adds default endpoints if no endpoints are defined explicitly.
Whatever configuration you mentioned in question is called File-less activation and you can activate service without even having physical .svc file. In WCF 4 you can define virtual service activation endpoints like one you have defined.
WCF detects what contracts are implemented by service and then method AddDefaultEndpoints adds one default endpoint per base address for each service contract implemented by the service. Note that this behavior is only when no explicit endpoints are added (either programmatically or through configuration). Should you add one explicit endpoint WCF stops adding default endpoints and it gives control to developer to customize it further.
I have a single service, one backing binary, that I want to configure to have two different endpoints. The problem is, I want a different serviceBehavior for each endpoint, to specify different security requirements.
E.G:
<service behaviorConfiguration="behavior1" name="MyServiceClass">
<endpoint address="endpoint1" bindingConfiguration="binding1" contract="IMyServiceContract"/>
</service>
<service behaviorConfiguration="behavior2" name="MyServiceClass">
<endpoint address="endpoint2" bindingConfiguration="binding2" contract="IMyServiceContract"/>
</service>
Is such a WCF configuration valid, or attainable in another format?
I'm not sure you can do it from config only, but there exists a code and config solution based around the extensibility point exposed by the IEndpointBehavior interface. This allows you to define behaviors at the endpoint level.
It's not particularly well documented as I don't think it's used very often. According to MSDN:
Endpoint behaviors, which implement IEndpointBehavior, are the primary
mechanism by which you modify the entire service or client run time
for a specific endpoint.
There are two mechanisms for adding endpoint behaviors to a service.
Add the behavior to the Behaviors property.
Implement a custom BehaviorExtensionElement that extends
configuration.
Specific examples of the first option exist here, and here, but I can't find anything about the second.
What is the difference between the Service node/section and the Client node/section in the configuration section? Why configure endpoints in one section over the other? Which is best for interoperability?
I'm currently building a service that talks to another service. I have endpoints for my clients and endpoints for the other service. Visual Studio seems to lump all the endpoints into the Client section.
I thought that client node was for your consumption and service node was for producing. But when you create a new wcf service visual studio puts your new service endpoint settings under the client node. I have moved my endpoint between both sections trying to figure out what the difference is.
When should I use service over client?
<system.serviceModel>
<services>
<service> <!--I noticed some tutorials and using wcf config edit tool
puts producer endpoint settings here -->
<endpoint blah settings/>
<endpoint blah settings/>
</service>
</services>
<client> <!--Visual Studio puts both producer and consumer endpoint
settings here -->
<endpoint blah settings />
<endpoint blah settings />
<endpoint blah settings />
</client>
<bindings>.....
</system.serviceModel>
Many settings in the WCF web.config (or app.config for that matter) can be shared for both consumers of a service as well as publishers of a service including:
Bindings
Endpoint Behaviors
Diagnostics
However as you have discovered, some config is specific to a service. A well-written service usually specifies:
It's base address. This is a convenience when defining a service as it allows your to define endpoints using relative addresses. Clients however don't use this particular setting as they need an absolute path. For this reason it makes no sense to specify in the section
Services can also be clients. If the client and server endpoints were all plonked together, WCF would not be able to know which should utilise the base address for one thing
Service behavior
By dividing up config between client and server, WCF is better able to know where to look for endpoints.
Which is best for interoperability?
I don't think that has anything to do with it. WCF is a means to achieve interopability but just by using WCF does not imply you will achieve it. Interopability is established when both parties agree on say a particular service contract; canonical data model; data transformation; message version or many of the other patterns as defined by SOA Patterns.org So there are various patterns you must follow. e.g. If you change a method on service contract but have not updated the clients then you have broken interopability by breaking the schema of the service.
Visual Studio seems to lump all the endpoints into the Client section
If your WCF process is both a consumer and producer of WCF services then it should not be putting all the endpoints under
Is there a way to do this globally, automatically for all my WCF services via configuration in WCF 4.0?
That is, I know WCF 4.0 exposes new configuration techniques that applies certain behaviors by default to all hosted endpoints, and that you don't need to explicitly specify individual endpoints by config anymore...but can I do something in the config that says to automatically host all services with both a BasicHttpBinding and a WebHttpBinding (using a /web relative address for the WebHttpBinding)? Or do I still need to use a custom ServiceHostFactory for this?
Thanks.
See the Developer's Introduction to WCF 4 for lots of interesting stuff in WCF 4.
One of the new features is called default protocol mapping, and this combined with the default endpoints provided by WCF 4 might solve your problem.
Default endpoints means that WCF 4 will provide one endpoint for each contract your service class implements (typically only 1), and for each base address defined in your config (or code for the ServiceHost).
In order to make sure a http:// endpoint gets exposed automagically with the webHttpBinding, you also need to override the system default (which is basicHttpBinding) - which you can do thanks to the protocol mappings.
<configuration>
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="webHttpBinding"/>
</protocolMapping>
</system.serviceModel>
</configuration>
How many ServiceContracts can a WCF service have?
Specifically, since a ServiceContract is an attribute to an interface, how many interfaces can I code into one WCF web service? Is it a one-to-one?
Does it make sense to separate the contracts across multiple web services?
WCF services can have multiple endpoints, each of which can implement a different service contract.
For example, you could have a service declared as follows:
[ServiceBehavior(Namespace = "DemoService")]
public class DemoService : IDemoService, IDoNothingService
Which would have configuration along these lines:
<service name="DemoService" behaviorConfiguration="Debugging">
<host>
<baseAddresses>
<add baseAddress = "http://localhost/DemoService.svc" />
</baseAddresses>
</host>
<endpoint
address =""
binding="customBinding"
bindingConfiguration="InsecureCustom"
bindingNamespace="http://schemas.com/Demo" contract="IDemoService"/>
<endpoint
address =""
binding="customBinding"
bindingConfiguration="InsecureCustom"
bindingNamespace="http://schemas.com/Demo" contract="IDoNothingService"/>
</service>
Hope that helps, but if you were after the theoretical maximum interfaces you can have for a service I suspect it's some crazily large multiple of 2.
You can have a service implement all the service contracts you want. I mean, I don't know if there is a limit, but I don't think there is.
That's a neat way to separate operations that will be implemented by the same service in several conceptually different service contract interfaces.
#jdiaz
Of course you should strive to have very different business matters in different services, but consider the case in which you want that, for example, all your services implement a GetVersion() operation. You could have a service contract just for that operation and have every service implement it, instead of adding the GetVersion() operation to the contract of all your services.
A service can theoretically have any number of Endpoints, and each Endpoint is bound to a particular contract, or interface, so it is possible for a single conceptual (and configured) service to host multiple interfaces via multiple endpoints or alternatively for several endpoints to host the same interface.
If you are using the ServiceHost class to host your service, though, instead of IIS, you can only associate a single interface per ServiceHost. I'm not sure why this is the case, but it is.