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属性,运行效果如下图:

     

  • 相关阅读:
    docker 安装mysql
    Java web项目搭建系列之二 Jetty下运行项目
    Java web项目搭建系列之一 Eclipse中新建Maven项目
    Maven 添加其他Maven组件配置问题
    C# 中定义扩展方法
    Oracle 函数
    【Webservice】2 counts of IllegalAnnotationExceptions Two classes have the same XML type name
    Linux精简版系统安装网络配置问题解决
    Rsync 故障排查整理
    Failed to set session cookie. Maybe you are using HTTP instead of HTTPS to access phpMyAdmin.
  • 原文地址:https://www.cnblogs.com/chillsrc/p/5707945.html
Copyright © 2011-2022 走看看