In this article demonstrates how you can implement two WCF Service Contracts on one Service and how to configure the service to support it. This became useful in duplex communications where the service needs to expose two different bindings.
Consider the following scenario:
The Service exposes two endpoints: wsDualHttpBinding and basicHttpBinding. Clients will be create a channel to the Service via DualHttpBinding and calling applications will be calling the Service via BasicHttpBinding. The Service will be broadcasting any message which has arrived to the clients which have registered to it. This scenario needs both ClientNotificationService and NotificationService implemented in single service but expose on two different endpoints.
This article is more on how to configure the service. So no coding is provided for the service contract and implementation. The full sample will be posted in future.
- IClientNotificationCallback: should be implemented by clients in order for the Service to call service operations on the client.
- IClientNotificationService: opens a dual channel to clients and provides service operations for clients in order for them to register to the Service.
- INotificationService: provides service operations for caller application to notify the service on broadcasts.
- NotificationService: this class will be implemented both IClientNotificationService and INotificationService. It will implement operations for both contracts.
<system.serviceModel> <serviceHostingEnvironment multipleSiteBindingsEnabled="true"> <serviceActivations> <add factory="System.ServiceModel.Activation.ServiceHostFactory" relativeAddress="./NotificationService.svc" service="Quatrevingtquinze.Services.NotificationService"/> </serviceActivations> </serviceHostingEnvironment> <services> <service name="SAS.Services.NotificationService" behaviorConfiguration="DefaultServiceBehavior"> <endpoint name="basicHttpService" address="" binding="basicHttpBinding" contract="Quatrevingtquinze.Services.Contracts.INotificationService" /> <endpoint name="dualHttpService" bindingConfiguration="dualHttpService" address="client" binding="wsDualHttpBinding" contract="Quatrevingtquinze.Services.Contracts.IClientNotificationService" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> </service> </services> <behaviors> <serviceBehaviors> <behavior name="DefaultServiceBehavior"> <serviceMetadata httpGetEnabled="True"/> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
A base address is provided on the serviceHostingEnvironment configuration. This address will be the base address where both endpoints will be exposed.
Note that there is only on Service in Services configuration which exposes three endpoints (the third endpoint is MetadataExchange which is not discussed here):
- basicHttpService: this is a basicHttpBinding endpoint which will be used by calling applications.
- dualHttpService: this is a wsDualHttpBinding endpoint which will be used by clients in order to register to the Service.
Important Note: note that the address attribute of the basicHttpService endpoint is empty whereas dualHttpService endpoint is not. In order to expose two endpoints they should have different addresses or the Service cannot be start. The basicHttpService endpoint will be following the base address and dualHttpService will have “/client” at the end of the address.
Below is the client configuration sample:
<client> <endpoint address="http://localhost/NotificationService.svc" binding="basicHttpBinding" bindingConfiguration="basicHttpService" contract="NotificationService.INotificationService" name="basicHttpService" /> <endpoint address="http://localhost/NotificationService.svc/client" binding="wsDualHttpBinding" bindingConfiguration="dualHttpService" contract="NotificationCallback.IClientNotificationService" name="dualHttpService"> </endpoint> </client>