在時間達到指定要求或者因一些特殊原因,會話會到期,此時服務物件銷毀。對於會話模式,basicHttpBinding是不支援的,所以如果是發布到iis,終結點的綁定不能是basicHttpBinding,可以選擇netTcpBinding和ws2007HttpBinding
下面看看例子:
服務端:
namespace LifeCycleService
{
// 注意: 使用“重構”菜單上的“重新命名”命令,可以同時更改代碼和設定檔中的介面名“IService”。
[ServiceContract(SessionMode= SessionMode.Required)]
public interface ILifeCycleService
{
[OperationContract]
string DoWork();
[OperationContract]
string GetInstance();
}
}
namespace LifeCycleService
{
// 注意: 使用“重構”菜單上的“重新命名”命令,可以同時更改代碼、服務和設定檔中的類名“Service”。
//[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
//[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class LifeCycleServiceImpl : ILifeCycleService
{
// 服務執行個體的個數
static int instance;
int times = 0;
// 建構函式,初始化callCount,並將服務執行個體的個數加1
public LifeCycleServiceImpl()
{
instance++;
System.Diagnostics.Debug.WriteLine("Create a new instance: " + instance.ToString() + "");
}
public string GetInstance()
{
string outstr = string.Format("Current Instance is {0}", instance);
return outstr;
}
// 被調用的函數,每次被調用callCount加1
public string DoWork()
{
times++;
string OutStr = string.Format("DoWork() is called by Instance {0}--Times:{1}", OperationContext.Current.SessionId, times);
return OutStr;
}
}
}
<%@ ServiceHost Language="C#" Debug="true" Service="LifeCycleService.LifeCycleServiceImpl" CodeBehind="~/App_Code/LifeCycleService.cs" %>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<services>
<service name="LifeCycleService.LifeCycleServiceImpl">
<endpoint address="http://lisheng/LifeCycleService/LifeCycleService.svc" binding="ws2007HttpBinding"
name="LifeCycle_ws2007HttpBinding" contract="LifeCycleService.ILifeCycleService" />
<endpoint address="net.tcp://lisheng/LifeCycleService/LifeCycleService.svc" binding="netTcpBinding"
name="LifeCycle_netTcpBinding" contract="LifeCycleService.ILifeCycleService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 為避免泄漏中繼資料資訊,請在部署前將以下值設定為 false 並刪除上面的中繼資料終結點 -->
<serviceMetadata httpGetEnabled="true"/>
<!-- 要接收故障異常詳細資料以進行調試,請將以下值設定為 true。在部署前設定為 false 以避免泄漏異常資訊-->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="false">
<serviceActivations>
<add relativeAddress="LifeCycleService.svc" service="LifeCycleService.LifeCycleServiceImpl" />
</serviceActivations>
</serviceHostingEnvironment>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
用戶端:
static void Main(string[] args)
{
Console.WriteLine("When the service is ready, press any key to countinue!");
Console.ReadKey(true);
using (LifeCycleServiceClient client1 = new LifeCycleServiceClient("LifeCycle_netTcpBinding"))
{
client1.Open();
Console.WriteLine(string.Format("=============start: {0}================", client1.GetInstance()));
for (int i = 1; i < 4; i++)
{
Console.WriteLine(client1.DoWork());
}
Console.WriteLine(string.Format("=============end: {0}================", client1.GetInstance()));
}
Console.WriteLine();
using (LifeCycleServiceClient client2 = new LifeCycleServiceClient("LifeCycle_ws2007HttpBinding"))
{
client2.Open();
Console.WriteLine(string.Format("=============start: {0}================", client2.GetInstance()));
for (int i = 1; i < 4; i++)
{
Console.WriteLine(client2.DoWork());
}
Console.WriteLine(string.Format("=============end: {0}================", client2.GetInstance()));
}
Console.ReadKey(true);
}
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="LifeCycle_netTcpBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
<ws2007HttpBinding>
<binding name="LifeCycle_ws2007HttpBinding" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</ws2007HttpBinding>
</bindings>
<client>
<endpoint address="http://lisheng/LifeCycleService/LifeCycleService.svc"
binding="ws2007HttpBinding" bindingConfiguration="LifeCycle_ws2007HttpBinding"
contract="LifeCycleService.ILifeCycleService" name="LifeCycle_ws2007HttpBinding">
<identity>
<servicePrincipalName value="host/lisheng" />
</identity>
</endpoint>
<endpoint address="net.tcp://lisheng/LifeCycleService/LifeCycleService.svc"
binding="netTcpBinding" contract="LifeCycleService.ILifeCycleService"
name="LifeCycle_netTcpBinding" />
</client>
</system.serviceModel>
</configuration>
看看另外兩種模式工作方式:
PerCall:
- 用戶端建立代理對象(Proxy)
- 用戶端調用代理對象的一個契約操作,代理對象將其傳遞給服務宿主程式。
- 宿主應用程式建立一新的服務契約對象,並且執行請求操作
- 在執行完請求操作後,如果要求有應答,那麼服務契約會給代理對象一個應答,然後銷毀自己(如果實現了IDisposable,則調用Dispose())。
Single :
- 服務端啟動,同時建立服務物件
- 用戶端通過代理調用契約操作
- 第一步中建立的服務物件接受請求 ,並執行操作,進行必要的應答
- 第一步建立的服務物件將一直保留
- 服務關閉,第一步建立的對象銷毀