zoukankan      html  css  js  c++  java
  • WCF系列之WCF的通信模式

    一、概述

    WCF在通信过程中有三种模式:请求与答复、单向、双工通信。以下我们一一介绍。

    二、请求与答复模式

    描述:

    客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务端有了答复后才能继续执行其他程序,如下图所示(图中的粗红线在此时代表顺序并不代表调用):

    请求与答复模式为WCF的默认模式,如下代码所示:

    [OperationContract]
     string ShowName(string name);

    即使返回值是void 也属于请求与答复模式。

    缺点:如果用WCF在程序A中上传一个2G的文件,那么要想执行程序B也许就是几个小时后的事情了。如果操作需要很长的时间,那么客户端程序的响应能力将会大大的下降。

    优点:有返回值我们就可以向客户端返回错误信息,如:只接收".rar"文件等信息。

    实例:

    //服务端接口
    using System.ServiceModel;
    
    namespace WCFService_Default
    {
        [ServiceContract]
        public interface IUser
        {
            [OperationContract]
            string ShowName(string name);
        }
    }
    //服务端实现
    namespace WCFService_Default
    {
        public class User : IUser
        {
            public string ShowName(string name)
            {
                //线程睡眠20秒钟
                System.Threading.Thread.Sleep(20000);
                return "WCF服务,显示名称:" + name;
            }
        }
    }
    
    //客户端调用
    using System;
    using WCFClient_Default.WCFService_Default;
    
    namespace WCFClient_Default
    {
        class Program
        {
            static void Main(string[] args)
            {
                UserClient client = new UserClient();
                Console.WriteLine(DateTime.Now);
                string result = client.ShowName("李林峰");
                Console.WriteLine(result);
                Console.WriteLine(DateTime.Now);
                Console.ReadLine();
            }
        }
    }

    在上例中,我们在服务端让线程睡眠20秒然后再返回客户端,那么客户端两次显示当前时间的间隔必然在20秒以上,如下图所示:

    二、单向模式

    描述:

    客户端向服务端发送求,但是不管服务端是否执行完成就接着执行下面的程序。如下图所示:

    单向模式要在OpertaionContract的属性中显示设置值,代码如下:

    [OperationContract(IsOneWay = true)]
    void ShowName(string name);

    优缺点与“请求响应模式”差不多倒过来。

    特点:使用 IsOneWay=true 标记的操作不得声明输出参数、引用参数或返回值

    实例:

    //服务端接口
    using System.ServiceModel;
    
    namespace WCFService_OneWay
    {
        [ServiceContract]
        public interface IUser
        {
            [OperationContract(IsOneWay = true)]
            void DoSomething();
        }
    }
    
    //服务端实现
    namespace WCFService_OneWay
    {
        public class User : IUser
        {
            public void DoSomething()
            {
                //线程睡眠20秒钟
                System.Threading.Thread.Sleep(20000);
            }
        }
    }
    
    //客户端调用
    using System;
    using WCFClient_OneWay.WCFService_OneWay;
    
    namespace WCFClient_OneWay
    {
        class Program
        {
            static void Main(string[] args)
            {
                UserClient client = new UserClient();
                Console.WriteLine(DateTime.Now);
                //调用WCF服务的方法
                client.DoSomething();
                Console.WriteLine(DateTime.Now);
                Console.ReadLine();
            }
        }
    }

    在单向模式中与请求响应模式最主要的就是加IsOneWay属性,运行效果如下:

    三、双工模式

    描述:

    双工模式建立在上面两种模式的基础之上,实现客户端与服务端相互的调用。相互调用:以往我们只是在客户端调用服务端,然后服务端有返回值返回客户端,而相互调用不光是客户端调用服务端,而且服务端也可以调用客户端的方法。如下图所示:

    在上图中,客户端的程序A调用服务端的程序A,服务程序A执行完成前又调用客户端的程序D,然后再返回到程序A,图有点乱,其实就是为了说明“服务端”与“客户端”可以相互调用,下面直接看代码。

    如我们所说的,双工模式是建立在以上两种模式之上的模式,他们并不冲突,代码如下:

    [ServiceContract(CallbackContract = typeof(IUserCallback))]
        public interface IUser
        {
            [OperationContract]
            string ShowName(string name);
        }
       //回调的接口 
        public interface IUserCallback
        {
            [OperationContract(IsOneWay = true)]
            void PrintSomething(string str);
        }

    实例:

    支持回调的绑定有4种:WSDualHttpBinding、NetTcpBinding、NetNamedPipeBinding、NetPeerTcpBinding。我们这里用WSDualHttpBinding为例

    //配置文件中的 binding 指定
    <endpoint address=""  binding="wsDualHttpBinding" contract="WCFService_DualPlex.IUser"></endpoint>
    
    //服务端接口
    using System.ServiceModel;
    
    namespace WCFService_DualPlex
    {
        [ServiceContract(CallbackContract = typeof(IUserCallback))]
        public interface IUser
        {
            [OperationContract]
            string ShowName(string name);
        }
    
        public interface IUserCallback
        {
            [OperationContract(IsOneWay = true)]
            void PrintSomething(string str);
        }
    }
    
    //服务端实现
    using System.ServiceModel;
    
    namespace WCFService_DualPlex
    {
        public class User : IUser
        {
            IUserCallback callback = null;
    
            public User()
            {
                callback = OperationContext.Current.GetCallbackChannel<IUserCallback>();
            }
    
            public string ShowName(string name)
            {
                //在服务器端定义字符串,调用客户端的方法向客户端打印
                string str = "服务器调用客户端...";
                callback.PrintSomething(str);
                //返回服务端方法
                return "WCF服务,显示名称:" + name;
            }
        }
    }
    
    //客户端调用
    using System;
    using System.ServiceModel;
    using WCFClient_DualPlex.WCFService_DualPlex;
    
    namespace WCFClient_DualPlex
    {
        //实现服务端的回调接口
        public class CallbackHandler : IUserCallback
        {
            public void PrintSomething(string str)
            {
                Console.WriteLine(str);
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                InstanceContext instanceContext = new InstanceContext(new CallbackHandler());
                UserClient client = new UserClient(instanceContext);
                Console.WriteLine(DateTime.Now);
                string result = client.ShowName("李林峰");
                Console.WriteLine(result);
                Console.WriteLine(DateTime.Now);
                Console.ReadLine();
            }
        }
    }

    在上例中,我们把接口定义在服务端,而实现在客户端,配置文件是由IDE自动生成的,我们在服务端ShowName方法中,调用了PringSomething的方法,实现了服务端向客户端的调用。

    执行效果如下图所示:

    四、代码下载:

    10 WCF 教程

    五、版权

    转载请注明出处:http://www.cnblogs.com/iamlilinfeng

  • 相关阅读:
    韩式英语
    Daily dictation 听课笔记
    words with same pronunciation
    you will need to restart eclipse for the changes to take effect. would you like to restart now?
    glottal stop(britain fountain mountain)
    education 的发音
    第一次用Matlab 的lamada语句
    SVN的switch命令
    String的split
    SVN模型仓库中的资源从一个地方移动到另一个地方的办法(很久才解决)
  • 原文地址:https://www.cnblogs.com/cmhunter/p/4245449.html
Copyright © 2011-2022 走看看