[WCF] Hosting
IIS hosting
驻留于 IIS 的主要优点在于 host 进程会在客户端首次请求服务时启动和由 IIS 来管理 host 进程的生命周期。缺点则是一旦选择了驻留于 IIS 那么就只能选择 HTTP 来进行数据传输了,而如果驻留于 IIS5 的话,另一个限制则是所有的服务都只能使用相同的端口号。
下面是创建一个 IIS hosting 的步骤:
1. 在 VS2005 中创建一个 Web 站点(WCF Service)
2. 修改该站点下面的 .svc 文件
<% @ServiceHost Language="C#"
Debug="true"
Service="Anrs.Service.AnrsService"
CodeBehind="~/App_Code/Services/AnrsService.cs" %>
.svc 文件的内容非常简单,就是标识服务及服务所在的文件。这里需要注意的就是服务的名字空间是 ServiceContract 特性中指定的名字空间,而不是接口所在的名字空间。
3. 修改 Web.config 配置文件
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.serviceModel>
<services>
<service name="Anrs.Service.AnrsService" behaviorConfiguration="returnFaults">
<endpoint contract="Anrs.Service.IAnrsServiceContract1" binding="wsHttpBinding"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="returnFaults" >
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.web>
<compilation debug="true"/>
</system.web>
</configuration>
同 .svc 文件一样,需要注意 service 节点的 name 属性值指定的名字空间。所有设置 OK 以后,如果在浏览器中访问 .svc 文件就能看到下面这样的效果。
Self-Hosting
在 VS2005 中创建一个 Self-Hosting 也是非常简单的,下面是一个典型的 Console Self-Hosting 的例子。
using System.ServiceModel;
namespace Anrs.Service
{
class Program
{
static void Main(string[] args)
{
Uri baseAddress = new Uri("http://localhost:8086/");
ServiceHost sh = new ServiceHost(typeof(AnrsService), baseAddress);
sh.Open();
Console.Write("Press any key to exit");
Console.ReadLine();
sh.Close();
}
}
}
ServiceHost 类派生于 ServiceHostBase 抽象类,后者又派生于 CommunicationObject 抽象类,而 CommunicationObject 则实现了 ICommunicationObject 接口。下面是 ICommunicationObject 接口的定义:
{
void Open();
void Close();
void Abort();
event EventHandler Closed;
event EventHandler Closing;
event EventHandler Faulted;
event EventHandler Opened;
event EventHandler Opening;
IAsyncResult BeginClose(AsyncCallback callback, object state);
IAsyncResult BeginOpen(AsyncCallback callback, object state);
void EndClose(IAsyncResult result);
void EndOpen(IAsyncResult result);
CommunicationState State
{ get;}
//More members
}
public enum CommunicationState
{
Created,
Opening,
Opened,
Closing,
Closed,
Faulted
}
接口中定义了 BeginClose/BeginOpen 这两个方法,通过调用这两个方法,可以在 open/close 服务时异步地进行一些操作。