Как разместить службу WCF в WAS
В настоящем разделе описаны основные этапы, требуемые для создания служб активации процесса Windows (также известных как WAS), размещенных в службе Windows Communication Foundation (WCF). WAS является новой службой активации процесса, представляющей собой обобщение функций служб IIS, работающей с транспортными протоколами, отличными от HTTP. WCF использует интерфейс адаптера прослушивателя для передачи запросов на активацию, полученных через протоколы, отличные от HTTP, и поддерживаемые WCF, такие как TCP, именованные каналы и очередь сообщений.
Данный параметр размещения требует правильно установленных и настроенных компонентов активации WAS, но не требует написания кода размещения как части приложения. Дополнительные сведения установке и настройке WAS см. в разделе Как устанавливать и настраивать компоненты активации WCF.
Внимание! |
---|
Активация WAS не поддерживается, если канал обработки запросов веб-сервера работает в классическом режиме. Чтобы использовать активацию WAS, канал обработки запросов веб-сервера необходимо перевести в интегрированный режим. |
Если служба WCF размещается в WAS, стандартные привязки используются обычным способом. Однако при использовании NetTcpBinding и NetNamedPipeBinding для настройки служб, размещенных на WAS, ограничение должно быть удовлетворено. Если разные конечные точки используют один и тот же транспорт, параметры привязки должны соответствовать семи следующим свойствам:
ConnectionBufferSize
ChannelInitializationTimeout
MaxPendingConnections
MaxOutputDelay
MaxPendingAccepts
ConnectionPoolSettings.IdleTimeout
ConnectionPoolSettings.MaxOutboundConnectionsPerEndpoint
В противном случае, конечная точка, запущенная первой, всегда определяет значения этих параметров, а добавленные позже конечные точки, если они не совпадают с этими настройками, вызывают ServiceActivationException.
Копию исходного кода этого примера см. Активация TCP.
Создание базовой службы, размещенной на WAS
Определите контракт службы для данного типа службы.
[ServiceContract] public interface ICalculator { [OperationContract] double Add(double n1, double n2); [OperationContract] double Subtract(double n1, double n2); [OperationContract] double Multiply(double n1, double n2); [OperationContract] double Divide(double n1, double n2); }
Реализуйте контракт службы в классе службы. Обратите внимание, что информация об адресе или привязке не указывается внутри реализации службы. Кроме того, для извлечения этих сведений из файла конфигурации не требуется писать код.
public class CalculatorService : ICalculator { public double Add(double n1, double n2) { return n1 + n2; } public double Subtract(double n1, double n2) { return n1 - n2; } public double Multiply(double n1, double n2) { return n1 * n2; } public double Divide(double n1, double n2) { return n1 / n2; } }
Создайте файл Web.config, чтобы определить привязку NetTcpBinding для использования конечными точками CalculatorService.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <netTcpBinding> <binding portSharingEnabled="true"> <security mode="None" /> </binding> </netTcpBinding> </bindings> </system.serviceModel> </configuration>
Создайте файл Service.svc, содержащий следующий код.
<%@ServiceHost language=c# Service="CalculatorService" %>
Разместите файл Service.svc в виртуальном каталоге своего IIS.
Создание клиента для использования службы
Из командной строки запустите Служебное средство ServiceModel Metadata Utility Tool (Svcutil.exe), чтобы создать код из метаданных службы.
Svcutil.exe <service's Metadata Exchange (MEX) address or HTTP GET address>
Создаваемый клиент содержит интерфейс ICalculator, определяющий контракт службы, которому должна удовлетворять реализация клиента.
//Generated interface defining the ICalculator contract [System.ServiceModel.ServiceContractAttribute( Namespace="http://Microsoft.ServiceModel.Samples", ConfigurationName="Microsoft.ServiceModel.Samples.ICalculator")] public interface ICalculator { [System.ServiceModel.OperationContractAttribute( Action="http://Microsoft.ServiceModel.Samples/ICalculator/Add", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/AddResponse")] double Add(double n1, double n2); [System.ServiceModel.OperationContractAttribute( Action="http://Microsoft.ServiceModel.Samples/ICalculator/Subtract", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/SubtractResponse")] double Subtract(double n1, double n2); [System.ServiceModel.OperationContractAttribute( Action="http://Microsoft.ServiceModel.Samples/ICalculator/Multiply", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/MultiplyResponse")] double Multiply(double n1, double n2); [System.ServiceModel.OperationContractAttribute( Action="http://Microsoft.ServiceModel.Samples/ICalculator/Divide", ReplyAction="http://Microsoft.ServiceModel.Samples/ICalculator/DivideResponse")] double Divide(double n1, double n2); }
Созданное клиентское приложение также содержит реализацию ClientCalculator. Обратите внимание, что информация об адресе и привязке нигде внутри реализации службы не указывается. Кроме того, для извлечения этих сведений из файла конфигурации не требуется писать код.
// Implementation of the CalculatorClient public partial class CalculatorClient : System.ServiceModel.ClientBase<Microsoft.ServiceModel.Samples.ICalculator>, Microsoft.ServiceModel.Samples.ICalculator { public CalculatorClient() { } public CalculatorClient(string endpointConfigurationName) : base(endpointConfigurationName) { } public CalculatorClient(string endpointConfigurationName, string remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public CalculatorClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : base(endpointConfigurationName, remoteAddress) { } public CalculatorClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : base(binding, remoteAddress) { } public double Add(double n1, double n2) { return base.Channel.Add(n1, n2); } public double Subtract(double n1, double n2) { return base.Channel.Subtract(n1, n2); } public double Multiply(double n1, double n2) { return base.Channel.Multiply(n1, n2); } public double Divide(double n1, double n2) { return base.Channel.Divide(n1, n2); } }
Конфигурация для клиента, использующего NetTcpBinding, также создается программой Svcutil.exe. Имя этого файла должно задаваться в файле App.config, если используется Visual Studio.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <bindings> <netTcpBinding> <binding name="NetTcpBinding_ICalculator"> <security mode="None"/> </binding> </netTcpBinding> </bindings> <client> <endpoint address="net.tcp://localhost/servicemodelsamples/service.svc" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_ICalculator" contract="ICalculator" name="NetTcpBinding_ICalculator" /> </client> </system.serviceModel> </configuration>
Создайте экземпляр класса ClientCalculator в приложении и вызовите операции службы.
//Client implementation code. class Client { static void Main() { // Create a client with given client endpoint configuration CalculatorClient client = new CalculatorClient(); // Call the Add service operation. double value1 = 100.00D; double value2 = 15.99D; double result = client.Add(value1, value2); Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result); // Call the Subtract service operation. value1 = 145.00D; value2 = 76.54D; result = client.Subtract(value1, value2); Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result); // Call the Multiply service operation. value1 = 9.00D; value2 = 81.25D; result = client.Multiply(value1, value2); Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result); // Call the Divide service operation. value1 = 22.00D; value2 = 7.00D; result = client.Divide(value1, value2); Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result); //Closing the client gracefully closes the connection and cleans up resources client.Close(); Console.WriteLine(); Console.WriteLine("Press <ENTER> to terminate client."); Console.ReadLine(); } }
Скомпилируйте и запустите клиент.