本人在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. SpringMVC框架应用

    SSMSpringMVC框架 1.    MVC设计模式:模型.视图.控制器: 视图:负责格式化数据并把他们呈现给用户,包括数据展示.用户交互.数据验证.界面设计等功能.对应组件:JSP或者HTML ...

  2. (转)json格式转换成javaBean对象的方法

    把json格式转换成javaBean才可以.于是查了一下资料,网上最多的资料就是下面的这种方式: Java code? 1 2 3 4 5 6 7 8 9 String str = "[{\ ...

  3. 初识Docker:BusyBox容器后台运行失败

    1.问题描述:我在进行Docker网络实验时,使用docker  run  -d  busybox命令时,busybox无法保持后台长期运行. ============================ ...

  4. Perl unless

    在perl的if控制结构中,只有当条件表达式为真时才执行某块代码.如果想让程序块在条件为假时才执行,此时可以把if改成unless 例如: unless ($fred =~ /^([A-Z_]\w*$ ...

  5. php提供下载服务实例

    两个步骤:1,通过header头信息告诉浏览器,我给你回应的是一个附件请接收 2,通过php读取下载的文件的内容并返回 前端 <!DOCTYPE html> <html lang=& ...

  6. IntelliJ IDEA 2017.3尚硅谷-----设置超过指定 import 个数,改为*

    (可忽略)

  7. opencv:图像梯度

    常见的图像梯度算子: 一阶导数算子: #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; ...

  8. Python 多任务(线程) day1

    多任务就是可以让一台电脑同时执行多个命令. 以前的单核cpu是怎么做到同时执行多个命令的?(时间片轮转) ——其实以前的单核CPU是让操作系统交替执行命令,每个任务执行0.01秒,这样看起来就像是在同 ...

  9. 消息队列(七)--- RocketMQ延时发送和消息重试(半原创)

    本文图片和部分总结来自于参考资料,半原创,侵删 问题 Rocketmq 重试是否有超时问题,假如超时了如何解决,是重新发送消息呢?还是一直等待 假如某个 msg 进入了重试队列(%RETRY_XXX% ...

  10. Docker - 创建第一个 docker 实例

    1. 概述 安装完准备开始使用 2. 环境 os centos 7 docker docker - ce 19.03 3. 步骤 启动docker > systemctl start docke ...