Procedimiento para hospedar y ejecutar un servicio básico de Windows Communication Foundation
Ésta es la tercera de las seis tareas necesarias para crear un servicio Windows Communication Foundation (WCF) básico y un cliente que pueda llamar al servicio. Para obtener información general de las seis tareas, vea el tema Tutorial de introducción.
En este tema se describe cómo ejecutar un servicio básico de Windows Communication Foundation (WCF). Este procedimiento consta de los siguientes pasos:
Crear una dirección base para el servicio.
Crear un host del servicio para el servicio.
Habilitar el intercambio de metadatos
Abrir el host del servicio.
En el ejemplo que se ofrece después del procedimiento, se proporciona una lista completa del código escrito en esta tarea. Agregue el código siguiente al método Main()
definido en la clase Program
. Esta clase se generó al crear la solución Service
.
Configuración de una dirección base para el servicio
Cree una instancia de Uri para la dirección base del servicio. Este identificador URI especifica el esquema HTTP, su equipo local, el número de puerto 8000 y la ruta de acceso ServiceModelSample/Service correspondiente al servicio que se especificó para el espacio de nombres del servicio del contrato.
Dim baseAddress As New Uri("https://localhost:8000/ServiceModelSamples/Service")
Uri baseAddress = new Uri("https://localhost:8000/ServiceModelSamples/Service");
Para hospedar el servicio
Importe el espacio de nombres
System.ServiceModel.Description
. Esta línea de código se debería colocar en la parte superior del archivo Program.cs/Program.vb con el resto de las instrucciones using o imports.Imports System.ServiceModel.Description
using System.ServiceModel.Description;
Cree una nueva instancia de ServiceHost para hospedar el servicio. Debe especificar el tipo que implementa el contrato de servicios y la dirección base. En este ejemplo, la dirección base es
https://localhost:8000/ServiceModelSamples/Service
yCalculatorService
es el tipo que implementa el contrato de servicio.Dim selfHost As New ServiceHost(GetType(CalculatorService), baseAddress)
ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);
Agregue una instrucción try-catch que detecte una CommunicationException y agregue el código en los tres pasos siguientes al bloqueo de intentos. La cláusula catch debería mostrar un mensaje de error y, a continuación, llamar a
selfHost.Abort()
.Try ' ... Catch ce As CommunicationException Console.WriteLine("An exception occurred: {0}", ce.Message) selfHost.Abort() End Try
try { // ... } catch (CommunicationException ce) { Console.WriteLine("An exception occurred: {0}", ce.Message); selfHost.Abort(); }
Agregue un extremo que exponga el servicio. Para ello, debe especificar el contrato que el extremo está exponiendo, un enlace y la dirección del extremo. Para obtener este ejemplo, especifique
ICalculator
como el contrato,WSHttpBinding
como el enlace yCalculatorService
como la dirección. Observe que la dirección del extremo es una dirección relativa. La dirección completa del extremo es la combinación de la dirección base y la dirección del extremo. En este caso la dirección completa eshttps://localhost:8000/ServiceModelSamples/Service/CalculatorService
.' Add a service endpoint selfHost.AddServiceEndpoint( _ GetType(ICalculator), _ New WSHttpBinding(), _ "CalculatorService")
selfHost.AddServiceEndpoint( typeof(ICalculator), new WSHttpBinding(), "CalculatorService");
Nota: A partir de .NET Framework 4, si no se configuran extremos de forma explícita para el servicio, el tiempo de ejecución agrega extremos predeterminados al abrir la clase ServiceHost. En este ejemplo se muestra cómo agregar explícitamente un extremo. Para obtener más información sobre los extremos, enlaces y comportamientos predeterminados, vea Configuración simplificada y Configuración simplificada de los servicios de WCF. Habilite el intercambio de metadatos. Para ello, agregue un comportamiento de metadatos de servicio. Primero, cree una instancia de ServiceMetadataBehavior, establezca la propiedad HttpGetEnabled en true y, a continuación, agregue el nuevo comportamiento al servicio. Para obtener más información sobre los problemas de seguridad al publicar metadatos, vea Security Considerations with Metadata.
' Enable metadata exchange Dim smb As New ServiceMetadataBehavior() smb.HttpGetEnabled = True selfHost.Description.Behaviors.Add(smb)
ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); smb.HttpGetEnabled = true; selfHost.Description.Behaviors.Add(smb);
Abra el ServiceHost y espere a los mensajes entrantes. Cuando el usuario presione la tecla Entrar, cierre el ServiceHost.
selfHost.Open() Console.WriteLine("The service is ready.") Console.WriteLine("Press <ENTER> to terminate service.") Console.WriteLine() Console.ReadLine() ' Close the ServiceHostBase to shutdown the service. selfHost.Close()
selfHost.Open(); Console.WriteLine("The service is ready."); Console.WriteLine("Press <ENTER> to terminate service."); Console.WriteLine(); Console.ReadLine(); // Close the ServiceHostBase to shutdown the service. selfHost.Close();
Para comprobar si el servicio funciona
Ejecute service.exe desde dentro de Visual Studio. Al ejecutarse en Windows Vista, el servicio se debe ejecutar con privilegios de administrador. Dado que Visual Studio se ejecutó con privilegios de administrador, service.exe también se ejecuta con dichos privilegios. También puede iniciar un nuevo símbolo del sistema con privilegios de administrador y ejecutar service.exe desde allí.
Abra Internet Explorer y vaya a la página de depuración del servicio en https://localhost:8000/ServiceModelSamples/Service.
Ejemplo
El siguiente ejemplo incluye el contrato de servicios y la implementación de los pasos anteriores del tutorial y hospeda el servicio en una aplicación de consola. Compile lo siguiente en una aplicación ejecutable llamada Service.exe .
Asegúrese de hacer referencia a System.ServiceModel.dll al compilar el código.
Imports System
Imports System.ServiceModel
Imports System.ServiceModel.Description
Module Service
' Define a service contract.
<ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples")> _
Public Interface ICalculator
<OperationContract()> _
Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double
End Interface
' Service class that implements the service contract.
' Added code to write output to the console window.
Public Class CalculatorService
Implements ICalculator
Public Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Add
Dim result As Double = n1 + n2
Console.WriteLine("Received Add({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result
End Function
Public Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Subtract
Dim result As Double = n1 - n2
Console.WriteLine("Received Subtract({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result
End Function
Public Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Multiply
Dim result As Double = n1 * n2
Console.WriteLine("Received Multiply({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result
End Function
Public Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Divide
Dim result As Double = n1 / n2
Console.WriteLine("Received Divide({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result
End Function
End Class
Class Program
Shared Sub Main()
' Step 1 of the address configuration procedure: Create a URI to serve as the base address.
Dim baseAddress As New Uri("https://localhost:8000/ServiceModelSamples/Service")
' Step 2 of the hosting procedure: Create ServiceHost
Dim selfHost As New ServiceHost(GetType(CalculatorService), baseAddress)
Try
' Step 3 of the hosting procedure: Add a service endpoint.
' Add a service endpoint
selfHost.AddServiceEndpoint( _
GetType(ICalculator), _
New WSHttpBinding(), _
"CalculatorService")
' Step 4 of the hosting procedure: Enable metadata exchange.
' Enable metadata exchange
Dim smb As New ServiceMetadataBehavior()
smb.HttpGetEnabled = True
selfHost.Description.Behaviors.Add(smb)
' Step 5 of the hosting procedure: Start (and then stop) the service.
selfHost.Open()
Console.WriteLine("The service is ready.")
Console.WriteLine("Press <ENTER> to terminate service.")
Console.WriteLine()
Console.ReadLine()
' Close the ServiceHostBase to shutdown the service.
selfHost.Close()
Catch ce As CommunicationException
Console.WriteLine("An exception occurred: {0}", ce.Message)
selfHost.Abort()
End Try
End Sub
End Class
using System;
using System.ServiceModel;
using System.ServiceModel.Description;
namespace Microsoft.ServiceModel.Samples
{
// Define a service contract.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
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);
}
// Service class that implements the service contract.
// Added code to write output to the console window.
public class CalculatorService : ICalculator
{
public double Add(double n1, double n2)
{
double result = n1 + n2;
Console.WriteLine("Received Add({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
public double Subtract(double n1, double n2)
{
double result = n1 - n2;
Console.WriteLine("Received Subtract({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
public double Multiply(double n1, double n2)
{
double result = n1 * n2;
Console.WriteLine("Received Multiply({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
public double Divide(double n1, double n2)
{
double result = n1 / n2;
Console.WriteLine("Received Divide({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
}
class Program
{
static void Main(string[] args)
{
// Step 1 of the address configuration procedure: Create a URI to serve as the base address.
Uri baseAddress = new Uri("https://localhost:8000/ServiceModelSamples/Service");
// Step 2 of the hosting procedure: Create ServiceHost
ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);
try
{
// Step 3 of the hosting procedure: Add a service endpoint.
selfHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(),
"CalculatorService");
// Step 4 of the hosting procedure: Enable metadata exchange.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
// Step 5 of the hosting procedure: Start (and then stop) the service.
selfHost.Open();
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
// Close the ServiceHostBase to shutdown the service.
selfHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}
}
}
}
Nota: |
---|
Servicios como este requieren permiso para registrar las direcciones HTTP en el equipo para la realización de escuchas. Las cuentas Administrador tienen este permiso, pero las cuentas que no son de administrador deben disponer de permisos concedidos para los espacios de nombre HTTP. Para obtener más información sobre configuración de las reservas de espacios de nombres, vea Configuración de HTTP y HTTPS. Al ejecutarse en Visual Studio, the service.exe se debe ejecutar con privilegios de administrador. |
Ahora, el servicio se está ejecutando. Continúe en Creación de un cliente de Windows Communication Foundation. Para obtener más información, vea Solución de problemas con el tutorial de introducción.