勇哥注:
此系列文章是梳理一下勇哥认为项目有用的WCF的知识点,读者须有WCF的开发经验。
wcf的预定义绑定
(1)ws*开头的绑定 【用于跨语言互通】
webservice模式 【BasicHttpBinding, WsHttpBinding】
restful模式 【WebHttpBinding】
(2) net开头的绑定 【用于.net 程序之间的互通】
直边式的访问 【netTcpBinding, NetNamedPipedBinding】
断开时的访问 【netMSMQBinding】
(3) 绑定的性能
NetNamedPiped> netTcp > basic >WS
(4) 遗憾
wcf最大的遗憾是tcp模式不支持跨语言互通,google开源的thrift就支持了这种模式
这其中的原因是tcp模式的跨语言互通并没有ws标准,所以wcf也就不支持。
正是由于这个原因,wcf无法与java的tcp模式互通。
binding的选择见下图:
wcf的netMsMQBinding
消息队列是与windows绑定在一起的一个功能。
wcf可以用netMsMQBinding来跟它进行通讯。
一。使用队列的好处
1. 削峰
队列就是三峡,可以拦截上游的洪水
带来的好处是可以有效的避免底层系统被流量冲垮
2. 同步架构异步化【解耦】
上游与下游的依赖关系被拆解,上游不知道下游是谁。
下游也不知道上游是谁,大家都和三峡大坝发生关系
所以队列可以让系统模块化,有利用横向扩容
下图显示的是多个Client如果直连Service的话,会产生强耦合关系。
如果所有Client通过MSMQ访问Service,则Client和Service之间是解耦的关系。
3. 并发请求串行化【无锁模式】
即然是队列,也就是FIFO,先行先出,也就不存在锁存机制了。
4. 提高系统稳定性
下游死机挂掉,不影响上游业务,因为大家解耦了。
二。MSMQ是什么?
1. 它是一个windows自带的消息队列
2. 它是基于硬盘的
3. 基于单机的,无集群[高可用,可并发]
以上三点,就决定了比较low,属于[90年代的产品]
给人感觉,wcf还保留在2000年代的状态。
三。wcf模式下的消息队列
1. wcf目前只支持自家的MSMQ, 没有开发对接第三方的消息队列组件
第三方的有:ActiveMQ, ZeroMQ, Kafka, Redis
唯一一个由RabbitMQ,有WCF Binding也放弃更新了
如果是企业网的需求,可以适当使用
2. 这种90年代的单机硬盘化的MSMQ,现实场景比较小,小系统可以接受。
netMsMQBinding 必须要是 操作契约为 IsOneWay模式
3. 在线模式, 离线模式
一个Message是4M的限制,超出则队列塞不进去,wcf也不报错。
MQ的思想,在互联网开发中特别重要。
如果想了解集群式消息队列,可以参考RabbitMQ,它可以应对互联网开发的许多应用场景。
四。代码实现
1。新建专用队列
注意勾选“事务性”
创建完后如下图所示:
2。设置host的app.config
主要几点:
address="net.msmq://localhost/private/ctrip"
注意地址的写法
<security mode="None"/>
安全必须关闭
binding="netMsmqBinding"
注意绑定类型
<system.serviceModel> <bindings> <netMsmqBinding> <binding name="mymsmq"> <security mode="None"/> </binding> </netMsmqBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="metadataBehavior"> <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:9999/calculatorservice/metadata" /> </behavior> </serviceBehaviors> </behaviors> <services> <service behaviorConfiguration="metadataBehavior" name="Services.CalculatorService"> <!--<endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding" contract="Contracts.ICalculator" />--> <endpoint address="net.msmq://localhost/private/ctrip" bindingConfiguration="mymsmq" binding="netMsmqBinding" contract="Contracts.ICalculator"/> </service> </services> </system.serviceModel>
3。启动,会报错
原因是netMsMQBinding 要求操作契约是IsOneWay模式。
修改如下:
[OperationContract(IsOneWay =true)] void DoWorker(string msg);
4。再次启动,会报错
见到这个错误,说明host和Client端的app.config还是有问题。
在默认的情况下,netMsmqBinding 的msmqAuthenticationMode为WindowsDomain,由于基于WindowsDomain必须安装AD,
利于在本机模拟,我把msmqAuthenticationMode改为None,相应的ProtectionLevel和clientCredentialType改为None。
所以把两边的app.config都要改一下:
<bindings> <netMsmqBinding> <binding name="mymsmq"> <security> <transport msmqAuthenticationMode ="None" msmqProtectionLevel ="None"/> <message clientCredentialType ="None"/> </security> </binding> </netMsmqBinding> </bindings>
5。现在没报错,并且结果是正确的。
这个过程是在线方式。
消息队列还支持离线方式。
我们只启动Client,不启动Host。
static void Main(string[] args) { //Thread.Sleep(2000); using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("calculatorservice")) { //省略代码 ICalculator proxy = channelFactory.CreateChannel(); using (proxy as IDisposable) { //Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2)); //Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2)); //Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2)); //Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2)); for(int i = 0; i < 1000; i++) { proxy.DoWorker("hello world"); } proxy.DoWorker("hello world"); Console.ReadKey(); } } }
然后选择专用队列,点击刷新按钮,可以看到消息数量为1001条。
然后我们启动Host端。这时候就把所有消息给消费了。
再看专用队列的消息数量:
代码下载:
链接:https://pan.baidu.com/s/1Wg5cFdYzmNYqmhyW6BqNxw
提取码:4h01
--来自百度网盘超级会员V6勇哥的分享
WCF的Rest服务
Restful [webHttpBinding]
1. 本质
(1)用URL定位唯一的资源 ,例如http://www.baidu.com
(2) 用Http动态描述对该资源的操作 (CURD)
get: 从baidu.com获取数据
post: 向baidu.com提交数据
put: modify
delete: delete
2. 背景
移动互联网时代,出现安卓,ios,等系统,
restful基于json,通讯效率高,可以实现跨平台互通
3。 restful相比soap和传统模式,有什么不同,解决了什么问题?
以student表的修改为例:
传统的http模式:【mvc】
http://localhost:80/Student/Get/1
http://localhost:80/Student/Add
http://localhost:80/Student/Modify
http://localhost:80/Student/Delete
而使用restful模式后:
http://localhost:80/Student/1 [get]
http://localhost:80/Student [post]
http://localhost:80/Student [put]
http://localhost:80/Student [delete]
区别就是url中不出现任何动词
除了get,其它类型的url保证一致
restful的标准就是在url中不可能出现动词
4。 soap和restful的侧重点
soap更专注于企业内部网(erp, oa),更加关注安全,事物等细节,由于内部网,对网强性能与网络带宽不关心
restful 更加关注于internet上的网络传输,所以比soap更节省带宽
5。 评价
由于wcf的restful像是为了响应移动应用的潮流的补丁。
后面就推出了webapi,对restful提供更好的支持。

