WCF一步一步往前爬(六)

本文介绍了WCF中PerSession会话模式的工作原理及其应用场景,包括客户端和服务端的具体交互过程。并通过示例代码展示了如何配置服务端和客户端来实现会话模式。此外,还对比了PerCall和Single两种模式的不同。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

wcf中会话模式(PerSession)的应用。

PerSession工作方式:

客户端创建代理对象(Proxy) 客户端第一次调用代理对象的一个契约操作,代理对象将其调用请求传递给服务宿主 宿主程序创建新的服务对象,并执行请求操作,如果有必要,返回客户端应答 客户端再次发出调用操作的请求,宿主会先判断是否已有建立好的会话,如果存在,则不需要再创建新的服务对象,直接使用老对象即可。 在时间达到指定要求或者因一些特殊原因,会话会过期,此时服务对象销毁。

对于会话模式,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:

  1. 客户端创建代理对象(Proxy)
  2. 客户端调用代理对象的一个契约操作,代理对象将其传递给服务宿主程序。
  3. 宿主应用程序创建一新的服务契约对象,并且执行请求操作
  4. 在执行完请求操作后,如果要求有应答,那么服务契约会给代理对象一个应答,然后销毁自己(如果实现了IDisposable,则调用Dispose())。

Single :

  1. 服务端启动,同时创建服务对象
  2. 客户端通过代理调用契约操作
  3. 第一步中创建的服务对象接受请求 ,并执行操作,进行必要的应答
  4. 第一步创建的服务对象将一直保留
  5. 服务关闭,第一步创建的对象销毁
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值