终端点创建概述

与 Windows Communication Foundation (WCF) 服务的所有通信都通过服务的 终结点 进行。 终结点提供客户端对 WCF 服务提供的功能的访问权限。 本部分介绍终结点的结构,并概述了如何在配置和代码中定义终结点。

终结点的结构

每个终结点都包含一个地址,该地址指示在何处查找终结点、指定客户端如何与终结点通信的绑定以及标识可用方法的协定。

  • 地址。 该地址唯一标识终结点,并告知潜在使用者服务所在的位置。 它由 EndpointAddress 地址在 WCF 对象模型中表示,该地址包含统一资源标识符(URI)和地址属性,其中包括标识、某些 Web 服务描述语言(WSDL)元素和可选标头集合。 可选标头提供用于标识或与终结点交互的其他详细寻址信息。 有关详细信息,请参阅 指定终结点地址

  • 绑定。 绑定指定如何与终结点通信。 绑定指定终结点如何与世界通信,包括要使用的传输协议(例如 TCP 或 HTTP),用于消息的编码(例如文本或二进制),以及需要哪些安全要求(例如,安全套接字层 [SSL] 或 SOAP 消息安全性)。 有关详细信息,请参阅 使用绑定配置服务和客户端

  • 服务协定。 服务协定概述了终结点向客户端公开的功能。 协定指定客户端可以调用的作、消息的形式以及调用作所需的输入参数或数据的类型,以及客户端可以期望的处理或响应消息的类型。 三种基本的协定类型与基本消息交换模式 (MEP) 相对应:数据报(单向)、请求/答复和双工(双向)。 服务协定还可以使用数据和消息协定来要求访问特定数据类型和消息格式。 有关如何定义服务协定的详细信息,请参阅 设计服务协定。 请注意,也可以要求客户端实现服务定义的协定(称为回调协定),以便在双工 MEP 下接收服务的消息。 有关详细信息,请参阅双工服务

服务的终结点可以通过编写代码以命令方式或通过配置以声明方式进行指定。 如果未指定终结点,则运行时会通过为每个基址添加一个默认终结点来为服务实现的每个服务协定提供默认终结点。 在代码中定义终结点通常不可行,因为部署服务的绑定和地址通常不同于在开发服务时使用的终结点。 通常,使用配置而不是代码定义服务终结点更为实用。 将绑定和寻址信息从代码中保留允许更改,而无需重新编译和重新部署应用程序。

注释

添加执行模拟的服务终结点时,必须使用 AddServiceEndpoint 方法之一或 GetContract(Type, Type) 方法来将协定正确加载到新的 ServiceDescription 对象。

在代码中定义终结点

以下示例演示如何使用以下内容在代码中指定终结点:

  • IEcho 类型的服务定义一个合同,该服务接受某人的姓名并以“Hello <name>!”作为响应。

  • 实现由 Echo 协定定义的该类型的 IEcho 服务。

  • 指定服务的终结点地址 http://localhost:8000/Echo

  • 使用Echo绑定来配置WSHttpBinding服务。

namespace Echo
{
   // Define the contract for the IEcho service
   [ServiceContract]
   public interface IEcho
   {
       [OperationContract]
       String Hello(string name)
   }

   // Create an Echo service that implements IEcho contract
   class Echo : IEcho
   {
      public string Hello(string name)
      {
         return "Hello" + name + "!";
      }
      public static void Main ()
      {
          //Specify the base address for Echo service.
          Uri echoUri = new Uri("http://localhost:8000/");

          //Create a ServiceHost for the Echo service.
          ServiceHost serviceHost = new ServiceHost(typeof(Echo),echoUri);

          // Use a predefined WSHttpBinding to configure the service.
          WSHttpBinding binding = new WSHttpBinding();

          // Add the endpoint for this service to the service host.
          serviceHost.AddServiceEndpoint(
             typeof(IEcho),
             binding,
             echoUri
           );

          // Open the service host to run it.
          serviceHost.Open();
     }
  }
}
' Define the contract for the IEcho service
    <ServiceContract()> _
    Public Interface IEcho
        <OperationContract()> _
        Function Hello(ByVal name As String) As String
    End Interface

' Create an Echo service that implements IEcho contract
    Public Class Echo
        Implements IEcho
        Public Function Hello(ByVal name As String) As String _
 Implements ICalculator.Hello
            Dim result As String = "Hello" + name + "!"
            Return result
        End Function

' Specify the base address for Echo service.
Dim echoUri As Uri = New Uri("http://localhost:8000/")

' Create a ServiceHost for the Echo service.
Dim svcHost As ServiceHost = New ServiceHost(GetType(HelloWorld), echoUri)

' Use a predefined WSHttpBinding to configure the service.
Dim binding As New WSHttpBinding()

' Add the endpoint for this service to the service host.
serviceHost.AddServiceEndpoint(GetType(IEcho), binding, echoUri)

' Open the service host to run it.
serviceHost.Open()

注释

服务主机是以一个基础地址创建的,然后相对于基础地址的其他部分被指定为终结点的一部分。 此地址分区允许为主机上的服务更方便地定义多个终结点。

注释

服务应用程序中的ServiceDescription属性不得在OnOpening上的ServiceHostBase方法之后进行修改。 如果修改通过该点的某些成员(如 Credentials 属性以及 AddServiceEndpointServiceHostBase 上的 ServiceHost 方法),则将引发异常。 某些允许你修改它们,但结果是不确定的。

同样,在调用 ServiceEndpoint 上的 OnOpening 之后不能在客户端上修改 ChannelFactory 值。 如果超出该点修改,该 Credentials 属性将引发异常。 可以修改其他客户端说明值而不出错,但结果未定义。

无论是对于服务还是客户端,建议在调用 Open前修改说明。

在配置中定义终结点

创建应用程序时,通常需要将决策推迟到部署应用程序的管理员。 例如,通常无法提前知道服务地址(URI)是什么。 最好允许管理员在创建服务后执行此作,而不是对地址进行硬编码。 这种灵活性是通过配置实现的。 有关详细信息,请参阅 “配置服务”。

注释

使用 ServiceModel 元数据实用工具(Svcutil.exe)/config:文件名[,文件名]开关快速创建配置文件。

使用默认终结点

如果在代码或配置中未指定任何终结点,则运行时通过为该服务实现的每个服务协定的每个基地址添加一个默认终结点,来提供默认终结点。 可以在代码或配置中指定基地址,并在Open()调用ServiceHost时添加默认终结点。 此示例与上一节中的示例相同,但由于未指定任何终结点,因此会添加默认终结点。

namespace Echo
{
   // Define the contract for the IEcho service
   [ServiceContract]
   public interface IEcho
   {
       [OperationContract]
       String Hello(string name)
   }

   // Create an Echo service that implements IEcho contract
   public class Echo : IEcho
   {
      public string Hello(string name)
      {
         return "Hello" + name + "!";
      }
      public static void Main ()
      {
          //Specify the base address for Echo service.
          Uri echoUri = new Uri("http://localhost:8000/");

          //Create a ServiceHost for the Echo service.
          ServiceHost serviceHost = new ServiceHost(typeof(Echo),echoUri);

          // Open the service host to run it. Default endpoints
          // are added when the service is opened.
          serviceHost.Open();
     }
  }
}
' Define the contract for the IEcho service
    <ServiceContract()> _
    Public Interface IEcho
        <OperationContract()> _
        Function Hello(ByVal name As String) As String
    End Interface

' Create an Echo service that implements IEcho contract
    Public Class Echo
        Implements IEcho
        Public Function Hello(ByVal name As String) As String _
 Implements ICalculator.Hello
            Dim result As String = "Hello" + name + "!"
            Return result
        End Function

' Specify the base address for Echo service.
Dim echoUri As Uri = New Uri("http://localhost:8000/")

' Open the service host to run it. Default endpoints
' are added when the service is opened.
serviceHost.Open()

如果显式提供终结点,则仍可在调用AddDefaultEndpoints之前通过在ServiceHost上调用Open来添加默认终结点。 有关默认终结点的详细信息,请参阅 WCF 服务的 简化配置简化配置

另请参阅