zoukankan      html  css  js  c++  java
  • WCF学习之旅—请求与答复模式和单向模式(十九)

    一、概述

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

    二、请求与答复模式

           客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务端有了答复后,客户端才会继续向下执行,这种方式相对单向模式来说灵活性差,但是安全性高,因为是单线程的所以安全性极高,适用于有数据返回的请求。如下图所示(下图来自网络,图中的粗红线在此时代表顺序并不代表调用):

     

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

           /// <summary>
           /// 请求与答复模式,默认模式
           /// </summary>
           /// <param name="Id">书籍ID</param>
           /// <returns></returns>
            [OperationContract]
            string GetBook(string Id);

      只要是使用特性“[OperationContract]”即使返回值是void 也属于请求与答复模式。

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

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

      实例:

     

    //服务端接口
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
     
    
    namespace WcfServiceLib
    {
    
        // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IBookService”。
        [ServiceContract]
        public interface IBookService
        {
           /// <summary>
           /// 请求与答复模式,默认模式
           /// </summary>
           /// <param name="Id">书籍ID</param>
           /// <returns></returns>
    
            [OperationContract]
            string GetBook(string Id);    
    
        }
    
    }
    
     
    
     
    
     //服务端实现
    public class BookService : IBookService
        {
    
      public string GetBook(string Id)
            {
    
       System.Threading.Thread.Sleep(20000);
                int bookId = Convert.ToInt32(Id);
                Books book = SetBook(bookId);
                string xml = XMLHelper.ToXML<Books>(book);
                return xml;
     
    
            }
    
     
    
            public Books SetBook(int Id)
            {
    
                Books book = new Books();
                book.BookID = Id;
                book.AuthorID = 1;
                book.Category = "IBM";
                book.Price = 39.99M;
                book.Numberofcopies = 25;
                book.Name = "DB2数据库性能调整和优";
                book.PublishDate = new DateTime(2015, 2, 23);
                return book;
    
            }
    
     }
    
     
    
     //客户端调用
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms; 
    
    namespace WinClient
    {
    
        public partial class Form1 : Form
        {
    
            public Form1()
            {
    
                InitializeComponent();
            }
    
     
    
            private void btnGetBook_Click(object sender, EventArgs e)
            {
    
              textBox1.Text += string.Format("开始调用wcf服务:{0}
    ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                BookServiceReference.BookServiceClient client = new BookServiceReference.BookServiceClient();
                string book = client.GetBook("5");
                textBox1.Text += book;
                textBox1.Text += string.Format("
    调用结束:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
    
            }
    
        }
    
    }

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

     

                                              图1

     

                                       图2

     

    三、单向模式

             单向模式顾名思义是一种单向的请求,客户端向服务端发出消息请求后客户端就和服务端失去了联系,请求的一端不会关心是否返回结果继续往下执行。也就是说客户端发送请求后就会向下继续执行,不会等待服务端返回消息,而且服务端接收消息并执行服务,这种单向的模式其实是一种多线程下的操作,客户端发出消息后, 客户端和服务端就会同时执行,这样它们之间就不会互相冲突,同时也是线程安全的,提高了执行效率。
           单向模式只需要在方法声明中添加IsOneWay属性即可,它即可表示该消息的调用使用的是单向模式。如下图所示:

     

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

       

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

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

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

      实例:

     

      //服务端接口
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
     
    
    namespace WcfServiceLib
    {
    
        // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IBookService”。
        [ServiceContract]
        public interface IBookService
        {
    
           /// <summary>
           /// 请求与答复模式,默认模式
           /// </summary>
           /// <param name="Id">书籍ID</param>
           /// <returns></returns>
            [OperationContract]
            string GetBook(string Id);
            /// <summary>
            /// 单工模式,显示名称
            /// </summary>
            /// <param name="name">书籍名称</param>
            [OperationContract(IsOneWay = true)]
            void ShowName(string name); 
    
        }
    }
    
     
    
     //服务端实现
    
     
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
     
    
    namespace WcfServiceLib
    
    {
    
        // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“BookService”。
    
        // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 BookService.svc 或 BookService.svc.cs,然后开始调试。
    
        public class BookService : IBookService
        {
    
            /// <summary>
            /// 请求与答复模式,默认模式
            /// </summary>
            /// <param name="Id">书籍ID</param>
            /// <returns></returns>
            public string GetBook(string Id)
            {
                System.Threading.Thread.Sleep(20000);
                int bookId = Convert.ToInt32(Id);
                Books book = SetBook(bookId);
                string xml = XMLHelper.ToXML<Books>(book);
                return xml;
            }
    
     
    
            public Books SetBook(int Id)
            {
                Books book = new Books();
                book.BookID = Id;
                book.AuthorID = 1;
                book.Category = "IBM";
                book.Price = 39.99M;
                book.Numberofcopies = 25;
                book.Name = "DB2数据库性能调整和优";
                book.PublishDate = new DateTime(2015, 2, 23);
                return book;
            }
    
            /// <summary>
            /// 单工模式,显示名称
            /// </summary>
            /// <param name="name">名称</param>
            public void ShowName(string name)
            {
                Console.WriteLine(string.Format("书籍名称:{0},日期时间{1}", name, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
            }
    
        }
    
    }
    
     
    
     //客户端调用
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
     
    
    namespace WinClient
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
     
    
            private void btnGetBook_Click(object sender, EventArgs e)
            {
    
                textBox1.Text += string.Format("开始调用wcf服务:{0}
    ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                BookServiceReference.BookServiceClient client = new BookServiceReference.BookServiceClient();
                string book = client.GetBook("5");
                textBox1.Text += book;
                textBox1.Text += string.Format("
    调用结束:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            }
    
     
    
     
    
            /// <summary>
            /// 单工模式
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void buttonOneWay_Click(object sender, EventArgs e)
    
            {
    
                textBox1.Text += string.Format("开始调用wcf服务:{0}
    
    ", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                BookServiceReference.BookServiceClient client = new BookServiceReference.BookServiceClient();
                client.ShowName("科学可以这样看丛书");           
    
                textBox1.Text += string.Format("
    
    调用结束:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            }
    
        }
    
    }

     

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

     

  • 相关阅读:
    Django2.1发布,Django2.1新特性
    解决tomcat启动慢问题
    ELKstack简介及环境部署
    Django项目中使用celery做异步任务
    vue moment库格式化处理后端传的日期
    vueAdmin ui基础包
    DRF项目工程基础包
    linux文件系统命令和分区 挂载
    linux解压缩基本命令使用
    vim基本操作
  • 原文地址:https://www.cnblogs.com/chillsrc/p/5707945.html
Copyright © 2011-2022 走看看