• WCF之Channel(二)


    接下来说ChannelListener和ChannelFactory。

    ChannelListener是Service端的技术,用来侦听消息,创建信道栈,并为应用程序提供指向栈顶的引用。

    我们不会直接使用ChannelListener,但是我们经常会使用到ServiceHost,殊途同归,其实也是用它来侦听消息。

    static void Main(string[] args)
    {
        BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
    
        Uri address = new Uri("http://localhost/request");
    
        Console.WriteLine("Starting Service...");
    
        IChannelListener<IReplyChannel> listener = binding.BuildChannelListener<IReplyChannel>(address, new BindingParameterCollection());
        listener.Open();
    
        IReplyChannel channel = listener.AcceptChannel();
        channel.Open();
    
        Console.WriteLine("Service Started~");
    
        Console.WriteLine("Waiting for request...");
    
        RequestContext request = channel.ReceiveRequest();
        Message message = request.RequestMessage;
        string data = message.GetBody<string>();
    
        Message replyMessage = Message.CreateMessage(message.Version, "http://localhost/reply", data);
    
        request.Reply(replyMessage);
        Console.WriteLine("Service stopped!");
    
        message.Close();
        request.Close();
        channel.Close();
        listener.Close();
    
        Console.ReadLine();
    }

    ChannelFactory是Client端的技术,用来发送消息和定义它所创建的channel的所有者。

    我们不会直接使用ChannelFactory,但是我们经常会见到ClientBase<T>,就是在Add Service Reference后自动生成的代码。

    static void Main(string[] args)
    {
        BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
    
        IChannelFactory<IRequestChannel> factory = binding.BuildChannelFactory<IRequestChannel>(new BindingParameterCollection());
    
        factory.Open();
    
        IRequestChannel channel = factory.CreateChannel(new EndpointAddress("http://localhost/request"));
        channel.Open();
    
        Message requestMessage = Message.CreateMessage(MessageVersion.Soap11, "http://localhost/reply", "This is the body data");
    
        Console.WriteLine("Sending message...");
    
        Message replyMessage = channel.Request(requestMessage);
    
        string data = replyMessage.GetBody<string>();
        Console.WriteLine("Reply received~");
    
        requestMessage.Close();
        replyMessage.Close();
        channel.Close();
        factory.Close();
    
        Console.ReadLine();
    }

    上面两段代码共同组成一个request-reply的Demo,代码下载:RequestReply.zip

    ChannelListener和ChannelFactory的区别是,前者会关闭全部相关的channel,而后者不会。

    ChannelFactory<T>区别于ChannelFactory,前者用于创建多个Client。

    最后提到ICommunicationObject,所有的Channel、ChannelListener和ChannelFactory都实现了这个接口,例如:

    IOutputChannel : IChannel, ICommunicationObject

    这个接口是为了实现状态机。

    image

    注意到这个接口的State属性,它是一个enum,对应了状态机的所有state:

    public enum CommunicationState
    {
        Created = 0,
        Opening = 1,
        Opened = 2,
        Closing = 3,
        Closed = 4,
        Faulted = 5,
    }

    image

    ClientBase<T>就是实现了ICommunicationObject接口。

    此外,WCF还提供了一个抽象类CommunicationObject,也实现了ICommunicationObject接口,并实现了状态机,所以我们可以使用ICommunicationObject接口暴露的那些event。我们只要从这个抽象类中派生,就可以自定义自己的方法和事件。

    WCF本质论P109页的这个例子,是把一个Client转换为ICommunicationObject接口,从而在接口暴露的事件上附加自定义的方法:

    image

    至此,Channel全都说完,不过,可惜啊可惜,这些内容只能用来加深我们对WCF的理解,而很少在实际中运用。WCF开发Team需要想想为什么了。

  • 相关阅读:
    linux删除目录的命令
    Windows XP下git通过代理下载android代码
    白话算法希尔排序
    操作系统——存储技术
    如何理解Linus Torvalds的“什么才是优秀程序员”的话
    程序员自我修养读书随笔——目标文件
    面试求职:大数据处理总结
    持久化与Session定义
    java中byte转换int时为何与0xff进行与运算
    OSI七层相关协议
  • 原文地址:https://www.cnblogs.com/Jax/p/1598157.html
Copyright © 2020-2023  润新知