Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом разделе описаны основные шаги, необходимые для создания службы активации процессов Windows (также известной как WAS), размещенной в Windows Communication Foundation (WCF). WAS — это новая служба активации процесса, которая представляет собой обобщение функций служб IIS, работающих с протоколами транспорта, не являющихся HTTP. WCF использует интерфейс адаптера прослушивателя для обмена сообщениями о запросах активации, полученных через протоколы, отличные от HTTP, поддерживаемые WCF, такие как TCP, именованные каналы и очередь сообщений.
Для этого параметра размещения требуется правильно установить и настроить компоненты активации WAS, но не требуется написания кода размещения как части приложения. Дополнительные сведения об установке и настройке WAS см. в разделе "Практическое руководство. Установка и настройка компонентов активации WCF".
Предупреждение
Активация WAS не поддерживается, если конвейер обработки запросов веб-сервера имеет классический режим. Конвейер обработки запросов веб-сервера должен иметь значение "Интегрированный режим", если используется активация WAS.
При размещении службы WCF в WAS стандартные привязки используются обычным образом. Однако при использовании NetTcpBinding и NetNamedPipeBinding для настройки размещенной службы WAS следует выполнить ограничение. Если разные конечные точки используют один и тот же транспорт, параметры привязки должны соответствовать следующим семи свойствам:
РазмерБуфераПодключения
Таймаут инициализации канала
MaxPendingConnections (Максимальное количество ожидающих подключений)
Максимальная задержка вывода
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 (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({value1},{value2}) = {result}"); // Call the Subtract service operation. value1 = 145.00D; value2 = 76.54D; result = client.Subtract(value1, value2); Console.WriteLine($"Subtract({value1},{value2}) = {result}"); // Call the Multiply service operation. value1 = 9.00D; value2 = 81.25D; result = client.Multiply(value1, value2); Console.WriteLine($"Multiply({value1},{value2}) = {result}"); // Call the Divide service operation. value1 = 22.00D; value2 = 7.00D; result = client.Divide(value1, value2); Console.WriteLine($"Divide({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(); } }Скомпилируйте и запустите клиент.