WCF会话(SESSION)与实例(INSTANCE)管理

2024-06-18 15:48

本文主要是介绍WCF会话(SESSION)与实例(INSTANCE)管理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、理解Session

1.Session的作用:保留Client和Service之间交互的状态,确保Client与Service之间交互唯一性(SessionId),即:多个Client同时访问Service,Service能够区别;

2.ASP.NET Session 与 WCF Session区别:

在WCF中,Session属于Service Contract的范畴,并在Service Contract定义中通过SessionModel参数来实现。WCF中会话具有以下几个重要的特征:

  • Session都是由Client端显示启动和终止的。

  在WCF中Client通过创建的代理对象来和服务进行交互,在支持Session的默认情况下,Session是和具体的代理对象绑定在一起,当Client通过调用代理对象的某个方法来访问服务时,Session就被初始化,直到代理的关闭,Session则被终止。我们可以通过两种方式来关闭代理:一是调用ICommunicationObject.Close 方法,二是调用ClientBase<TChannel>.Close 方法 。我们也可以通过服务中的某个操作方法来初始化、或者终止Session,可以通过OperationContractAttribute的IsInitiating和IsTerminating参数来指定初始化和终止Session的Operation。

  • 在WCF会话期间,传递的消息按照它发送的顺序被接收。
  • WCF并没有为Session支持保存相关的状态数据。

  而Asp.net中的Session具有以下特性:

  • Asp.net的Session总是由服务端启动的,即在服务端进行初始化的。
  • Asp.net中的Session是无序的,不能保证请求处理是有序的。
  • Asp.net是通过在服务端以某种方式保存State数据来实现对Session的支持,例如保存在Web Server端的内存中。

二、WCF实例管理

对于Client来说,它实际上不能和Service进行直接交互,它只能通过客户端创建的Proxy来间接地和Service进行交互,然而真正的调用而是通过服务实例来进行的。我们把通过Client的调用来创建最终的服务实例过程称作激活,在.NET Remoting中包括Singleton模式、SingleCall模式和客户端激活方式,WCF中也有类似的服务激活方式:单调服务(PerCall)、会话服务(PerSession)和单例服务(Singleton)。

  • 单调服务(Percall):为每个客户端请求分配一个新的服务实例。类似.NET Remoting中的SingleCall模式
  • 会话服务(Persession):在会话期间,为每次客户端请求共享一个服务实例,类似.NET Remoting中的客户端激活模式。
  • 单例服务(Singleton):所有客户端请求都共享一个相同的服务实例,类似于.NET Remoting的Singleton模式。但它的激活方式需要注意一点:当为对于的服务类型进行Host的时候,与之对应的服务实例就被创建出来,之后所有的服务调用都由这个服务实例进行处理。

注意:

1.WCF中服务激活的默认方式是PerSession,但不是所有的Bingding都支持Session,比如BasicHttpBinding就不支持Session。

2.通过在服务契约接口上ServiceContract(SessionMode = 会话模式)来显式设置会话模式,禁用会话模式,可设为:SessionMode.NotAllowed

3.通过在Service实现类上ServiceBehavior(InstanceContextMode=激活方式)来显式设置服务实例激活方式

三、运用WCF 的单例服务(Singleton)及会话模式,实现系统同一时间只能允许同一用户名登录(即:单次登录),代码如下:

1.定义服务契约及创建服务类

using System.ServiceModel;namespace WcfServiceLibrary1
{[ServiceContract(SessionMode = SessionMode.Required)]public interface ILogin{[OperationContract]string Login(string username, string password);[OperationContract(IsOneWay=true)]void Logout();}
}using System.Collections.Generic;
using System.ServiceModel;namespace WcfServiceLibrary1
{[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]public class LoginService:ILogin{private Dictionary<string,string> loginUsers;public LoginService(){this.loginUsers = new Dictionary<string, string>();}public string Login(string username, string password){if (!string.IsNullOrEmpty(username) && password == "123456"){if (!this.loginUsers.ContainsValue(username)){this.loginUsers.Add(OperationContext.Current.SessionId,username);return null;}else{return string.Format("用户{0}已在其它地方有登录,同一时间不允许同一用户重复登录!", username);}}else{return "用户名或密码错误!";}}public void Logout(){this.loginUsers.Remove(OperationContext.Current.SessionId);}}
}

2.创建宿主程序

CONFIG配置文件:

<?xml version="1.0" encoding="utf-8" ?>
<configuration><system.serviceModel><behaviors><behavior name="LoginServicemetadatabehavior"><serviceMetadata httpGetEnabled="true"/></behavior></behaviors><services><service name="WcfServiceLibrary1.LoginService" behaviorConfiguration="LoginServicemetadatabehavior"><endpoint address="" binding="wsHttpBinding" contract="WcfServiceLibrary1.ILogin"></endpoint><host><baseAddresses><add baseAddress="http://127.0.0.1:10900/LoginService"/></baseAddresses></host></service></services></system.serviceModel>
</configuration>

代码部份:

using System;
using WcfServiceLibrary1;
using System.ServiceModel;
using System.ServiceModel.Description;namespace ConsoleApplicationHost
{class Program{static void Main(string[] args){BuildLoginServiceHostByConfig();}static void BuildLoginServiceHostByConfig(){using (ServiceHost host = new ServiceHost(typeof(LoginService))){host.Opened += (s, e) => { Console.WriteLine("LoginService已经启动,按按回车键终止服务!"); };host.Open();Console.ReadLine();}}}
}

3.在客户端程序调用WCF服务

首先添加并引用WCF服务,VS自动生成WCF服务相关的接口与代理类,这里是:LoginClient

然后就可以直接使用LoginClient来调用WCF服务相关方法,代码如下:

using System;
using System.ServiceModel;
using WcfServiceLibrary1;namespace ConsoleApplicationClient
{class Program{static void Main(string[] args){CallLoginService();Console.WriteLine("按任意键结束。");Console.Read();}static void CallLoginService(){using (LoginServices.LoginClient proxy = new LoginServices.LoginClient()){Console.Write("请输入用户名:");string input1 = Console.ReadLine();Console.Write("请输入密码:");string input2 = Console.ReadLine();string loginResult = proxy.Login(input1, input2);if (!string.IsNullOrEmpty(loginResult)){Console.WriteLine(loginResult);return;}Console.WriteLine("恭喜你,登录成功!");Console.Write("若需登出,请输入Y:");string input3 = Console.ReadLine();if (input3 == "Y"){proxy.Logout();Console.WriteLine("登出成功!");}}}}
}

如果同时打开多个客户端程序,并输入相同的用户名,只要有一个登录成功或登录成功后不登出,其余的均会登录不上,报错!效果如下图示:

当然也可以利用其它激活方式实现更多功能,在此就不再重述,原理相同!

本文参考与引用了以下作者的文章:

跟我一起学WCF(8)——WCF中Session、实例管理详解

这篇关于WCF会话(SESSION)与实例(INSTANCE)管理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1072425

相关文章

用Microsoft.Extensions.Hosting 管理WPF项目.

首先引入必要的包: <ItemGroup><PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" /><PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" /><PackageReference Include="Serilog

swiper实例

大家好,我是燐子,今天给大家带来swiper实例   微信小程序中的 swiper 组件是一种用于创建滑动视图的容器组件,常用于实现图片轮播、广告展示等效果。它通过一系列的子组件 swiper-item 来定义滑动视图的每一个页面。 基本用法   以下是一个简单的 swiper 示例代码:   WXML(页面结构) <swiper autoplay="true" interval="3

Java面试题:通过实例说明内连接、左外连接和右外连接的区别

在 SQL 中,连接(JOIN)用于在多个表之间组合行。最常用的连接类型是内连接(INNER JOIN)、左外连接(LEFT OUTER JOIN)和右外连接(RIGHT OUTER JOIN)。它们的主要区别在于它们如何处理表之间的匹配和不匹配行。下面是每种连接的详细说明和示例。 表示例 假设有两个表:Customers 和 Orders。 Customers CustomerIDCus

关于如何更好管理好数据库的一点思考

本文尝试从数据库设计理论、ER图简介、性能优化、避免过度设计及权限管理方面进行思考阐述。 一、数据库范式 以下通过详细的示例说明数据库范式的概念,将逐步规范化一个例子,逐级说明每个范式的要求和变换过程。 示例:学生课程登记系统 初始表格如下: 学生ID学生姓名课程ID课程名称教师教师办公室1张三101数学王老师101室2李四102英语李老师102室3王五101数学王老师101室4赵六103物理陈

springboot家政服务管理平台 LW +PPT+源码+讲解

3系统的可行性研究及需求分析 3.1可行性研究 3.1.1技术可行性分析 经过大学四年的学习,已经掌握了JAVA、Mysql数据库等方面的编程技巧和方法,对于这些技术该有的软硬件配置也是齐全的,能够满足开发的需要。 本家政服务管理平台采用的是Mysql作为数据库,可以绝对地保证用户数据的安全;可以与Mysql数据库进行无缝连接。 所以,家政服务管理平台在技术上是可以实施的。 3.1

vue3项目将所有访问后端springboot的接口统一管理带跨域

vue3项目将所有访问后端springboot的接口统一管理带跨域 一、前言1.安装Axios2.创建Axios实例3.创建API服务文件4.在组件中使用API服务 二、跨域三、总结 一、前言 在Vue 3项目中,统一管理所有访问后端Spring Boot接口的最佳实践是创建一个专门的API服务层。这可以让你的代码更加模块化、可维护和集中管理。你可以使用Axios库作为HTT

如何实现一台机器上运行多个MySQL实例?

在一台机器上一个MySQL服务器运行多个MySQL实例有什么好处?这里我先入为主给大家介绍这样做至少存在两个好处(看完这篇文章后理解会更透彻): (1)减轻服务器链接负担 (2)为不同的用户提供不同的mysqld服务器的访问权限以方便这些用户进行自我管理。   下面我介绍具体的实现过程: 一、准备工作     台式机一台、Windows系统、MySQL服务器(我安装的版本是MySQL

逆向学习汇编篇:内存管理与寻址方式

本节课在线学习视频(网盘地址,保存后即可免费观看): ​​https://pan.quark.cn/s/3ceeb9ae6d98​​ 在汇编语言的世界中,内存管理和寻址方式是构建程序的基础。理解这些概念不仅对于编写高效的汇编代码至关重要,也是进行逆向工程分析的关键技能。本文将深入探讨内存管理的基本原则和多种寻址方式,并通过代码案例来展示它们的实际应用。 1. 内存管理 内存管理涉及如何分配

Git代码管理的常用操作

在VS022中,Git的管理要先建立本地或远程仓库,然后commit到本地,最后push到远程代码库。 或者不建立本地的情况,直接拉取已有的远程代码。 Git是一个分布式版本控制系统,用于跟踪和管理文件的变化。它可以记录文件的修改历史,并且可以轻松地回滚到任何历史版本。 Git的基本概念包括: 仓库(Repository):Git使用仓库来存储文件的版本历史。一个仓库可以包含多个文件

Yarn:引领JavaScript包管理新潮流

在浩瀚的JavaScript世界中,包管理工具如同一位精明的管家,帮助开发者管理着各式各样的代码包。而Yarn,这位新晋管家,以其高效、稳定和安全的特性,正逐渐成为开发者心中的新宠。本文将带您走进Yarn的世界,让您轻松掌握Yarn的强大特性和使用方法。 特性一:快速如闪电         想象一下,你是一位忙碌的图书馆管理员,每天需要整理成千上万的书籍。如果每本书的摆放都