我们希望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绑定netTcpBinding寄宿到控制台应用程序

WCF绑定netTcpBinding寄宿到IIS

最新文章

  1. Android图片缓存之初识Glide
  2. python(五)文件操作
  3. iOS 微信支付
  4. 文本分析工具awk简单示例
  5. oracle lsnrctl status|start|stop
  6. [转]log4net使用(WinForm/WebFrom)
  7. 修改weblogic11g的JDK版本
  8. java对文件拷贝的简单操作
  9. linux中patch命令 -p 选项
  10. js动态向页面中添加表格
  11. 基于Adaboost的人脸检测算法
  12. delphi 输入文件相对路径的更改,更改成用户的
  13. “百度杯”CTF比赛 十月场EXEC
  14. CoordinatorLayout 嵌套 AppBarLayout RecyclerView ,通过代码控制,使得CoordinatorLayout 自动滑动到tab置顶的位置
  15. loadrunner脚本函数讲解
  16. DirectX11 With Windows SDK--03 索引缓冲区、常量缓冲区
  17. Centos6.8 下 从零开始 部署 Java Web 应用
  18. mongodb集群配置分片集群
  19. jQuery三级联动
  20. Hadoop学习笔记之六:HDFS功能逻辑(2)

热门文章

  1. df命令详解
  2. C++ 下面的AIDL
  3. [Ting&#39;s笔记Day6]活用套件carrierwave gem:(1)在Rails实现图片上传功能
  4. 在ASP.NET中使用KindEditor富文本编辑器
  5. SpringBoot集成Jasypt安全框架,配置文件内容加密
  6. 652. Find Duplicate Subtrees找出重复的子树
  7. linux用户和组管理,/etc/passwd 、/etc/shadow和/etc/group --学习
  8. Entity Framework - PostgresQL CodeFirst
  9. 每月最后一周的周六晚上21:00执行任务-crontab
  10. 服务器重新启动,ftp重新连接问题