WCF Essentials (3)
来源:互联网 发布:中国联通wap网络 编辑:程序博客网 时间:2024/06/05 09:15
6. 端点 (Endpoints)
每个服务都会关联到一个用于定位服务位置的地址(Address),一个用于定义如何与服务进行通讯的绑定(Binding),以及一个告知客户端服务能做什么的契约(Contract),这三样共同组成了服务的助记符 ——ABC。WCF 以端点(Endpoint)这样一个形式来体现三者的关系,端点本身就是地址、契约和绑定的组合体。
端点示意图
每个端点都必须完整拥有这三个组成部分,宿主(host)则通过公开端点来对外提供服务。理论上,端点就是服务的外部交互接口、就像 CLR 或者COM接口。每个服务至少需要公开一个端点,服务上所有的端点都必须拥有唯一的定位地址,单个服务可以提供多个端点供不同类型的客户端调用。这些端点可以使用相同或不同的绑定对象,可以拥有相同或不同的服务契约。单个服务的不同端点之间没有任何关联。
端点配置管理
我们可以在宿主配置文件(app.config / web.config)中对端点参数进行设置。
<services>
<service name = "MyNamespace.MyService">
<endpoint
address = "http://localhost:8000/MyService/"
binding = "wsHttpBinding"
contract = "MyNamespace.IMyContract"
/>
</service>
</services>
</system.serviceModel>
需要注意的是,我们必须指定完整的契约限定名(含 Namespace)。当然,我们可以为单个服务提供多个端点设置。
<endpoint
address = "http://localhost:8000/MyService/"
binding = "wsHttpBinding"
contract = "IMyContract"
/>
<endpoint
address = "net.tcp://localhost:8001/MyService/"
binding = "netTcpBinding"
contract = "IMyContract"
/>
<endpoint
address = "net.tcp://localhost:8002/MyService/"
binding = "netTcpBinding"
contract = "IMyOtherContract"
/>
</service>
在配置文件中设置服务参数是种非常好的选择,它提供了更好的弹性,可以在不修改代码不重新发布系统的情况下对服务的地址、绑定和契约参数进行修改。
我们还可以提供一个或多个默认的基本地址(BaseAddress),这样在端点设置中只需提供相对地址。多个基本地址之间不能冲突,不能在同一个端口进行监听。相对地址通过端点绑定类型与基本地址进行匹配,从而在运行时获得完整地址。如果我们将某个端点设置中的地址设为空值(或省略 address),则表示直接使用某个相匹配的基本地址。
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/" />
<add baseAddress="net.tcp://localhost:8081/" />
</baseAddresses>
</host>
<endpoint
address = "MyService" <!-- http://localhost:8080/MyService -->
binding = "wsHttpBinding"
contract = "IMyContract"
/>
<endpoint
address = "MyService" <!-- net.tcp://localhost:8081/MyService -->
binding = "netTcpBinding"
contract = "IMyContract"
/>
<endpoint
address = "net.tcp://localhost:8002/MyService/"
binding = "netTcpBinding"
contract = "IMyOtherContract"
/>
</service>
我们还可以进一步对端点中的绑定参数进行设置。每种绑定类型可拥有多个名称(name)不同的参数设置,然后在端点的 bindingConfiguration 属性中指定关联设置名称即可。
<services>
<service name = "MyService">
<endpoint
address = "net.tcp://localhost:8000/MyService/"
bindingConfiguration = "TransactionalTCP"
binding = "netTcpBinding"
contract = "IMyContract"
/>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name = "TransactionalTCP"
transactionFlow = "true"
/>
</netTcpBinding>
</bindings>
</system.serviceModel>
下面是一个完整的演示。
interface IMyService
{
[OperationContract]
void Test(int x);
}
class MyService : IMyService
{
public void Test(int x)
{
Console.WriteLine(x);
}
}
class Program
{
static void Main(string[] args)
{
var host = new ServiceHost(typeof(MyService));
host.Open();
// ------------
var http = ChannelFactory<IMyService>.CreateChannel(new BasicHttpBinding(),
new EndpointAddress("http://localhost:801/MyService"));
using (http as IDisposable)
{
http.Test(1);
}
// ----------------
var tcp = ChannelFactory<IMyService>.CreateChannel(new NetTcpBinding(),
new EndpointAddress("net.tcp://localhost:802/MyService"));
using (tcp as IDisposable)
{
tcp.Test(1);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey(true);
Environment.Exit(0);
}
}
App.config
<configuration>
<system.serviceModel>
<services>
<service name="Learn.CUI.MyService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:801" />
<add baseAddress="net.tcp://localhost:802" />
</baseAddresses>
</host>
<endpoint
address="MyService"
binding="basicHttpBinding"
contract="Learn.CUI.IMyService"
/>
<endpoint
address="MyService"
binding="netTcpBinding"
contract="Learn.CUI.IMyService"
/>
</service>
</services>
</system.serviceModel>
</configuration>
除了使用配置文件外,我们还可以直接在代码中对端点参数进行设置。
Binding wsBinding = new WSHttpBinding( );
Binding tcpBinding = new NetTcpBinding( );
host.AddServiceEndpoint(typeof(IMyContract), wsBinding, "http://localhost:8000/MyService");
host.AddServiceEndpoint(typeof(IMyContract), tcpBinding, "net.tcp://localhost:8001/MyService");
host.AddServiceEndpoint(typeof(IMyOtherContract), tcpBinding, "net.tcp://localhost:8002/MyService");
host.Open( );
ServiceHost 类型用来创建 Self-Hosting,AddServiceEndpoint(...) 有多个重载方法,用于添加端点设置。
和上面配置文件中所做的一样,在代码里同样可以使用绝对或相对地址。
Uri baseTcpUri = new Uri("net.tcp://localhost:8001");
ServiceHost host = new ServiceHost(typeof(MyService), baseHttpUri, baseTcpUri);
Binding wsBinding = new WSHttpBinding( );
Binding tcpBinding = new NetTcpBinding( );
host.AddServiceEndpoint(typeof(IMyContract), wsBinding, "MyService");
host.AddServiceEndpoint(typeof(IMyContract), tcpBinding, "MyService");
host.AddServiceEndpoint(typeof(IMyOtherContract), tcpBinding, "net.tcp://localhost:8002/MyService");
host.Open( );
至于绑定类型的设置,同样没啥问题。
NetTcpBinding tcpBinding = new NetTcpBinding( );
tcpBinding.TransactionFlow = true;
host.AddServiceEndpoint(typeof(IMyContract), tcpBinding, "net.tcp://localhost:8000/MyService");
host.Open( );
- WCF Essentials (3)
- WCF Essentials (1)
- WCF Essentials (2)
- WCF Essentials (4)
- WCF Essentials (5)
- WCF Essentials (6)
- WCF Essentials (7)
- WCF Coding Standards - Essentials
- 3D Graphics Engine Essentials
- 3D Graphics Engine Essentials
- Essentials of Programming Languages, 3rd Edition
- Notes on <Papervision 3D Essentials> - 01
- Notes on <Papervision 3D Essentials> - 02
- Learn KeyShot 3D Animation Essentials
- Oracle Essentials: Oracle Database 10g, 3rd Edition
- About Face 3: The Essentials of Interaction Design
- Solaris™ 10 System Administration Essentials 3,4 -Software Management
- MySQL5.0 3种不同版本:Essentials、Complete、Noinstall
- 实现下载的代码?请指教
- WCF Essentials (2)
- 基于消息驱动的面向对象通用C/S应用框架(六)
- Discuz! 7.0 - 数据调用中[show]标记的处理中有缺陷
- 基于消息驱动的面向对象通用C/S应用框架(七)
- WCF Essentials (3)
- 基于消息驱动的面向对象通用C/S应用框架(八)
- WCF Essentials (4)
- 如何开启Vista的隐藏管理员共享
- 基于消息驱动的面向对象通用C/S应用框架(九)
- WCF Essentials (5)
- 基于消息驱动的面向对象通用C/S应用框架(十)
- ruby中的的数组和字符串的转换
- WCF Essentials (6)