WCF透明代理类,动态调用,支持async/await
来源:互联网 发布:村上作品推荐 知乎 编辑:程序博客网 时间:2024/05/22 15:14
原文地址:http://www.cnblogs.com/felixnet/p/wcf_client_transparent_proxy_channelfactory.html
我们希望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 style ws.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; } }}
针对每个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
阅读全文
0 0
- WCF透明代理类,动态调用,支持async/await
- WCF透明代理类,动态调用,支持async-awai
- 使nodejs服务端支持async/await语法
- Task类与async/await
- silverlight学习之路(2)异步编程趋于同步 利用async和await调用wcf服务
- C# 调用wcf代理类
- await-async
- async await
- async/await
- async&await
- Async/Await
- async/await
- async/await
- async/await
- async/await
- async/await
- async/await
- async/await
- 仿百度页面(html+css)
- Intel82599网卡TCP/IP与FSDK对比测试
- sublime插件
- 【JZOJ5347】遥远的金字塔
- 使用JAVA读写Properties属性文件
- WCF透明代理类,动态调用,支持async/await
- java实现多线程的方法
- Centos6与Centos7防火墙设置与端口开放的方法
- 260. Single Number III
- 【JZOJ 5260】 区间第k小
- .NET Framework 的容器
- 华为硬件通用类笔试总结
- Python连接数据库
- InnoDB存储引擎