WCF透明代理类,动态调用,支持async/await
我们希望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());
}
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 = ;
ws.MaxBufferPoolSize = ;
ws.MaxReceivedMessageSize = ;
ws.ReaderQuotas.MaxStringContentLength = ;
ws.CloseTimeout = new TimeSpan(, , );
ws.OpenTimeout = new TimeSpan(, , );
ws.ReceiveTimeout = new TimeSpan(, , );
ws.SendTimeout = new TimeSpan(, , );
bindinginstance = ws;
}
else if (binding == WcfBindingType.NetNamedPipeBinding)
{
NetNamedPipeBinding ws = new NetNamedPipeBinding();
ws.MaxReceivedMessageSize = ;
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 = ;
ws.Security.Mode = SecurityMode.None;
bindinginstance = ws;
}
else if (binding == WcfBindingType.WebHttpBinding)
{
WebHttpBinding ws = new WebHttpBinding(); //Restful style
ws.MaxReceivedMessageSize = ;
bindinginstance = ws;
}
else if (binding == WcfBindingType.WSDualHttpBinding)
{
WSDualHttpBinding ws = new WSDualHttpBinding();
ws.MaxReceivedMessageSize = ;
bindinginstance = ws;
}
else if (binding == WcfBindingType.WSFederationHttpBinding)
{
WSFederationHttpBinding ws = new WSFederationHttpBinding();
ws.MaxReceivedMessageSize = ;
bindinginstance = ws;
}
else if (binding == WcfBindingType.WSHttpBinding)
{
WSHttpBinding ws = new WSHttpBinding(SecurityMode.None);
ws.MaxReceivedMessageSize = ;
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透明代理类,动态调用,支持async/await的更多相关文章
- WCF 透明代理
现在我们通过类似的原理创建一个用于模拟WCF服务端和客户端工作原理的模拟程序.[源代码从这里下载] 目录 一.基本的组件和执行流程 二.创建自定义HttpHandler实现对服务调用请求的处理 三.定 ...
- 终于解决:升级至.NET 4.6.1后VS2015生成WCF客户端代理类的问题
在Visual Studio 2015中将一个包含WCF引用的项目的targetFramework从4.5改为4.6.1的时候,VS2015会重新生成WCF客户端代理类.如果WCF引用配置中选中了&q ...
- Node 7.6默认支持Async/Await
Node.js 7.6正式默认支持async/await功能,并能够使低内存设备获得更出色的性能. Node 7.6对async/await的支持来自于将V8(Chromium JavaScript引 ...
- WCF服务代理类-学习
类:ServiceDescriptionImporter Class 公开一种为 XML Web services 生成客户端代理类的方法. 地址:https://docs.microsoft.com ...
- 为什么 array.foreach 不支持 async/await
一.背景 react 项目中,渲染组件时,显示的数据一直有问题,本来以为是 react 组件的问题,后来才发现罪魁祸首在 fetch 数据的过程,因为我用了 async/await ,而却搭配了 fo ...
- 动态得到WCF的代理类并生成代码
Uri uri = new Uri("http://localhost:6580/Service1.svc?wsdl"); MetadataExchange ...
- C# 通过反射类动态调用DLL方法
网上看了很多关于反射的思路和方法,发现这个还算不错 //使用反射方: using System; using System.Collections.Generic; using System.Linq ...
- 关于IIS寄宿WCF服务,客户端不能生成代理类
我在使用VS2010写好WCF的Web服务后,部署在IIS7.0上,可以在IE9上进行访问,并且能显示XML数据,如下图 然后我在项目的客户端进行服务的添加引用,如下图 VS2010自动生成代理类,但 ...
- 创建一个简单的WCF程序2——手动开启/关闭WCF服务与动态调用WCF地址
一.创建WCF服务器 1.创建WCF服务器的窗体应用程序 打开VS2010,选择文件→新建→项目菜单项,在打开的新建项目对话框中,依次选择Visual C#→Windows→Windows窗体应用程序 ...
随机推荐
- Microsoft DQS sqlException 0x80131904 - SetDataQualitySessionPhaseTwo
遇到这个问题的原因可以从报错信息看出来,大概率是.net framework的问题 可以尝试如下解决途径 1. regenerate .net Assemble for DQS 2. 如果步骤一无法解 ...
- GDI+_入门教程【一】
GDI For VisualBasic6.0 [一]文件下载:GDI+ For VB6[一] 简单绘图实例演示百度网盘 1 '以下为作者[vIsiaswx]的教程 '(该教程发布的原地址已无法访问,此 ...
- Javascript面试题收集
第一部分“ 来源: http://bbs.miaov.com/forum.php?mod=viewthread&tid=6974 1.var a = b = 1; ——这样定义变量的隐患 fu ...
- 移动端过禁止输入emoji表情实现方案
最近手头上的项目有一个需求就是输入框不能输入表情,然后就各种在网上找资料,网上好多人给的方案是: str = str.replace(/\uD83C[\uDF00-\uDFFF]|\uD83D[\uD ...
- cdn贝四层协议配置端口映射TCP端口转发
端口映射就是将外网主机的IP地址的一个端口映射到内网中一台机器,提供相应的服务.当用户访问该IP的这个端口时,服务器自动将请求映射到对应局域网内部的机器上.端口映射有动态和静态之分 1.安装好节点后初 ...
- mybatis 根据参数映射对应模型
ORM 框架的优势在于能让我们利用面向对象的思维去操作数据库, hibernate 作为重量级的 ORM 框架对面向对象的支持很强大.作为半自动化的 mybatis ,对面向对象的支持也是很完备的.这 ...
- POJ-3268.SilverCowParty.(最短路 + 图的转置)
本题思路:对原图和原图的逆图分别用一次最短路,找出最大值即可. 一开始是我是对每个顶点spfa搜了一波,结果判题时间巨长,还好这个题的数据量不是很大,所以就用了另一种思路. 参考代码:spfa单结点爆 ...
- CentOS7配置samba服务
Step1:安装samba相关软件 [root@node-1 ~]# yum -y install samba samba-client Step2:创建共享目录 [root@node-1 ~]# m ...
- 386. Lexicographical Numbers 输出1到n之间按lexico排列的数字序列
[抄题]: Given an integer n, return 1 - n in lexicographical order. For example, given 13, return: [1,1 ...
- convert 函数的使用
先说问题:今天项目中很多模块出现了一个集体性的问题,时间检索时选择同一天 检索不出数据(表中数据确实存在),其实这个问题在做东西的时候领导说过,记忆中我解决了,但是后来写代码可能把这个问题忘记了! 其 ...