本文参考自http://www.cnblogs.com/wangweimutou/p/4516224.html,纯属读书笔记,加深记忆

一、WCF会话简介

1、在WCF应用程序中,回话将一组消息相互关联,从而形成一个回话(回话可以理解为一段时间内的通话,有开始,有结束),会话是服务端和客户端的终结点在在开始回话和结束回话这段时间内的所有消息的一个集合。

2、WCF中的回话机制通过设置服务协定ServiceContract上的SessionMode的枚举值来设置服务协定是否要求、允许或者拒绝基于回话的绑定.枚举值有以下三种:

(1)、Allowed:允许回话,这是SessionMode的默认值,当前协定允许使用会话,则客户端可以进行连接,并选择建立回话或者不建立回话,但是如果回话结束,然后还在当前回话通道发送消息,将会引起异常.

(2)、Required:要求回话,即所有调用(支持调用的基础消息交换)都必须是同一个会话的一部分,如果回话结束,然后还在当前回话通道发送消息,则会重新开一个通道,进行和服务端的通话

(3)、NotAllowed:禁止会话,即服务端不会与客户端进行消息交换。

3、影响WCF会话机制的因素

(1)、设置了SessionMode的值为Required,当采用的BasicHttpBinding时,因为BasicHttpBinding不支持会话,所以程序报错.

(2)、对于WSHttpBinding和WS2007HttpBinding,如果我们将安全模式设置为None(关闭安全会话)并且关闭可靠会话,他们也无法提供会话支持

(3)、对于NetTcpBinding和NetNamedPipeBinding来说,由于其传输类型本身具有支持会话的特性,所以采用了这两种绑定类型的终结点服务协定的会话模式不能设置为NotAllowed,即使关闭了安全会话和可靠会话也不行。

二、WCF中的回话和Asp.Net中的回话

1、WCF中回话的主要功能有以下:

(1)、他们由调用程序显示启动或者关闭

(2)、会话期间传递的消息按照接收消息的顺序进行处理。

(3)、会话将一组消息相互关联,从而形成对话。该关联的含义是抽象的。例如,一个基于会话的通道可能会根据共享网络连接来关联消息,而另一个基于会话的通道可能会根据消息正文中的共享标记来关联消息。可以从会话派生的功能取决于关联的性质。

(4)、不存在与 WCF 会话相关联的常规数据存储区。

2、Asp.Net中的回话由System.Web.SessionState.HttpSessionState 类提供功能,它的主要功能如下:

(1)、Asp.Net的回话是由服务器启动的

(2)、Asp.Net的回话原本是无序的

(3)、ASP.NET 会话提供了一种跨请求的常规数据存储机制。

三、代码示例

工程结构如下图所示:

1、WCF服务层搭建:新建契约层、服务层、和WCF宿主,添加必须的引用(这里不会的参考本人前面的随笔),配置宿主,生成解决方案,打开Host.exe,开启服务。具体的代码如下:

ICalculate.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks; namespace IService
{
[ServiceContract
(
SessionMode = SessionMode.Required
)
]
public interface ICalculate
{
[OperationContract
(
IsTerminating = true//客户端调用Add后会话通道就会关闭会话
)
]
int Add(int a, int b); [OperationContract]
int Divide(int value1, int value2);
}
}

IUserInfo.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks; namespace IService
{
[ServiceContract]
public interface IUserInfo
{
[OperationContract]
User[] GetInfo(int? id);
} [DataContract]
public class User
{
[DataMember]
public int ID { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public int Age { get; set; }
[DataMember]
public string Nationality { get; set; }
}
}

注:必须引入System.Runtime.Serialization命名空间,应为User类在被传输时必须是可序列化的,否则将无法传输

Calculate.cs

using IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceModel; namespace Service
{
public class Calculate : ICalculate
{
public int Add(int a, int b)
{
return a + b;
} public int Divide(int a, int b)
{
try
{
return a / b;
}
catch (DivideByZeroException) {
throw new FaultException("除数不能为0");//FaultException需要引用System.ServiceModel命名空间
}
}
}
}

UserInfo.cs

using IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Service
{
public class UserInfo : IUserInfo
{
public User[] GetInfo(int? id)
{
List<User> Users = new List<User>();
Users.Add(new User { ID = 1, Name = "张三", Age = 11, Nationality = "China" });
Users.Add(new User { ID = 2, Name = "李四", Age = 12, Nationality = "English" });
Users.Add(new User { ID = 3, Name = "王五", Age = 13, Nationality = "American" }); if (id != null)
{
return Users.Where(x => x.ID == id).ToArray();
}
else
{
return Users.ToArray();
}
}
}
}

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Service;
using System.ServiceModel; namespace Host
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(Calculate)))
{
host.Opened += delegate { Console.WriteLine("服务已经启动,按任意键终止!"); };
host.Open();
Console.Read();
}
}
}
}

App.Config

<?xml version="1.0"?>
<configuration>
<system.serviceModel> <services>
<service name="Service.Calculate" behaviorConfiguration="mexBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:1234/Calculate/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" contract="IService.ICalculate" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services> <behaviors>
<serviceBehaviors>
<behavior name="mexBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

ok,打开Host.exe

服务开启成功!

2、创建一个名为Client的客户端控制台应用程序

Program.cs代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Client
{
class Program
{
static void Main(string[] args)
{
try
{
Client.ServiceReference1.CalculateClient client = new Client.ServiceReference1.CalculateClient();
Console.WriteLine("1+2={0}", client.Add(, ));
Console.WriteLine("1+2={0}", client.Add(, ));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}

通过给ICalculate的Add方法加上了IsTerminating=true,所以当客户端调用了一次Add方法之后,其与服务端的会话通道就会被关闭,所以第二次调用就会报错。

注意:因为默认的服务实例化模型(InstanceContextMode)采用PerSession,即每个服务实例都各自创建了一个会话通道,当Client调用Add后会话关闭,但Client1的会话通道并没有关闭,所以还是可以调用Add。但是如果将InstanceContextMode设置为单例模式,当一个客户端调用完Add方法之后,那么这个通道就被关闭了,另外一个客户端也无法调用了。

WCF系列教程之WCF中的会话的更多相关文章

  1. WCF系列教程之WCF服务协定

    本文参考自:http://www.cnblogs.com/wangweimutou/p/4422883.html,纯属读书笔记,加深记忆 一.服务协定简介: 1.WCF所有的服务协定层里面的服务接口, ...

  2. WCF系列教程之WCF服务宿主与WCF服务部署

    本文参考自http://www.cnblogs.com/wangweimutou/p/4377062.html,纯属读书笔记,加深记忆. 一.简介 任何一个程序的运行都需要依赖一个确定的进程中,WCF ...

  3. WCF系列教程之WCF服务配置工具

    本文参考自http://www.cnblogs.com/wangweimutou/p/4367905.html Visual studio 针对服务配置提供了一个可视化的配置界面(Microsoft ...

  4. WCF系列教程之WCF服务配置

    文本参考自:http://www.cnblogs.com/wangweimutou/p/4365260.html 简介:WCF作为分布式开发的基础框架,在定义服务以及消费服务的客户端时可以通过配置文件 ...

  5. WCF系列教程之WCF消息交换模式之单项模式

    1.使用WCF单项模式须知 (1).WCF服务端接受客户端的请求,但是不会对客户端进行回复 (2).使用单项模式的服务端接口,不能包含ref或者out类型的参数,至于为什么,请参考C# ref与out ...

  6. WCF系列教程之WCF实例化

    本文参考自http://www.cnblogs.com/wangweimutou/p/4517951.html,纯属读书笔记,加深记忆 一.理解WCF实例化机制 1.WCF实例化,是指对用户定义的服务 ...

  7. WCF系列教程之WCF客户端异常处理

    本文参考自:http://www.cnblogs.com/wangweimutou/p/4414393.html,纯属读书笔记,加深记忆 一.简介 当我们打开WCF基础客户通道,无论是显示打开还是通过 ...

  8. WCF系列教程之WCF客户端调用服务

    1.创建WCF客户端应用程序需要执行下列步骤 (1).获取服务终结点的服务协定.绑定以及地址信息 (2).使用该信息创建WCF客户端 (3).调用操作 (4).关闭WCF客户端对象 二.操作实例 1. ...

  9. WCF系列教程之WCF操作协定

    一.简介 1.在定义服务协定时,在它的操作方法上都会加上OperationContract特性,此特性属于OperationContractAttribute 类,将OperationContract ...

随机推荐

  1. PHP爬虫(3)PHP DOM开源代码里的大坑和字符编码

    一.开源代码的问题 在PHP爬虫(2)中介绍了开源工程Sunra.PhpSimple.HtmlDomParser.在实际工作中发现一个问题,例如http://www.163.com的网页数据怎么也抓取 ...

  2. 其他信息: 实体类型 xxxxx 不是当前上下文的模型的一部分。

    我是手动添加的EF类的,   解决方法: 没有在DbContext 添加  public virtual DbSet<xxx> xxxx{ get; set; } 导致不在上下文中

  3. .netcore Swagger 生成 api接口文档

    1, 引用第三方包, Swashbuckle.AspNetCore Swashbuckle.AspNetCore.Swagger Swashbuckle.AspNetCore.SwaggerUI 最简 ...

  4. WinForm 窗体应用程序(初步)之三

    进程: 进程,简单的说,就是让你的程序启动另一个程序. 1.Process.Start("calc");//启动计算器 弊端:只认识系统自带的程序,如果写错系统会崩溃. 2. // ...

  5. NPOI设置Excel单元格字体、边框、对齐、背景色

    代码: ICellStyle cellStyle = workbook.CreateCellStyle(); cellStyle.BorderBottom = BorderStyle.Thin; ce ...

  6. CentOS6.3上部署Ceph

    一.背景知识 搭建ceph的机器分为两种:client和非client(mds.monitor.osd). 配置时client只需要在内核编译时选上ceph就行,而其它三种则还需要编译ceph用户态源 ...

  7. php函数源代码 C编写 【持续更新】

    由于经常被抓取文章内容,在此附上博客文章网址:,偶尔会更新某些出错的数据或文字,建议到我博客地址 :  --> 点击这里 strlen() 获取字符串长度,成功则返回字符串 string 的长度 ...

  8. Nmap 扫描

    最近在家里学习渗透,看到了nmap对服务器进行端口扫描,记录学习如下: Nmap支持非常多的扫描方式,包括TCP Syn ,TCP Connect,TCP ACK,TCP FIN/Xmas/NULL, ...

  9. “全栈2019”Java第一百章:局部内部类可以实现接口吗?

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  10. php性能优化二(PHP配置php.ini)

    PHP优化对于PHP的优化主要是对php.ini中的相关主要参数进行合理调整和设置,以下我们就来看看php.ini中的一些对性能影响较大的参数应该如何设置. # vi /etc/PHP.ini (1) ...