WCF透明代理类,动态调用,支持async-awai
来源:互联网 发布:阿里通网络短信 编辑:程序博客网 时间:2024/06/08 11:06
我们希望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-awai
- WCF透明代理类,动态调用,支持async/await
- C# 调用wcf代理类
- Thrift 使用以及使用动态代理透明化调用
- 动态调用WCF地址 (使用ChannelFactory类)
- 动态调用WCF地址 (使用ChannelFactory类)
- 动态调用WCF的工具类库
- 动态调用WCF示例
- 动态调用WCF服务
- wcf 动态调用
- jdk动态代理支持
- wcf 生成代理类
- Wince 上动态调用Wcf
- 动态配置Silverlight调用WCF
- 使用ChannelFactory类实现动态调用WCF地址
- Silverlight 动态调用 WCF And WebService
- Silverlight动态调用WEBSERVICE,WCF方法
- 客户端动态调用WCF服务中的方法
- 容器索引
- Linux下安装tomcat
- TCP三次握手与四次挥手——上篇
- PowerDesigner 16.5详细安装图解与破解
- JavaScript常见字符串方法
- WCF透明代理类,动态调用,支持async-awai
- DPDK(二):系统要求
- CRC16校验算法实现
- Android Drawable简介
- CentOS 6.8 安装Tomcat7
- idea的使用-Tomcat配置
- 最为一个大学生的实训笔记(一)
- VC6.0中如何修改工程的名字
- Tinker热修复 及walle多渠道打包流程