我们希望WCF客户端调用采用透明代理方式,不用添加服务引用,也不用Invoke的方式,通过ChannelFactory<>动态产生通道,实现服务接口进行调用,并且支持async/await,当然也不用在Config中配置serviceModel。

服务端代码:

[ServiceContract]
public interface IGameService
{[OperationContract]Task DoWorkAsync(string arg);[OperationContract]void DoWork(string arg);
}public class GameService : IGameService
{public async Task<string> DoWorkAsync(string arg){return await Task.FromResult($"Hello {arg}, I am the GameService.");}public string DoWork(string arg){return $"Hello {arg}, I am the GameService.";}
}[ServiceContract]
public interface IPlayerService
{[OperationContract]Task<string> DoWorkAsync(string arg);[OperationContract]string DoWork(string arg);
}public class PlayerService : IPlayerService
{public async Task<string> DoWorkAsync(string arg){return await Task.FromResult($"Hello {arg}, I am the PlayerService.");}public async string DoWork(string arg){return $"Hello {arg}, I am the PlayerService.";}
}

代理类

动态创建服务对象,ChannelFactory<T>的运用,一个抽象类

namespace Wettery.Infrastructure.Wcf
{public enum WcfBindingType{BasicHttpBinding,NetNamedPipeBinding,NetPeerTcpBinding,NetTcpBinding,WebHttpBinding,WSDualHttpBinding,WSFederationHttpBinding,WSHttpBinding}public abstract class WcfChannelClient<TChannel> : IDisposable{public abstract string ServiceUrl { get; }private Binding _binding;public virtual Binding Binding{get{if (_binding == null)_binding = CreateBinding(WcfBindingType.NetTcpBinding);return _binding;}}protected TChannel _channel;public TChannel Channel{get { return _channel; }}protected IClientChannel ClientChannel{get { return (IClientChannel)_channel; }}public WcfChannelClient(){if (string.IsNullOrEmpty(this.ServiceUrl)) throw new NotSupportedException("ServiceUrl is not overridden by derived classes.");var chanFactory = new ChannelFactory<TChannel>(this.Binding, this.ServiceUrl);_channel = chanFactory.CreateChannel();this.ClientChannel.Open();}protected virtual void Dispose(bool disposing){if (disposing && this.ClientChannel != null){try{this.ClientChannel.Close(TimeSpan.FromSeconds(2));}catch{this.ClientChannel.Abort();}}//TODO: free unmanaged resources
        }public void Dispose(){Dispose(true);GC.SuppressFinalize(this);}~WcfChannelClient(){Dispose(false);}private static Binding CreateBinding(WcfBindingType binding){Binding bindinginstance = null;if (binding == WcfBindingType.BasicHttpBinding){BasicHttpBinding ws = new BasicHttpBinding();ws.MaxBufferSize = 2147483647;ws.MaxBufferPoolSize = 2147483647;ws.MaxReceivedMessageSize = 2147483647;ws.ReaderQuotas.MaxStringContentLength = 2147483647;ws.CloseTimeout = new TimeSpan(0, 10, 0);ws.OpenTimeout = new TimeSpan(0, 10, 0);ws.ReceiveTimeout = new TimeSpan(0, 10, 0);ws.SendTimeout = new TimeSpan(0, 10, 0);bindinginstance = ws;}else if (binding == WcfBindingType.NetNamedPipeBinding){NetNamedPipeBinding ws = new NetNamedPipeBinding();ws.MaxReceivedMessageSize = 65535000;bindinginstance = ws;}else if (binding == WcfBindingType.NetPeerTcpBinding){//NetPeerTcpBinding ws = new NetPeerTcpBinding();//ws.MaxReceivedMessageSize = 65535000;//bindinginstance = ws;throw new NotImplementedException();}else if (binding == WcfBindingType.NetTcpBinding){NetTcpBinding ws = new NetTcpBinding();ws.MaxReceivedMessageSize = 65535000;ws.Security.Mode = SecurityMode.None;bindinginstance = ws;}else if (binding == WcfBindingType.WebHttpBinding){WebHttpBinding ws = new WebHttpBinding(); //Restful stylews.MaxReceivedMessageSize = 65535000;bindinginstance = ws;}else if (binding == WcfBindingType.WSDualHttpBinding){WSDualHttpBinding ws = new WSDualHttpBinding();ws.MaxReceivedMessageSize = 65535000;bindinginstance = ws;}else if (binding == WcfBindingType.WSFederationHttpBinding){WSFederationHttpBinding ws = new WSFederationHttpBinding();ws.MaxReceivedMessageSize = 65535000;bindinginstance = ws;}else if (binding == WcfBindingType.WSHttpBinding){WSHttpBinding ws = new WSHttpBinding(SecurityMode.None);ws.MaxReceivedMessageSize = 65535000;ws.Security.Message.ClientCredentialType = MessageCredentialType.Windows;ws.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;bindinginstance = ws;}return bindinginstance;}        }
}

View Code

针对每个WCF服务派生一个代理类,在其中重写ServiceUrl与Binding,ServiceUrl可以配置到Config中,Binding不重写默认采用NetTcpBinding

public class GameServiceClient : WcfChannelClient<IGameService>{public override string ServiceUrl{get{return "net.tcp://localhost:21336/GameService.svc";}}}public class PlayerServiceClient : WcfChannelClient<IPlayerService>{public override string ServiceUrl{get{return "net.tcp://localhost:21336/PlayerService.svc";}}}

客户端调用

using (var client = new GameServiceClient())
{client.Channel.DoWork("thinkpig");  //无返回值await client.Channel.DoWorkAsync("thinkpig");  //无返回值异步
}using (var client = new PlayerServiceClient())
{var result = client.Channel.DoWork("thinkdog");  //有返回值result = await client.Channel.DoWorkAsync("thinkdog");  //有返回值异步
}

关于WCF寄宿主机可以参考前两篇文章

WCF绑定netTcpBinding寄宿到控制台应用程序

WCF绑定netTcpBinding寄宿到IIS

转载于:https://www.cnblogs.com/felixnet/p/wcf_client_transparent_proxy_channelfactory.html

WCF透明代理类,动态调用,支持async/await相关推荐

  1. 【Rust日报】 2019-08-12:Tokio alpha 版发布,新版本支持async/await

    Tokio alpha 版发布 #tokio 新版本支持async/await tokio = "=0.2.0-alpha.1" #![feature(async_await)]u ...

  2. WCF 服务端+客户端动态调用

    最近在写WCF服务相关代码,把项目中用到的通讯框架做了下整理,以备以后自己记忆. WCF服务端: 包含契约定义:WCF.Contract.契约实现:WCF.Service 以及宿主主程序:WcfSer ...

  3. Python 3.5将支持Async/Await异步编程

    根据Python增强提案(PEP) 第0492号, Python 3.5将通过async和await语法增加对协程的支持.该提案目的是使协程成为Python语言的原生特性,并"建立一种普遍. ...

  4. Java什么时候提高境界支持async/await写法啊?

    2019独角兽企业重金招聘Python工程师标准>>> 异步编程的最高境界,就是根本不用关心它是不是异步 .NET的async/await方式最先达到了这个境界. 和async/aw ...

  5. 动态代理最全详解系列[2]-Proxy生成代理类对象源码分析

      之前我们通过JDK中的Proxy实现了动态代理,Proxy用起来是比较简便的,但理解起来不是那么清晰,是因为我们并没有看见代理类是怎么生成的,代理类怎么调用的被代理类方法,所以下面我们进入源码看一 ...

  6. 2.在某应用软件中需要记录业务方法的调用日志,在不修改现有业务类的基础上为每一个类提供一个日志记录代理类,在代理类中输出日志,例如在业务方法 method() 调用之前输出“方法 method() 被

    2.在某应用软件中需要记录业务方法的调用日志,在不修改现有业务类的基础上为每一个类提供一个日志记录代理类,在代理类中输出日志,例如在业务方法 method() 调用之前输出"方法 metho ...

  7. 动态调用WCF服务[转]

    原文地址:http://blog.csdn.net/castlooo/archive/2010/05/06/5562619.aspx 客户端调用wcf ,有时需要动态的调用服务端的WCF中的方法,本方 ...

  8. C#动态调用web服务 远程调用技术WebService

    一.课程介绍 一位伟大的讲师曾经说过一句话:事物存在即合理!意思就是说:任何存在的事物都有其存在的原因,存在的一切事物都可以找到其存在的理由,我们应当把焦点放在因果关联的本质上.所以在本次分享课开课之 ...

  9. Web Serveice服务代理类生成及编译

    一.生成代理类 对于web service服务和wcf的webservice服务,我们都可以通过一个代理类来调用. 怎么写那个代理类呢?通过一个工具生成即可!!微软为我们提供了一个wsdl.exe的W ...

最新文章

  1. java 调用webservice的各种方法总结
  2. JAVA面试题(27)
  3. II play with GG
  4. Windows Server 2012 R2 WSUS-6:配置计算机组和客户端目标
  5. Java生成javadoc
  6. 设置input标签禁用_Vue造轮子 | input组件
  7. html a标签去掉下划线_如何用HTML基本元素制作表格
  8. 【2016年第5期】位置大数据在车辆保险风险管理中的应用
  9. 主流区块链底链技术横评 hyperledger fabric、fisco bcos、chainmaker
  10. c++ ActiveX基础1:使用VS2010创建MFC ActiveX工程项目
  11. win10 游戏等应用打开时闪退解决方案
  12. 磅、号、ppi、dpi、字号和分辨率关系
  13. 前端实现视频录制功能
  14. VMware15.1安装苹果系统mac10.15.3(图解)
  15. Ubuntu 14.04 64 位安装 Google 的 TensorFlow
  16. 关于四川华图省考面试 1:1职位保护的承诺函
  17. 在国企的 Java 程序员是一种什么样的体验?让我来告诉你吧!
  18. springboot ruoyi
  19. [翻译] 在 Overleaf 中更改编辑器字体大小
  20. MongoDB 3.0 用户创建

热门文章

  1. ge linux安装apt_教你如何在 Linux 中使用 apt 命令
  2. web前端网页设计作业_如何学习网页前端设计培训?
  3. js基础代码大全_关于前端业务代码的一些见解
  4. python小白教程-面向小白的Python教程:入门篇(六)
  5. 安装2000数据库的时候挂起
  6. java流框架_Java中的IO框架流二
  7. php生成gif动态图片_PHP绘制GIF动态图片
  8. 数组元素替换_LeetCode基础算法题第183篇:一维数组的重新洗牌
  9. 系统学习机器学习之非参数方法
  10. axios上传图片到php报500,vue项目中使用axios上传图片等文件