概述

WCF:Windows Communication Foundation ,Windows通信基础。

SOP:Service Orientation Architechture,面向服务的架构。

WebService是以BasicHttpBing方式运行的WCF。

方案结构:

1、创建解决方案WCFService

依次添加四个项目,如上图,Client和Hosting为控制台应用程序,Service和Service.Interface均为类库。

2、引用关系

Service.Interface:定义服务契约(Service Contract)接口,引用WCF核心库System.ServiceModel.dll;

Service:定义服务的项目,由于需要实现具体的服务,而服务契约在Service.Interface中,所以要引用Service.Interface项目;

Hosting:服务宿主的控制台程序,需要引用Service.Interface和Service项目,同时还要引用System.ServiceModel.dll类库:

Client:一个控制台应用程序的客户端,需要引用Service.ServiceModel类库。

一、Contracts协定:

一个类库项目,定义服务契约。

服务契约抽象了服务的所有操作,一般契约为接口形式存在。

//服务协定
[ServiceContract(Name = "ICalculator", Namespace = "http://SampleWcfTest")] //webservice描述文件用的portType命名空间
//CallbackContract =typeof(ICallBack),//双工时的返回协定
//ConfigurationName = "Calculator",//配置文件重的服务名
//ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign,//保护等级
//SessionMode = SessionMode.Allowed//设置会话的支持模式
public interface ICalculator
{
//操作协定
[OperationContract]
double Add(double n1, double n2);
}

二、Services服务:

一个类库项目,提供对契约的实现。

public class Calculator : ICalculator
{
public double Add(double n1, double n2)
{
double result = n1 + n2;
Console.WriteLine("Received Add({0},{1})", n1, n2);
// Code added to write output to the console window.
Console.WriteLine("Return: {0}", result);
return result;
}
}

VS的“WCF服务库项目”自动生成了svc文件和对应的svc.cs文件以及App.config文件,运行此项目,会自动启动“WCF服务主机”和“WCF测试客户端”窗口

三、ServiceHost自我服务宿主:

一个控制台项目,通过自我寄宿的方式作为Sevice项目服务的宿主。寄宿进程为ServiceHost1.exe。
服务寄宿的目的是开启一个进程,为WCF服务提供一个运行环境,并为服务添加一个或者多个终结点,然后暴漏给服务消费者。

WCF服务需要一个运行着的宿主进程,服务寄宿就是给服务指定一个宿主的过程。、

终结点(EndPoint)

WCF采用基于终结点(EndPoint)的通信手段。终结点有地址(Address),绑定(Binding)和契约(Contract)三部分组成,三要素也可以记作:EndPoint=ABC。

一个终结点包含了通信所必须的所有信息,具体如下:

  • Address:地址决定了服务的位置,解决了寻址的问题;
  • Binding:绑定实现了通信的所有细节,包括网络传输,消息编码,以及其他为实现某种功能(比如传输安全,可靠消息传输,事务等)对消息进行的相应处理。
    WCF中具有一系列的系统定义绑定,比如BasicHttpBinding,WSHttpBinding和NetTcpBinding,WSHttpBinding、NetMsmqBindiing等;
  • Contract:契约是对服务操作的抽象,也是对消息交换模式以及消息结构的定义。

1、编码方式:

//承载服务的宿主
using (ServiceHost selfHost = new ServiceHost(typeof(Calculator)))
{
try
{ //添加服务终结点
selfHost.AddServiceEndpoint(typeof(ICalculator), new WSHttpBinding(), new Uri("http://localhost:8000/GettingStarted/"));
        //添加服务元数据行为
        if (selfHost.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
{
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.HttpGetUrl = new Uri("http://localhost:8000/GettingStarted/metadata")
selfHost.Description.Behaviors.Add(smb);
}
selfHost.Open();
Console.WriteLine("The service is ready.");
Console.WriteLine("input<exit> to terminate service.");
Console.WriteLine();
while ("exit" == Console.ReadLine())
{
selfHost.Close();
}
}
catch (CommunicationException ex)
{
Console.WriteLine(ex.Message);
selfHost.Abort();
}
}

2、配置文件方式:

打开Hosting项目中的app.config,添加以下代码即可。

可直接右键点击config文件选择“编辑WCF配置”菜单,或通过VS的“工具”菜单,选择“WCF Service配置编辑器”菜单编辑配置文件。

<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
    <services>  <!--服务-->
<service name="Service.CalculatorService" behaviorConfiguration="metadataBehavior">
<endpoint address="http://127.0.0.1:1111/GettingStarted" binding="wsHttpBinding" contract="Service.Interface.ICalculator"></endpoint>
</service>
</services>
<behaviors> <!--行为-->
<serviceBehaviors>
<behavior name="metadataBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:1111/GettingStarted/metadata"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>

Hosting代码修改如下:

using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
{
host.Opened += delegate
{
Console.Write("CalculatorService已经启动,按任意键终止服务");
};
host.Open();
Console.Read();
}

四、IIS宿主

一个Web应用程序,通过IIS寄宿的方式将服务寄宿于IIS中,

寄宿进程为w3wp.exe。WAS激活服务:Window Activation Services。

1、创建WCF服务文件:CalculatorService.svc:

<%@ ServiceHost Sevice=”GettingStarted.CalculatorService” %>

2、配置文件

与app.config相比,web.config无EndPointAddress?服务的地址为.svc所在的地址,默认的元数据为…../CalculatorService.svc?ws…

<system.serviceModel>
<services>
<service name="GettingStarted.CalculatorService" behaviorConfiguration="metadataBehavior" >
<endpoint address="CalculatorService" binding="wsHttpBinding" contract="Calculator"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="metadataBehavior" >
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>

五、实现Rest 风格的web服务

可以使用 WCF REST 编程模型。

默认WebHttpBinding。

在协定的实现方式上添加 WebGet或者WebInvoke属性

[OperationContract]
[WebInvoke(UriTemplate = "div?x={x}&y={y}")]
long Divide(long x, long y); [OperationContract]
[WebGet(UriTemplate = "hello?name={name}")]
string SayHello(string name);

举例2:

[ServiceContract]
public interface ITestService
{
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "Test1", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
string Test1(string userName, string password); [OperationContract]
[WebGet(UriTemplate = "Test/{id}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
string Test(string id);
}

六、使用预配置的主机类WebServiceHost

使用WebServiceHost类

Uri baseAddress = new Uri("http://localhost:8000/");
WebServiceHost svcHost = new WebServiceHost(typeof(CalcService), baseAddress);
try
{
svcHost.Open();
Console.WriteLine("Service is running");
Console.WriteLine("Press enter to quit...");
Console.ReadLine(); svcHost.Close();
}
catch (CommunicationException cex)
{
Console.WriteLine("An exception occurred: {0}", cex.Message);
svcHost.Abort();
}

3、调用:

http://…/div?x=1&y=2

七、client:一个客户端

1、使用VS“添加服务引用”生成的CalculatorServiceClient:

CalculatorServiceClient基类是System.ServiceModel.ClientBase,该基类封装了ChannelFactory<ICalculator>

using (CalculatorServiceClient proxy = new CalculatorServiceClient())
{
double result = proxy.Add(1, 2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);
}

2、不用添加服务引用,使用ChannelFactory方式:

//using (ChannelFactory channelFactory = new ChannelFactory<ICalculator>(new WSHttpBinding(), "http://127.0.0.1:1111/CalculatorService"))//构造函数中指定了终结点的ABC三要素,
using (ChannelFactory channelFactory = new ChannelFactory<ICalculator>("CalculatorService"))//通过配置文件来进行,对应的为config 文件中终结点的name
{
ICalculator proxy = channelFactory.CreateChannel();
using (proxy as IDisposale)
{
Console.WriteLine("x+y={2} when x={0} and y={1}", 1, 2, proxy.Add(1, 2));
}
}

配置文件:

<configuration>
<system.serviceModel>
<client>
<endpoint name="CalculatorService" address="http://127.0.0.1:1111/CalculatorService" binding="wsHttpBinding" contract="Service.Interface.ICalculator" />
</client>
</system.serviceModel>
</configuration>

八、绑定类型:

WCF中常用的binding方式:

1. 基于HTTP的绑定

BasicHttpBinding、WSHttpBinding、WSDualHttpBinding和WSFederationHttpBinding选项适合于通过XML Web服务协议提供契约类型。显然,如果需要使该服务可适用于更多场合(多种操作系统和多种编程语言),这些就是需要关注的绑定,因为所有这些绑定类型都基于XML表示编码数据并且使用HTTP传送数据。

在下面清单中,注意到可以在代码中表示WCF绑定(通过System.ServiceModel名称空间中的类类型),或者作为在*.config文件中定义的XML属性表示WCF绑定。

  1. BasicHttpBinding:用于绑定符合WS-Basic Profile(WS-I Basic Profile 1.1)的WCF服务。该绑定使用HTTP作为传送方式,并且使用Text/XML作为默认消息编码。用于兼容旧的Web ASMX 服务。
    BasicHttpBinding是所有以Web服务为中心的协议中最简单的协议。特别是,该绑定将确保WCF服务符合由WS-I定义的名为WS-I Basic Profile 1.1的规范。
  2. WSHttpBinding:类似于BasicHttpBinding,但是提供了更多的Web服务特性。该绑定添加对事务、可靠消息发送和WS-Addressing的支持。
    WSHttpBinding协议不仅集成了对WS-*规范(事务、安全性和可靠会话)子集的支持,而且支持使用消息传输优化机制(Message Transmission Optimization Mechanism,MTOM)处理二进制数据编码的能力。
  3. WSDualHttpBinding:类似于WSHttpBinding,但是用于与双向契约结合使用(例如,服务和客户可以来回发送消息)。该绑定只支持SOAP安全性,并且需要可靠的消息发送。
    WSDualHttpBinding的主要优点是它添加了允许调用者和发送方使用双向消息发送(duplex messaging)通信的能力,这是一种表示调用者和发送方可以参加双向会谈的流行方法。在选择WSDualHttpBinding时,可以与WCF发布/订阅事件模型建立关联。
  4. WSFederationHttpBinding:安全的和可互操作的绑定,该绑定支持WS-Federation协议,并且允许位于联盟内的组织有效地验证和授权用户
    WSFederationHttpBinding是基于Web服务的协议,在安全性最为重要时就需要使用该协议。该绑定支持WS-Trust、WS-Security和WS-SecureConversation规范,通过WCF CardSpace API表示这些规范。
  5. WebHttpBinding:用于通过HTTP(非SOAP)请求提供的服务队脚本客户端有用,如ASPNet AJAX。

2. 基于TCP的绑定

如果正在构建一个分布式系统,该系统涉及使用.NET 3.0/3.5库配置的一组连网机器(换句话说,所有机器都运行Windows XP、Windows Server 2003或Windows Vista),就可以通过绕开Web服务绑定并选择使用TCP绑定来增强性能,TCP绑定确保以紧凑二进制格式(而不是XML)编码所有数据。同样,在使用下表的的绑定时,客户和主机必须是.NET应用程序。

  1. NetNamedPipeBinding:用于相同机器上不同.NET应用程序之间通信的安全的、可靠的、优化的绑定。
    NetNamedPipeBinding支持事务、可靠的会话和安全的通信,但是它不能够执行跨机器的调用。如果您正在寻找在相同机器上的WCF应用程序之间推动数据(例如,跨越应用程序的域通信)的最快速方法,NetNamedPipeBinding绑定就是最佳的选择。
  2. NetPeerTcpBinding:为对等(P2P)网络应用程序提供安全的绑定。
    至于NetPeerTcpBinding,可查阅.NET Framework 3.5 SDK文档以了解关于P2P连网的细节。
  3. NetTcpBinding:适合于不同机器上.NET应用程序之间通信的安全的、优化的绑定。
    NetTcpBinding类使用TCP在客户和WCF服务之间移动二进制数据。前面提及,这将导致比Web服务协议更佳的性能,但是只限于内部应用程序解决方案。此外,NetTcpBinding支持事务、可靠的会话和安全的通信。

3. 基于MSMQ的绑定

  1. MsmqIntegrationBinding:该绑定可用于允许WCF应用程序向已有的MSMQ应用程序发送消息以及从这种应用程序接收消息,这种应用程序使用COM、本地C++或定义在System.Messaging名称空间中的类型
  2. NetMsmqBinding:这个排队的绑定适合于不同机器上的.NET应用程序之间的通信

注:二进制编码格式使用TCP、IPC、MSMQ可以获取最佳性能,但是它是以牺牲互操作性为代价,因为它只支持WCF到WCF的通信。

WCF Windows基础通信的更多相关文章

  1. Open Interface Service WCF三种通信模式

    WCF三种通信模式 一.请求响应模式: 概念:客户端发送请求,一直等待服务端响应,在此期间处于等待(假死)状态:直到服务器响应,才能继续执行其他的操作: 即使返回值是void 也属于请求与答复模式. ...

  2. 再次理解WCF以及其通信(附加一個編程小經驗)

    一.概述 Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分.由 .NE ...

  3. WCF Windows Service Using TopShelf and ServiceModelEx z

    http://lourenco.co.za/blog/2013/08/wcf-windows-service-using-topshelf-and-servicemodelex/ There are ...

  4. WCF - Windows Service Hosting

    WCF - Windows Service Hosting The operation of Windows service hosting is a simple one. Given below ...

  5. 关于WCF一些基础。

    关于WCF Windows Communication Foundation(WCF)是由微软发展的一组数据通信的应用程序开发接口,可以翻译为Windows通讯接口,它是.NET框架的一部分.由 .N ...

  6. Delphi一共封装(超类化)了8种Windows基础控件和17种复杂控件

    超类化源码: procedure TWinControl.CreateSubClass(var Params: TCreateParams; ControlClassName: PChar); con ...

  7. 为什么选择Netty作为基础通信框架?

    在开始之前,我先讲一个亲身经历的故事:曾经有两个项目组同时用到了NIO编程技术,一个项目组选择自己开发NIO服务端,直接使用JDK原生的API,结果两个多月过去了,他们的NIO服务端始终无法稳定,问题 ...

  8. windows 基础命令小集

    windows 基础命令小集 winver---------检查Windows版本wmimgmt.msc----打开windows管理体系结构(WMI)wupdmgr--------windows更新 ...

  9. 移动onenet基础通信套件V1.08版本的AT指令测试

    1. 本次测试版本V1.08,AT+MIPLCREATE,首先需要一个配置文件.该指令创建一个基础通信套件的实例 2. 看下CGFID=2的配置,这个连接类型,UDP是1还是0?用户名和密码是什么?哪 ...

随机推荐

  1. React native 放大点击区域 hitSlop属性的使用

    在日常的需求中,如上图的加减按钮,可能写ui布局的时候没考虑实际的这个点击范围太小,不利于真机上用户点击到,如果加包裹层加padding的话又会影响原先定好的布局,或者不利于对齐. 那么可以用  hi ...

  2. spring boot 2.x版本:java.lang.ClassNotFoundException: org.springframework.boot.bind.RelaxedDataBinder

    标题 ##搭建spring boot 2.0.3版本 使用alibaba的druid数据库连接池,com.github.pagehelper的分页插件,启动项目报错. 错误提示:java.lang.C ...

  3. win10系统ping另一台电脑上虚拟机的IP

    刚刚因为虚拟机与主机没法互相ping通的事情,奋战到将近凌晨一点.现在把这个过程总结一下,以方便后加入该行业的广大IT精英. VMWare提供了三种工作模式:bridged(桥接模式).NAT(网络地 ...

  4. mysql查看表结构命令,如下:

    desc 表名; show columns from 表名; describe 表名; show create table 表名;

  5. 关于spring中配置文件路径的那些事儿

    在项目中我们经常会需要读一些配置文件来获取配置信息,然而对于这些配置文件在项目中存放的位置以及获取这些配置文件的存放路径却经常搞不清楚,自己研究了一下,记录下来以备后用. 测试代码如下 package ...

  6. C#的@标志的使用情况—本篇blog采用Markdown编写

    @(C# 参考--出自官方文档入口) 1.使 C# 关键字用作标识符. @ 字符可作为代码元素的前缀,编译器将把此代码元素解释为标识符而非 C# 关键字. 下面的示例使用 @ 字符定义其在 for 循 ...

  7. vue elment table根据返回值修改样式

    今天在写vue项目的时候,查询出的数据库的数据想根据条件修改显示.查询资料有一个 :formatter,可以实现这个效果,废话不多说,这个是我的例子: <el-table-column prop ...

  8. Vue路由参数

    vue路由参数 1.参数router-link vue.prototype.xxx = {add:fn}`所有组件中,使用this.xxx就能拿到这个对象2.查询字符串 (1)配置: :to=&quo ...

  9. JavaScript--常用对象的属性及方法(1)

    1.Number对象(基本数据类型) Number对象的方法大多是一些强制转换方法,如果转换失败返回NaN,以下举例中用number来代替具体数字: *console.log在控制台输出(键盘F12可 ...

  10. 通过Nginx统计网站的PV、UV、IP

    转载:通过Nginx统计网站的PV.UV.IP 概念 UV:独立访客:以cookie为依据,假设一台电脑装有3个不同的浏览器,分别打开同一个页面,将会产生3个UV.PV:访问量:页面每访问或刷新一次, ...