wcf深入学习笔记
从msdn中解释WCF:
WCF 通过一种面向服务的新型编程模型简化了关联应用程序的开发。通过提供分层的体系结构,WCF 支持多种风格的分布式应用程序开发。WCF 通道体系结构在底层提供了异步的非类型化消息传递基元。而建立在此基础之上的是用于进行安全可靠的事务处理数据交换的各种协议功能,以及广泛的传输协议和编码选择。
下面是wcf的配置介绍:
了解了wcf的大致情况,下面是总结的一些wcf运行步骤:
WCF Dispatching System
Step 1: ServiceHost和ServiceDescription的创建
ServiceDescription
Behaviors
ServiceBehavior EndpointBehavior ContractBehavior OperationBehavior
service behavior集合
Endpoints Address,Binding,Contract,Behaviors
Step 2: ServiceHost.Open()和Channel Listener & ChannelDispatcher的创建
Step 3: 请求接听和小心接受
Step 4: 获取匹配的EndpointDispatcher,并分发request message
Step 5: InstanceContext的获取
Step 6: 选择DispatchOperation
Step 7: 初始化当前的OperationContext
Step 8: 验证 Addressing信息
Step 9: 对request message进行检验或修改
Step 10: 对现有的service instance进行释放和回收
Step 11: 获取或者创建service instance
Step 12: 对当前线程的Context进行初始化
Step 13: 反序列化输入参数列表
Step 14: 对输入参数进行验证
Step 15: 执行service operation方法
Step 16: 对返回值或输出参数进行校验
Step 17: 序列化返回值或者输出参数
Step 18: 清理thread context
Step 19: Error handling
Step 20: 最后作一些资源的释放和清理工作
除此之外,wcf许多场景可以扩展,binging可以自定义MyBinding,可以定义自定义的MessageEncoder等。
好了说了这么多理论,该有实验场景了,
首先创建是MyRequestChannel:
public class MyRequestChannel:ChannelBase,IRequestChannel { private IRequestChannel InnerChannel { get; set; } public MyRequestChannel(ChannelManagerBase channelManager, IRequestChannel innerChannel) : base(channelManager) { this.InnerChannel = innerChannel; } #region Implement ChannelBase Members #endregion #region Implement IRequestChannel Members #endregion }
定义MyReplyChannel:
public class MyReplyChannel:ChannelBase,IReplyChannel { private IReplyChannel InnerChannel { get; set; } public MyReplyChannel(ChannelManagerBase channelManager, IReplyChannel innerChannel) : base(channelManager) { this.InnerChannel = innerChannel; } #region Implement ChannelBase Members #endregion #region Implement IReplyChannel Members #endregion }
接下来开始定义MyChannelListener:
public class MyChannelListener<TChannel>:ChannelListenerBase<TChannel> where TChannel:class,IChannel { private IChannelListener<TChannel> InnerChannelListener { get; set; } public MyChannelListener(BindingContext context) { this.InnerChannelListener = context.BuildInnerChannelListener<TChannel>(); } #region Implement ChannelListenerBase Members #endregion }
然后定义MyChannelFactory:
public class MyChannelFactory<TChannel> : ChannelFactoryBase<TChannel> { private IChannelFactory<TChannel> InnerChannelFactory { get; set; } public MyChannelFactory(BindingContext context) { this.InnerChannelFactory = context.BuildInnerChannelFactory<TChannel>(); } #region Implement ChannelFactoryBase<TChannel>Members #endregion }
定义MyBindingElement:
public class MyBindingElement:BindingElement { #region Implement BindingElement Members #endregion }
定义MyBinding:
public class MyBinding:Binding { #region Implement Binding Members public override BindingElementCollection CreateBindingElements() { BindingElementCollection elements = new BindingElementCollection(); elements.Add(new TextMessageEncodingBindingElement()); elements.Add(new MyBindingElement()); elements.Add(new HttpTransportBindingElement()); return elements.Clone(); } public override string Scheme { get { return "http"; } } #endregion }
最后就可以使用自己定义的Binding,WCF通讯了。
static void Main(string[] args) { MyBinding binding = new MyBinding(); IChannelListener<IReplyChannel> channelListener = binding.BuildChannelListener<IReplyChannel>( new Uri("http://127.0.0.1:8888/messagingbinding")); channelListener.Open(); while (true) { IReplyChannel channel = channelListener.AcceptChannel(TimeSpan.MaxValue); channel.Open(); RequestContext context = channel.ReceiveRequest(TimeSpan.MaxValue); Console.WriteLine("Receive a request message:\n{0}", context.RequestMessage); Message replyMessage = Message.CreateMessage( MessageVersion.Soap12WSAddressing10, "http://gavin.messagebinding", "this is manually created reply message for the purpose of testing"); context.Reply(replyMessage); channel.Close(); }
同样,扩展也可以用在MessageEncoder,下次继续介绍。
To be continued!