本人在2013年就做过一个WCF的项目,但最近又开始看相关的文章,才发现当年的认识实在太浅显,这里我把WCF的几个重要知识点总结以下。  

  ABC概念

  WCF服务的构成如下图

  如你所见,Host即为宿主,因为WCF不能自运行,所以需要依附于宿主,通常可以是Windows程序(Winform/wpf/控制台等.net应用均可)、IIS、Windows服务。

  Endpoint

    Endpoint是WCF实现通信的核心要素。一个WCF Service由一个Endpoint集合组成,每个Endpoint就是用于通信的入口,客户端和服务端通过Endpoint交换信息。
    Endpoint由三部分组成:Address,Binding,Contract。
  Address

    Address通过一个URI唯一地标识一个Endpoint,并告诉潜在的WCF service的调用者如何找到这个Endpoint。

  Binding

    Binding实现在Client和Service通信的所有底层细节。比如Client与Service之间传递的Message是如何编码的—— text/XML, binary,MTOM;这种Message的传递是采用的哪种Transport——TCP,
Http, Named Pipe, MSMQ; 以及采用怎样的机制解决Secure
Messaging的问题——SSL,Message Level Security。

  Contract

    Contract的主要的作用是定义通信协议,具体Service提供了哪些方法。

  WCF一些容易被忽略的特性

跨平台

Wcf服务可以被javascript调用,首先需要对WCF配置文件进行一些配置

<behavior name="ajaxServiceBehavior">
<enableWebScript/>
</behavior>

  有时还需要给锲约接口添加特性

    [WebInvoke(Method = "GET",ResponseFormat = WebMessageFormat.Json)]

  调用方法有多种,下面一一介绍。

  第一种与调用webservice类似,经过了数天的验证该方法未生效,如果有大神实现该方式希望能赐教,但理论上该方法可行。

 function myFunction() {
var URL = "http://192.168.209.117/UserService.asmx/GetUser";
var Params = "name=leftfist&age=28";//传给WCF的参数
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.Open("POST",URL, false);//用POST方法,此处可改为GET方法
xmlhttp.SetRequestHeader("Content-Type","application/x-www-form-urlencoded");
xmlhttp.SetRequestHeader ("Content-Length",Params.length);
xmlhttp.send(Params);
var result = xmlhttp.status;
//OK
if (result == 200) {
document.write(xmlhttp.responseText);
}
xmlhttp = null;
}

  第二种方法与C#调用WCF服务类似,先添加服务引用

  

  <asp:ScriptManager ID="ScriptManager" runat="server">
<Services>
<asp:ServiceReference Path="http://192.168.6.47:8080/HelloService.svc" />
</Services>
</asp:ScriptManager>

  在调用函数中用以下方法即可进行调用,

  var wcfProxy = new Valsun.Service1();
wcfProxy.GetTestList(id, OnSucceededCallback, OnFailedCallback);

  第三种方法是Ajax

 $.ajax
(
{
type: 'GET',
url: 'Services/RestTestService.svc/GetTest',
dataType: 'json',
data: 'a=a&b=b',
success: function (response, type, xhr)
{
window.alert('A: ' + response.A);
},
error: function (xhr)
{
window.alert('error: ' + xhr.statusText);
}
}
);

  分布式事务  

  WCF服务的执行可添加事务,也可进行服务传递,通过在方法上添加属性TransactionScopeRequired可实现对该方法启动事务,例如

  

 [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public bool Add(Model.User user, Model.Shop shop)
{
int shopID;
int UserID; if (Add(user, out UserID)) //数据库插入方法1
{
shop.UserID = UserID; return Add(shop, out shopID); //数据库插入方法2
} return false;
}

  在上述方法中,只有代码正确执行到return,方法1和方法2的结果才能正确提交,否则将会回滚。

  如果在配置文件中添加以下代码,还能实现客户端事务到服务端的传递,

<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1" transactionFlow="true" />
</wsHttpBinding>
</bindings>

  并在WCF服务方法上添加

    [TransactionFlow(TransactionFlowOption.Allowed)]

  如果在客户端将服务的调用放在一个事务里,如下所示

 using (TransactionScope ts = new TransactionScope())
{
//调用服务
using (TestService.Service1Client service = new TestService.Service1Client())
{
service.AddData_1("");
}
Console.WriteLine("第一次调用:成功插入一条数据");   //重新去调用WCF服务
using (TestService.Service1Client service2 = new TestService.Service1Client())
{
   //WCF中的AddData_2会报错
  service2.AddData_2("");
}
ts.Complete();
}

  此时,如果在客户端的调用方法的事务中出现报错,服务端的方法AddData_1方法AddData_2 即使已执行也会回滚。

  消息队列

  MSMQ的实现原理是:消息的发送者把自己想要发送的信息放入一个容器,然后把它保存到一个系统公用空间的消息队列中,本地或异地的消息接收程序再从该队列中取出发给它的消息进行处理。

  MSMQ中主要有两个概念

  • 一个是消息Message:Message是通信双方需要传递的消息,它可以是文本、图片、视频等。消息包含发送和接收者的标识,只有指定的用户才能取得消息。
  • 一个是队列Queue:用来保存消息的存储空间。

  消息队列的优缺点

  • 采用消息队列的好处是:由于是异步通信,无论是发送方还是接收方都不同等待对方返回成功消息,就可以执行余下的代码,大大提高了处理的能力;在信息传递过程中,具有故障恢复能力;MSMQ的消息传递机制使得通信的双方具有不同的物理平台成为可能。
  • 消息队列缺点是:不适合Client需要Server端实时交互情况,大量请求时候,响应可能延迟。对于客户端,必须是Windows系统。可以通过连接器跟其他的非微软技术集成。

  

  首先呢得先在服务器新建一个msmq队列

MessageQueue.Create(@".\Private$\LMXQueue ")

  部署服务时需指定消息队列

using (ServiceHost host =new ServiceHost(typeof(MSMQOrderService),
new Uri("net.msmq://localhost/Private/LMXQueue")))
{ NetMsmqBinding binding = new NetMsmqBinding(NetMsmqSecurityMode.None);
binding.ExactlyOnce = false;
binding.Durable = true; host.AddServiceEndpoint(
typeof(IMSMQService).FullName,
binding,
""); host.Open();
Console.Read(); }

  在客户端调用时也需指定队列

NetMsmqBinding binding = new NetMsmqBinding(NetMsmqSecurityMode.None);
binding.ExactlyOnce = false;
binding.Durable = true; ChannelFactory<IMSMQService> channel =
new ChannelFactory<IMSMQService>(
//这里面解释一下:localhost代表是本机服务器,Private字面上是私有,这里面表示是“消息队列”里面的“专用队列”,“LMXQueue”是我们专用队列的一个类似“消息组”的一个名称。
binding, new EndpointAddress("net.msmq://localhost/Private/LMXQueue")); IMSMQService client =
channel.CreateChannel();

  至此有关WCF的一些容易遗漏的重要知识点就介绍完毕了,希望对大家有帮助。

  

WCF技术归纳的更多相关文章

  1. 利用WCF技术降低系统之间的耦合度

    为了降低本系统各个组件之间的耦合度,本系统将BLL层采用WCF技术发布为Web Service,以供UI层调用. 前面我们已经介绍过,为什么UI层不直接调用BLL层,而是要经过UI->Servi ...

  2. WCF技术的不同应用场景及其实现分析

    这一篇文章,是总结一下WCF技术,以及基于这个技术发展出来的几个典型应用场景,并且我将尝试对这些不同的WCF实现的原理进行一些比较分析. 关于WCF这个技术的基本概念,如果你不是很清楚,可以参考一下有 ...

  3. WCF技术剖析之三十:一个很有用的WCF调用编程技巧[下篇]

    原文:WCF技术剖析之三十:一个很有用的WCF调用编程技巧[下篇] 在<上篇>中,我通过使用Delegate的方式解决了服务调用过程中的异常处理以及对服务代理的关闭.对于<WCF技术 ...

  4. WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇]

    原文:WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇] 在进行基于会话信道的WCF服务调用中,由于受到并发信道数量的限制,我们需要及时的关闭信道:当遇到某些异常,我们需要强行中止(Abor ...

  5. WCF技术剖析之二十九:换种不同的方式调用WCF服务[提供源代码下载]

    原文:WCF技术剖析之二十九:换种不同的方式调用WCF服务[提供源代码下载] 我们有两种典型的WCF调用方式:通过SvcUtil.exe(或者添加Web引用)导入发布的服务元数据生成服务代理相关的代码 ...

  6. WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序)

    原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于HTTP-GET的实现](提供模拟程序) 基于HTTP-GET的元数据发布方式与基于WS-MEX原理类似,但是ServiceMetad ...

  7. WCF技术剖析之二十八:自己动手获取元数据[附源代码下载]

    原文:WCF技术剖析之二十八:自己动手获取元数据[附源代码下载] 元数据的发布方式决定了元数据的获取行为,WCF服务元数据架构体系通过ServiceMetadataBehavior实现了基于WS-ME ...

  8. WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于WS-MEX的实现](提供模拟程序)

    原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[基于WS-MEX的实现](提供模拟程序) 通过<如何将一个服务发布成WSDL[编程篇]>的介绍我们知道了如何可以通过编程或者配 ...

  9. WCF技术剖析之二十七: 如何将一个服务发布成WSDL[编程篇]

    原文:WCF技术剖析之二十七: 如何将一个服务发布成WSDL[编程篇] 对于WCF服务端元数据架构体系来说,通过MetadataExporter将服务的终结点导出成MetadataSet(参考< ...

随机推荐

  1. 结构struct 联合Union和枚举Enum的细节讨论

    联合(Union)是一种构造数据类型,它提供了一种使不同类型数据类型成员之间共享存储空间的方法,同时可以实现不同类型数据成员之间的自动类型转换.联合体对象在同一时间只能存储一个成员的值.联合的内存大小 ...

  2. docker跨主机链接

    三种方式 一,使用网桥实现跨主机容器连接

  3. Python入门2 —— 变量

    一:问号三连 1.什么是变量? 变 指的是事物的状态是可以发生变化的 量 指的是记录事物的状态 2.为什么要有变量? 为了让计算机像人一样去记录事物的状态 3.怎么用变量? 先定义 后引用 二:变量的 ...

  4. AcWing 792. 高精度减法

    https://www.acwing.com/problem/content/794/ #include<bits/stdc++.h> using namespace std; //判断是 ...

  5. [Netcat] 断线重连 自动重连

    今天想做些操作,所以想到了nc 但是nc太过于轻量级 所以 导致我没有找到他的断线重连功能 然后我就想到了windows的神器之一 vbs脚本 vbs代码如下 Dim a,b set a= WScri ...

  6. resize2fs: 报错

    报错如下 [root@localhost ~]# resize2fs /dev/mapper/centos-root resize2fs (-Dec-) resize2fs: Bad magic nu ...

  7. Makefile的编写及四个特殊符号的意义@、$@、$^、$

    https://www.cnblogs.com/sky-heaven/p/9450435.html Makefile一般的格式是: target:components rule 一.@ 这个符串通常用 ...

  8. python 递归调用 返回值问题

    当使用递归时并有返回值时,调用自身函数时需要加上return语句如下: def daxiao(biao1,biao2):     #判断两个列表的大小,根据里面的元素大小     #如果biao1大于 ...

  9. 最小树形图模板 UVA11183

    题意:给定n个节点m条边的有向带权图,求以0为根节点的最小树形图权值大小 用这个代码的时候要注意,这里的数据是从0开始的,边也是从0开始算, 所以在打主代码的时候,如果是从1开始,那么算法里面的从0开 ...

  10. wampserver 配置的几个坑(雾

    1. 从安装版本说起 自从我进入大学之后,便继承了学长那里的wampserver2.5版本 直到有一天自己下载wamp的时候才注意到已经有 3.0.6版本了 (现在有更高的了 但是3.0.6够用了) ...