本人在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. selenium自动化之加载浏览器配置文件

    化环境:python3.6 + selenium3 当我们做自动化的时候,如果不做任何配置的话打开的浏览器默认是不加载我们的浏览器配置文件的,下面我们来说说如何加载配置文件: 首先不管使用的是火狐浏览 ...

  2. AtCoder Beginner Contest 144

    https://atcoder.jp/contests/abc144/tasks/abc144_c #include<bits/stdc++.h> using namespace std; ...

  3. rancher2中文文档地址

    rancher2中文文档地址 待办 https://docs.rancher.cn/

  4. 浅谈Power Signoff

    Power Analysis是芯片设计实现中极重要的一环,因为它直接关系到芯片的性能和可靠性.Power Analysis 需要Timing Analysis 产生包含频率.transition 等时 ...

  5. DataTable、DataRow、DataColumn用法

    转载csdner 发布于2018-08-17 17:03:30 阅读数 4375  收藏   DataSet 表示数据在内存中的缓存. 属性 Tables  获取包含在 DataSet 中的表的集合. ...

  6. layuiAdmin pro v1.x 【单页版】开发者文档

    layuiAdmin std v1.x [iframe版]开发者文档 题外 该文档适用于 layuiAdmin 专业版(单页面),阅读之前请务必确认是否与你使用的版本对应. 熟练掌握 layuiAdm ...

  7. PHP基础学习笔记3

    一.检索表单信息 PHP 中的 $_GET 和 $_POST 变量用于检索表单中的信息,比如用户输入 提交的表单: <form action="welcome.php" me ...

  8. oracle imp exp 导入导出

    一.exp导出 exp myuser/mypwd@orcl file=D:\sql-bak\myuser.dmp log=D:\sql-bak\myuser.log exp 用户/密码@实例名 fil ...

  9. java爬虫出现java.lang.IllegalArgumentException: Illegal character in path at index 31

    url地址中出现了空格,使用trim()函数去除空格就好了

  10. 【WPF学习】第十四章 事件路由

    由上一章可知,WPF中的许多控件都是内容控件,而内容控件可包含任何类型以及大量的嵌套内容.例如,可构建包含图形的按钮,创建混合了文本和图片内容的标签,或者为了实现滚动或折叠的显示效果而在特定容器中放置 ...