.net WCF

news/2025/3/21 3:01:22/

Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分。由 .NET Framework 3.0 开始引入
 WCF合并了Web服务、.net Remoting、消息队列和Enterprise Services的功能并集成在Visual Studio中。
在这里插入图片描述
在这里插入图片描述

WCF 部署到IIS中 自动生成的配置文件如下:
客户端Web.config:

<?xml version="1.0" encoding="utf-8"?><!--有关如何配置 ASP.NET 应用程序的详细消息,请访问http://go.microsoft.com/fwlink/?LinkId=169433--><configuration><system.web><compilation debug="true" targetFramework="4.0" /></system.web><system.serviceModel><bindings><basicHttpBinding><binding name="BasicHttpBinding_IUser" closeTimeout="00:01:00"openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"useDefaultWebProxy="true"><readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"maxBytesPerRead="4096" maxNameTableCharCount="16384" /><security mode="None"><transport clientCredentialType="None" proxyCredentialType="None"realm="" /><message clientCredentialType="UserName" algorithmSuite="Default" /></security></binding></basicHttpBinding></bindings><client><endpoint address="http://localhost/User.svc" binding="basicHttpBinding"bindingConfiguration="BasicHttpBinding_IUser" contract="WCFService.IUser"name="BasicHttpBinding_IUser" /></client></system.serviceModel>
</configuration>

服务端Web.config代码:

<?xml version="1.0" encoding="utf-8"?>
<configuration><system.web><compilation debug="true" targetFramework="4.0" /></system.web><system.serviceModel><behaviors><serviceBehaviors><behavior><!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点 --><serviceMetadata httpGetEnabled="true"/><!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 --><serviceDebug includeExceptionDetailInFaults="false"/></behavior></serviceBehaviors></behaviors><serviceHostingEnvironment multipleSiteBindingsEnabled="true" /></system.serviceModel><system.webServer><modules runAllManagedModulesForAllRequests="true"/></system.webServer></configuration>

由上面的两个配置文件我们发现,客户端system.serviceMode节点有我们刚才讲的endpoint,而服务端为什么没有?这不是和我们刚才讲的有违背吗?那么我们看下面手工修改后[把对看起来很复杂并且对当前的学习无用的配置节删掉]的配置文件的代码(我将服务端和客户端放在一块了):
在这里插入图片描述
  那么第一次的配置文件为什么能执行呢?答案是我们把WCF寄宿在IIS上,而IIS默认监听的就是Http协议[B确定了]并且地址也是相对于IIS上的文件地址[A确定了],合同更不用说了,找到User.svc什么都有了[C确定了],所以在服务端就没有必要显示的写出system.serviceModel,不信你试试,把服务端的配置文件中system.serviceModel节删除,程序一样可以运行!服务器端的endpoint确定了,客户端的endpoint自然要和服务端去对应,所以IDE在生成客户端的配置文件里endpoint写的很详细的,而服务端却没有endpoint。

宿主

在这里插入图片描述
 WCF本身不能够独自运行(每个WCF服务必须宿主在一个Windows进程中)。.net 提供了多种宿主供WCF运行,WCF还是非常灵活的。WCF的宿主可以是 Windows 服务、COM+应用程序、WAS(Windows Activation Services,Windows进程激活服务)或IIS、Windows应用程序,或简单的控制台应用程序及任何.net程序。
 在这里插入图片描述
在这里插入图片描述
控制台应用程序宿主
建立宿主

(1)在解决方案下新建控制台输出项目 WCFHost_Console。

(2)添加 System.ServiceModel.dll 的引用。

(3)添加 WCF 服务类库(WCFLibrary)的项目引用。

(4)创建宿主程序,代码如下:

using System;
using WCFLibrary;
using System.ServiceModel;
using System.ServiceModel.Description;namespace WCFHost_Console
{class Program{static void Main(string[] args){//创建宿主的基地址Uri baseAddress = new Uri("http://localhost:8080/User");//创建宿主using (ServiceHost host = new ServiceHost(typeof(User), baseAddress)){//向宿主中添加终结点host.AddServiceEndpoint(typeof(IUser), new WSHttpBinding(), "");//将HttpGetEnabled属性设置为trueServiceMetadataBehavior smb = new ServiceMetadataBehavior();smb.HttpGetEnabled = true;//将行为添加到Behaviors中host.Description.Behaviors.Add(smb);//打开宿主host.Open();Console.WriteLine("WCF中的HTTP监听已启动....");Console.ReadLine();host.Close();}}}
}

在这个示例中我们把Endpoint中的ABC,基地址,Behaviors等都**直接写在了代码里,但实际应用过程中都是去依赖配置文件,**为了对比说明我们下面的例子中会使用配置文件。
因为上面是部署到IIS中,协议就是http 所以binding 就不需要再客户端绑定了。
在这里插入图片描述

Windows应用程序宿主

建立宿主

(1)在解决方案下新建Windows窗体应用程序项目 WCFHost_Form。

(2)添加 System.ServiceModel.dll 的引用。

(3)添加 WCF 服务类库(WCFLibrary)的项目引用。

(4)添加应用程序配置文件App.config。

(5)创建宿主程序MainForm窗体,并修改App.config,代码如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration><system.serviceModel><services><service name="WCFLibrary.User"><host><baseAddresses><add baseAddress="http://localhost:8081/User"/></baseAddresses></host><endpoint address="" binding="wsHttpBinding" contract="WCFLibrary.IUser"></endpoint></service></services><behaviors><serviceBehaviors><behavior><serviceMetadata httpGetEnabled="True"/><serviceDebug includeExceptionDetailInFaults="False"/></behavior></serviceBehaviors></behaviors></system.serviceModel>
</configuration>using System;
using WCFLibrary;
using System.ServiceModel;
using System.Windows.Forms;
using System.Configuration;namespace WCFHost_Form
{public partial class MainForm : Form{ServiceHost host;public MainForm(){InitializeComponent();}//应用程序加载private void MainForm_Load(object sender, EventArgs e){host = new ServiceHost(typeof(User));//打开宿主host.Open();this.lblState.Text = "WCF中的HTTP监听已启动....";}//应用程序关闭private void MainForm_FormClosed(object sender, FormClosedEventArgs e){host.Close();}}
}

在这里插入图片描述
在这里插入图片描述

配置也是WCF编程中的主要组成部分。在以往的.net应用程序中,我们会把DBConn和一些动态加载类及变量写在配置文件里。但WCF有所不同。他指定向客户端公开的服务,包括服务的地址、服务用于发送和接收消息的传输和消息编码,以及服务需要的安全类型等。使用配置文件后,我们无需编译即可修改WCF的变化的信息,提高了程序的灵活性。

如果在代码里写了配置,那么配置文件将不起作用。
 Web程序在Web.config中配置,应用程序中在App.config中配置。

**

服务配置的主要部分

**
 在Config中配置服务的结点为:<system.serviceModel></system.serviceModel>,在这个节点中主要有三个平级的部分。如下代码所示:

<?xml version="1.0" encoding="utf-8"?><configuration><system.serviceModel><!--配置服务和终结点开始--><services><service><endpoint></endpoint></service></services><!--配置服务和终结点结束--><!--配置绑定开始--><bindings><netTcpBinding><binding></binding></netTcpBinding></bindings><!--配置绑定结束--><!--配置行为开始--><behaviors><serviceBehaviors><behavior></behavior></serviceBehaviors></behaviors><!--配置行为结束--></system.serviceModel></configuration>

在这里插入图片描述

<?xml version="1.0"?>
<configuration><system.serviceModel><!--服务--><services><!--name:名称空间.类型名    name:指定提供服务协定实现的类型,它是完全限定名称(命名空间和类型名称)--> <!--behaviorConfiguration:behavior的名称,请看behavior配置节的名称--><service name="WCFLibrary.User" behaviorConfiguration="MyBehavior"><host><baseAddresses><!-- 每种传输协议的baseAddress,用于跟使用同样传输协议Endpoint定义的相对地址组成完整的地址,每种传输协议只能定义一个baseAddress。HTTP的baseAddress同时是service对外发布服务说明页面的URL --><add baseAddress="http://localhost:8732/Design_Time_Addresses/WCFLibrary/Service/"/></baseAddresses></host><!-- 除非完全限定,否则地址将与上面提供的基址相关,每个服务可以有多个Endpoint --><!-- Address:指定这个Endpoint对外的URI,这个URI可以是个绝对地址,也可以是个相对于baseAddress的相对地址。如果此属性为空,则这个Endpoint的地址就是baseAddress--><!--bindingConfiguration:binding的名称,请看binding配置节的名称--><endpoint address="" binding="wsHttpBinding" contract="WCFLibrary.IUser" bindingConfiguration="myHttpBinding"><identity><dns value="localhost"/></identity></endpoint><!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除--><endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/></service></services><!--绑定--><bindings><wsHttpBinding><binding name="myHttpBinding"><security mode="None"><message clientCredentialType="Windows" /></security></binding></wsHttpBinding></bindings><!--行为--><behaviors><serviceBehaviors><behavior name="MyBehavior"><!-- httpGetEnabled - bool类型的值,表示是否允许通过HTTP的get方法获取sevice的WSDL元数据 --><serviceMetadata httpGetEnabled="True"/></behavior></serviceBehaviors></behaviors></system.serviceModel>
</configuration>

在这里插入图片描述

完整案例:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

WCF在通信过程中有三种模式:请求与答复、单向、双工通信。以下我们一一介绍。
在这里插入图片描述
请求应答模式这种交换模式是使用最多的一中,它有如下特征:
调用服务方法后需要等待服务的消息返回,即便该方法返回 void 类型
相比Duplex来讲,这种模式强调的是客户端的被动接受,也就是说客户端接受到响应后,消息交换就结束了。
在这种模式下,服务端永远是服务端,客户端就是客户端,职责分明。
它是缺省的消息交换模式,设置OperationContract便可以设置为此种消息交换模式
在这里插入图片描述
单向模式:
存在着如下的特征:
只有客户端发起请求,服务端并不会对请求进行回复
不能包含ref或者out类型的参数
没有返回值,返回类型只能为void
通过设置OperationContract的IsOneWay=True可以将满足要求的方法设置为这种消息交换模式
在这里插入图片描述
双工通讯Duplex具有以下特点:

1它可以在处理完请求之后,通过请求客户端中的回调进行响应操作

2.消息交换过程中,服务端和客户端角色会发生调换

3.服务端处理完请求后,返回给客户端的不是reply,而是callback请求

4.Duplex模式对Bindding有特殊的要求,它要求支持Duplex MEP(Message Exchange Pattern),如WSDualHttpBinding和NetTcpBinding
注意:在WCF预定义绑定类型中,WSDualHttpBinding和NetTcpBinding均提供了对双工通信的支持,但是两者在对双工通信的实现机制上却有本质的区别。WSDualHttpBinding是基于HTTP传输协议的;而HTTP协议本身是基于请求-回复的传输协议,基于HTTP的通道本质上都是单向的WSDualHttpBinding实际上创建了两个通道,一个用于客户端向服务端的通信,而另一个则用于服务端到客户端的通信,从而间接地提供了双工通信的实现。而NetTcpBinding完全基于支持双工通信的TCP协议。
支持回调的绑定有4种:WSDualHttpBinding、NetTcpBinding、NetNamedPipeBinding、NetPeerTcpBinding。我们这里用WSDualHttpBinding为例
在这里插入图片描述

//配置文件中的 binding 指定
<endpoint address=""  binding="wsDualHttpBinding" contract="WCFService_DualPlex.IUser"></endpoint>//服务端接口
using System.ServiceModel;namespace WCFService_DualPlex
{[ServiceContract(CallbackContract = typeof(IUserCallback))]public interface IUser{[OperationContract]string ShowName(string name);}public interface IUserCallback{[OperationContract(IsOneWay = true)]void PrintSomething(string str);}
}//服务端实现
using System.ServiceModel;namespace WCFService_DualPlex
{public class User : IUser{IUserCallback callback = null;public User(){//获取调用当前操作的客户端实例的通道。callback = OperationContext.Current.GetCallbackChannel<IUserCallback>();}public string ShowName(string name){//在服务器端定义字符串,调用客户端的方法向客户端打印string str = "服务器调用客户端...";callback.PrintSomething(str);//返回服务端方法return "WCF服务,显示名称:" + name;}}
}//客户端调用
using System;
using System.ServiceModel;
using WCFClient_DualPlex.WCFService_DualPlex;namespace WCFClient_DualPlex
{//实现服务端的回调接口public class CallbackHandler : IUserCallback{public void PrintSomething(string str){Console.WriteLine(str);}}class Program{static void Main(string[] args){InstanceContext instanceContext = new InstanceContext(new CallbackHandler());UserClient client = new UserClient(instanceContext);Console.WriteLine(DateTime.Now);string result = client.ShowName("xxxx");Console.WriteLine(result);Console.WriteLine(DateTime.Now);Console.ReadLine();}}
}

在这里插入图片描述
在这里插入图片描述
**

操作协定的属性:

**
**加粗样式
**
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

WCF 客户端调用服务几种情况

在这里插入图片描述
在这里插入图片描述
ChannelFactory
一个创建不同类型通道的工厂,客户端使用这些通道将消息发送到不同配置的服务终结点。
在这里插入图片描述
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Service;
using System.ServiceModel;
using System.ServiceModel.Channels;

namespace Client3
{
class Program
{
static void Main(string[] args)
{

        EndpointAddress address = new EndpointAddress("http://localhost:1234/UserInfo");WSHttpBinding binding = new WSHttpBinding();ChannelFactory<IUserInfo> factory = new ChannelFactory<IUserInfo>(binding,address);IUserInfo channel = factory.CreateChannel();User[] Users = channel.GetInfo(null);Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}", "ID", "Name", "Age", "Nationality");for (int i = 0; i < Users.Length; i++){Console.WriteLine("{0,-10}{1,-10}{2,-10}{3,-10}",Users[i].ID.ToString(),Users[i].Name.ToString(),Users[i].Age.ToString(),Users[i].Nationality.ToString());}((IChannel)channel).Close();factory.Close();Console.Read();}
}

}
在这里插入图片描述
WCF客户端----异 步—调用服务
有时我们需要长时间处理应用程序并得到返回结果,但又不想影响程序后面代码部分的执行,这时我们就需要考虑使用异步的方式来调用服务。注意这里的异步是完全针对客户端而言的,与WCF服务契约的方法是否异步无关,也就是在不改变操作契约的情况下,我们可以用同步或者异步的方式调用WCF服务。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
服务引用和生成代理类 异步的客户端均如下代码
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

数据协定概念

在这里插入图片描述
在这里插入图片描述
默认情况下,任何给定的 CLR 命名空间(采用 Clr.Namespace 格式)都会映射到“http://schemas.datacontract.org/2004/07/Clr.Namespace”命名空间。 若要重写此默认值,请对整个模块或程序集应用 ContractNamespaceAttribute 属性。 或者,若要控制每种类型的数据协定命名空间,请设置 DataContractAttribute 的 Namespace 属性。

在这里插入图片描述

在这里插入图片描述
**

数据协定等效性特点概述

**
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

KnownTypeAttribute 类概述

在数据到达接收终结点时,WCF 运行库尝试将数据反序列化为公共语言运行库 (CLR) 类型的实例。通过首先检查传入消息选择为反序列化而实例化的类型,以确定消息内容遵循的数据协定。然后反序列化引擎尝试查找实现与消息内容兼容的数据协定的 CLR 类型。反序列化引擎在此过程中允许的侯选类型集称为反序列化程序的“已知类型”集。
让反序列化引擎了解某个类型的一种方法是使用 KnownTypeAttribute。不能将属性应用于单个数据成员,只能将它应用于整个数据协定类型。将属性应用于可能为类或结构的“外部类型”。在其最基本的用法中,应用属性会将类型指定为“已知类型”。只要反序列化外部类型的对象或通过其成员引用的任何对象,这就会导致已知类型成为已知类型集的一部分。可以将多个 KnownTypeAttribute 属性应用于同一类型。
在这里插入图片描述

IUserInfo.cs代码如下:

Service:类库程序,WCF服务端程序。在服务协定接口IUserInfo.cs中定义数据协定类Person,再定义一个数据协定类User。User派生至Person,继承基类Person的构造方法,定义新的属性成员SayHello。定义操作协定GetInfo和GetInfoEx,两者返回类型都为Person。在UserInfo.cs中实现数据协定,在GetInfo中,我们返回Person对象类型,在GetInfoEx中我们返回派生类User类型。由于在GetInfoEx中我们需要传递派生类User类型,所以要在基类数据协定Person上面加上KnownType(typeof(User))特性标记,这样User就能够服务端进行反序列化,供客户端使用。

using System.ServiceModel;using System.Runtime.Serialization;using System;namespace Service{   [ServiceContract]    public interface IUserInfo   {       [OperationContract]   Person GetInfo(int id,string name);[OperationContract]       Person GetInfoEx(int id, string name);    }[DataContract]   [KnownType(typeof(User))]   public class Person   {       [DataMember]     public int ID { get; set; }[DataMember]     public string Name { get; set; }public Person(int id, string name)    {           this.ID = id;       this.Name = name;     }   }[DataContract]   public class User:Person   {       public User(int id, string name): base(id,name){}[DataMember]       public string SayHello   {          get { return "Hello:" + Name; }      set { throw new NotImplementedException(); }    }   }
}

UserInfo.cs代码如下:
using System;using System.Collections.Generic;
using System.Linq;using System.Text;
namespace Service{
public class UserInfo:IUserInfo
{
public Person GetInfo(int id, string name)
{
return new Person(id, name);
}
public Person GetInfoEx(int id, string name)
{
return new User(id, name);
}
}

WCF消息协定概述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

异常

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

WCF服务配置编辑器【可视化】
个可视化的配置界面(Microsoft Service Configuration Editor),极大的方便开发者进行服务配置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
点击文件菜单下的另存为选项保存文件,将配置文件内容复制到先前建好的Host工程下的App.config文件中,编译程序后,就可以运行寄宿服务了,到此我们就完成了一个服务程序配置任务。
在这里插入图片描述
在这里插入图片描述

WAS

在这里插入图片描述


http://www.ppmy.cn/news/796467.html

相关文章

MongoDB 类replace替换字符串指定内容

目录 需求介绍 技术分析 技术积累 1、replaceOne 语法 2、javascript语法 实战演示 1、查询满足条件的数据 2、在mongodb语法中融入javascript语法并执行 3、查看刚刚被修改的数据 需求介绍 根据业务发展&#xff0c;现在需要对已经存在的数据进行处理&#xff0c;需…

nginx负载均衡简单配置

准备三台虚拟机来做这个实验&#xff1a; PA 负载均衡服务器 www.mydomain.com PA1 192.168.2.3 web服务器 PA2 192.168.2.4 web服务器 首先三台电脑预装nginx软件&#xff1a; 1、导入外部软件库 rpm -Uvh http://dl.iuscommunity.org/pub/ius/stabl…

使用promise函数封装post请求,封装aes加解密方法,并进行请求头aes加密,封装sm2国密加解密,进行请求体数据加密,响应数据解密。

export default {async post(url, params { header:{}, data:{} }, showLoading true){if(showLoading){uni.showLoading({title:"加载中",mask:true})}let options{header:{...params.header},url:globalParams.basepathurl.url,data:{...params.data}}//渠道 ae…

spark k8s Scheduler(Apache YuniKorn and Volcano)杂谈

其实关于Spark on k8s笔者很早就接触了&#xff0c;而且也进行过实战,而且也改造分析过&#xff0c; 比如spark on k8s 与 spark on k8s operator的对比这里进行了比对 kubernetes(k8s) scheduler backend 调度的实现和KubernetesClientException: too old resource version 原…

干货-卷起来,企业级web自动化测试实战落地(二)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 WebDriver的基本使…

leetcode739 每日温度 单调栈+数组下标

https://leetcode.cn/problems/daily-temperatures/给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于第 i 天&#xff0c;下一个更高温度出现在几天后。如果气温在这之后都不会升高&#xff0c;…

word-break:break-word、word-break:break-all和word-wrap:break-word 自动换行

文章目录 1&#xff0c;word-break:break-all2&#xff0c;word-wrap:break-word3&#xff0c;word-break;break-all word-break&#xff1a;break-all和word-wrap&#xff1a;break-word的都是使容器自动换行 它们的区别就在于&#xff1a; 1&#xff0c;word-break:break-all…

word 操作

一 Word 快捷键 作用快捷键大小写切换ShiftF3应用标题一的样式CtrlShift1手动换行&#xff08;例如标题太长分为两行&#xff09;ShiftEnter刷新域&#xff08;用于题注图片位置交换之后使用&#xff09;全选之后 按F9 二 论文 I 页面设置 页面设置主要功能 1 设置正文和页面…