Comment : héberger et exécuter un service Windows Communication Foundation de base
Il s'agit de la troisième des six tâches requises pour créer un service Windows Communication Foundation (WCF) de base et un client pouvant appeler le service. Pour disposer d'une vue d'ensemble des six tâches, consultez la rubrique Didacticiel de mise en route.
Cette rubrique décrit comment exécuter un service Windows Communication Foundation (WCF) de base. Cette procédure se compose des étapes suivantes :
Créer une adresse de base pour le service.
Créer un hôte de service pour le service.
Activer l'échange de métadonnées.
Ouvrir l'hôte de service.
La liste complète du code écrit dans cette tâche est fournie dans l'exemple qui suit la procédure. Ajoutez le code suivant dans la méthode Main()
définie dans la classe Program
. Cette classe a été générée lorsque vous avez créé la solution Service
.
Pour configurer une adresse de base pour le service
Créer une instance Uri pour l'adresse de base du service. Cet URI spécifie le schéma HTTP, votre ordinateur local, le numéro de port 8000 et le chemin ServiceModelSample/Service du service spécifié pour l'espace de noms du service dans le contrat de service.
Dim baseAddress As New Uri("https://localhost:8000/ServiceModelSamples/Service")
Uri baseAddress = new Uri("https://localhost:8000/ServiceModelSamples/Service");
Pour héberger le service
Importez l'espace de noms
System.ServiceModel.Description
. Cette ligne de code doit être placée en haut du fichier Program.cs/Program.vb avec le reste des instructions using ou imports.Imports System.ServiceModel.Description
using System.ServiceModel.Description;
Créez une nouvelle instance ServiceHost pour héberger le service. Vous devez spécifier le type qui implémente le contrat de service et l'adresse de base. Pour cet exemple, l'adresse de base est
https://localhost:8000/ServiceModelSamples/Service
etCalculatorService
est le type qui implémente le contrat de service.Dim selfHost As New ServiceHost(GetType(CalculatorService), baseAddress)
ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);
Ajoutez une instruction try-catch qui intercepte un objet CommunicationException et ajoutez le code lors des trois étapes suivantes au bloc try. La clause catch doit afficher un message d'erreur puis appeler
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(); }
Ajoutez un point de terminaison qui expose le service. Pour ce faire, vous devez spécifier le contrat que le point de terminaison expose, une liaison, et l'adresse pour le point de terminaison. Dans cet exemple, spécifiez
ICalculator
comme contrat,WSHttpBinding
comme liaison etCalculatorService
comme adresse. Remarquez ici que l'adresse de point de terminaison est une adresse relative. L'adresse complète du point de terminaison est la combinaison de l'adresse de base et de l'adresse de point de terminaison. Dans ce cas, l'adresse complète esthttps://localhost:8000/ServiceModelSamples/Service/CalculatorService
' Add a service endpoint selfHost.AddServiceEndpoint( _ GetType(ICalculator), _ New WSHttpBinding(), _ "CalculatorService")
selfHost.AddServiceEndpoint( typeof(ICalculator), new WSHttpBinding(), "CalculatorService");
Remarque : Depuis .NET Framework 4, si aucun point de terminaison n'est explicitement configuré pour le service, le runtime ajoute les points de terminaison par défaut lors de l'ouverture de ServiceHost. Cet exemple ajoute explicitement un point de terminaison afin de fournir un exemple de la procédure à suivre. Pour plus d'informations sur le sujet suivant les points de terminaison par défaut, les liaisons et les comportements, consultez Configuration simplifiée et Simplified Configuration for WCF Services. Activer l'échange de métadonnées. Pour ce faire, ajoutez un comportement des métadonnées du service. Dans un premier temps, créez une instance ServiceMetadataBehavior, affectez à la propriété HttpGetEnabled la valeur true, puis ajoutez le nouveau comportement au service. Pour plus d'informations sur le sujet suivant les problèmes de sécurité lors de la publication des métadonnées, consultez 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);
Ouvrez le ServiceHost et attendez les messages entrants. Lorsque l'utilisateur appuie sur la touche ENTRÉE, fermez 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();
Pour vérifier que le service fonctionne
Exécutez le service.exe à partir de Visual Studio. Lors de l'exécution sur Windows Vista, le service doit être exécuté avec les privilèges d'administrateur. Parce que Visual Studio a été exécuté avec les privilèges d'administrateur, service.exe est également exécuté avec ces mêmes privilèges. Vous pouvez aussi démarrer une nouvelle invite de commandes qui l'exécute avec les privilèges d'administrateur et y exécuter service.exe.
Ouvrez Internet Explorer et accédez à la page de débogage du service à l'adresse https://localhost:8000/ServiceModelSamples/Service.
Exemple
L'exemple suivant inclut le contrat de service et l'implémentation d'étapes précédentes dans le didacticiel et héberge le service dans une application console. Compilez les éléments suivants dans un exécutable nommé Service.exe.
Veillez à référencer System.ServiceModel.dll lors de la compilation du code.
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();
}
}
}
}
Remarque : |
---|
Les services tels que celui-ci requièrent que l'autorisation enregistre des adresses HTTP sur l'ordinateur pour écouter. Les comptes Administrateur possèdent cette autorisation, mais l'autorisation pour les espaces de noms HTTP doit être accordée aux comptes qui ne sont pas administrateur. Pour plus d'informations sur le sujet suivant comment configurer des réservations d'espace de noms, consultez Configuration de HTTP et HTTPS. Lors de l'exécution sous Visual Studio, service.exe doit être exécuté avec les privilèges d'administrateur. |
Le service est en cours d'exécution. Poursuivez avec Comment : créer un client Windows Communication Foundation. Pour obtenir des informations de dépannage, consultez Dépannage du didacticiel de mise en route.