• WCF接口实例介绍


    Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台。

    WCF整合了原有的windows通讯的 .net Remoting,WebService,Socket的机制,并融合有HTTPFTP的相关技术。

    简单的归结为四大部分

    1>.网络服务的协议,即用什么网络协议开放客户端接入。

    2>.业务服务的协议,即声明服务提供哪些业务。

    3>.数据类型声明,即对客户端与服务器端通信的数据部分进行一致化。

    4>.传输安全性相关的定义。

    下面直接看一个例子:

    一.服务端实例

    1.定义一个WCF接口名称未Ichangeline

        服务契约(ServiceContract),订定服务的定义。

         // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IStaffLoginCheckService”。
        [ServiceContract] //服务协定定义
        public interface IChangeline
        {

            [OperationContract] // 操作服务定义

            string EsopCheckOk();

            [OperationContract]
            string HelloWorld();

        } 

    2.定义一个类实现接口名称Changeline

     // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“StaffLoginCheckService”。
        [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single)]
        public class Changeline : IChangeline
        {
           public string HelloWorld()
            {
                string result = "123456";
                return result;
            }

    }

    3.开通WCF所需要的服务,也可以从VS直接添加WCF服务

     1  #region 启动WCF服务
     2         private void OpenWcfService()
     3          {
     4              try
     5              {
     6                  var changeline = new Changeline(bendview);
     7                  host = new ServiceHost(changeline, new Uri("http://localhost:8734/MyService/"));
     8                  //这是我们服务的地址
     9                 host.AddServiceEndpoint(typeof(IChangeline), new BasicHttpBinding(), string.Empty);
    10                  host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
    11                  //mex元数据的地址
    12                 host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(),
    13                      "mex");
    14                  host.Open();
    15                  var port = "8734"; //获取端口号
    16                 var inname = "Changeline"; //打开端口号的名称
    17                 var str = " netsh advfirewall firewall add rule name=" + inname +
    18                            " dir=in action=allow protocol=TCP localport= " + port;
    19                  var pro = new Process(); //实例化进程
    20                 pro.StartInfo.FileName = "cmd.exe"; //设置要运行的程序文件
    21                 pro.StartInfo.UseShellExecute = false; //是否使用操作系统shell程序启动
    22                 pro.StartInfo.RedirectStandardInput = true; //是否接受来自应用程序的调用
    23                 pro.StartInfo.RedirectStandardOutput = true; //是否接受来自应用程序的输出信息
    24                 pro.StartInfo.RedirectStandardError = true; //是否接受重定向错误信息
    25                 pro.StartInfo.CreateNoWindow = true; //不显示窗口信息
    26                 pro.Start(); //启动程序
    27 
    28                 //向cmd窗口发送输入信息
    29                 pro.StandardInput.WriteLine(str + "&exit");
    30 
    31                 pro.StandardInput.AutoFlush = true;
    32                  pro.WaitForExit(); //等待程序运行完退出程序
    33                 pro.Close(); //关闭进程
    34             }
    35              catch (Exception ex)
    36              {
    37                  Tool.Log.Error("WCF开起失败:" + ex.Message);
    38              }
    39              CheckWCFServerTh = new Thread(WCF_HostCheck);
    40              CheckWCFServerTh.IsBackground = true;
    41              CheckWCFServerTh.Start();
    42          }
    43          void WCF_HostCheck(object o)
    44          {
    45              //Closed 指示通信对象已关闭,且不再可用。
    46             //Closing 指示通信对象正转换到 Closed 状态。
    47             //Created 指示通信对象已实例化且可配置,但尚未打开或无法使用。
    48             //Faulted 指示通信对象发生错误,无法恢复且不再可用。
    49             //Opened 指示通信对象目前已打开,且随时可供使用。
    50             //Opening 指示通信对象正从 Created 状态转换到 Opened 状态。
    51             while (true)
    52              {
    53                  try
    54                  {
    55                      if (!(host.State == CommunicationState.Opened || host.State == CommunicationState.Opening))
    56                      {
    57                          var changeline = new Changeline(bendview);
    58                          host = new ServiceHost(changeline, new Uri("http://localhost:8734/MyService/"));
    59                          //这是我们服务的地址
    60                         host.AddServiceEndpoint(typeof(IChangeline), new BasicHttpBinding(), string.Empty);
    61                          host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
    62                          //mex元数据的地址
    63                         host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(),
    64                              "mex");
    65                          host.Open();
    66 
    67                         var port = "8734"; //获取端口号
    68                         var inname = "Changeline"; //打开端口号的名称
    69                         var str = " netsh advfirewall firewall add rule name=" + inname +
    70                                    " dir=in action=allow protocol=TCP localport= " + port;
    71                          var pro = new Process(); //实例化进程
    72                         pro.StartInfo.FileName = "cmd.exe"; //设置要运行的程序文件
    73                         pro.StartInfo.UseShellExecute = false; //是否使用操作系统shell程序启动
    74                         pro.StartInfo.RedirectStandardInput = true; //是否接受来自应用程序的调用
    75                         pro.StartInfo.RedirectStandardOutput = true; //是否接受来自应用程序的输出信息
    76                         pro.StartInfo.RedirectStandardError = true; //是否接受重定向错误信息
    77                         pro.StartInfo.CreateNoWindow = true; //不显示窗口信息
    78                         pro.Start(); //启动程序
    79                         //向cmd窗口发送输入信息
    80                         pro.StandardInput.WriteLine(str + "&exit");
    81                          pro.StandardInput.AutoFlush = true;
    82                          pro.WaitForExit(); //等待程序运行完退出程序
    83                         pro.Close(); //关闭进程
    84                     }
    85                  }
    86                  catch (Exception ex)
    87                  {
    88                      Tool.Log.Error("WCF开起失败:" + ex.Message);
    89                  }
    90                  Thread.Sleep(3000);
    91              }
    92          }
    93          #endregion
    View Code

    二.客户端的程序

    1.配置好通道工厂,为客户端创立独立通道,为获取接口配置程序可以创建一个类(WcfChannelFactory)

     1 /// <summary>
     2       /// 使用ChannelFactory为wcf客户端创建独立通道
     3      /// </summary>
     4       public class WcfChannelFactory
     5       {
     6           public WcfChannelFactory()
     7           {
     8           }
     9 
    10         /// <summary>
    11          /// 执行方法   WSHttpBinding
    12          /// </summary>
    13          /// <typeparam name="T">服务接口</typeparam>
    14          /// <param name="uri">wcf地址</param>
    15          /// <param name="methodName">方法名</param>
    16          /// <param name="args">参数列表</param>
    17          public static object ExecuteMetod<T>(string uri, string methodName, params object[] args)
    18           {
    19               //BasicHttpBinding binding = new BasicHttpBinding();   
    20              WSHttpBinding binding = new WSHttpBinding();
    21               EndpointAddress endpoint = new EndpointAddress(uri);
    22   
    23               using (ChannelFactory<T> channelFactory = new ChannelFactory<T>(binding, endpoint))
    24              {
    25                   T instance = channelFactory.CreateChannel();
    26                   using (instance as IDisposable)
    27                   {
    28                       try
    29                       {
    30                           Type type = typeof(T);
    31                           MethodInfo mi = type.GetMethod(methodName);
    32                           return mi.Invoke(instance, args);
    33                       }
    34                       catch (TimeoutException)
    35                       {
    36                           (instance as ICommunicationObject).Abort();
    37                           throw;
    38                       }
    39                       catch (CommunicationException)
    40                       {
    41                           (instance as ICommunicationObject).Abort();
    42                           throw;
    43                       }
    44                       catch (Exception vErr)
    45                       {
    46                           (instance as ICommunicationObject).Abort();
    47                           throw;
    48                       }
    49                   }
    50               }
    51           }
    52   
    53   
    54          //nettcpbinding 绑定方式
    55          public static object ExecuteMethod<T>(string pUrl, string pMethodName,params object[] pParams)
    56           {
    57                   EndpointAddress address = new EndpointAddress(pUrl);
    58                   Binding bindinginstance = null;
    59                   BasicHttpBinding ws = new BasicHttpBinding();
    60                   ws.MaxReceivedMessageSize = 20971520;
    61                   bindinginstance = ws;
    62                   using (ChannelFactory<T> channel = new ChannelFactory<T>(bindinginstance, address))
    63                   {
    64                       T instance = channel.CreateChannel();
    65                       using (instance as IDisposable)
    66                       {
    67                           try
    68                           {
    69                               Type type = typeof(T);
    70                               MethodInfo mi = type.GetMethod(pMethodName);
    71                               return mi.Invoke(instance, pParams);
    72                           }
    73                           catch (TimeoutException)
    74                           {
    75                               (instance as ICommunicationObject).Abort();
    76                               throw;
    77                           }
    78                           catch (CommunicationException)
    79                           {
    80                               (instance as ICommunicationObject).Abort();
    81                               throw;
    82                           }
    83                           catch (Exception vErr)
    84                           {
    85                               (instance as ICommunicationObject).Abort();
    86                               throw;
    87                           }
    88                       }
    89                   }
    90           }
    91       }
    View Code

    2.调用WcfChannelFactory,获取接口数据

    调用时需要把服务端开的接口添加到本程序中,

      

     public void Statedeal()
             {
                 try
                 {
    
                    string result = WcfChannelFactory.ExecuteMethod<IChangeline>("http://localhost:8734/MyService/", "EsopCheckOk").ToString();
                   
                     MessageBox.Show(result.ToString());
                 }
                 catch(Exception ex)
                 {
                     MessageBox.Show(ex.ToString());
    
                }
             }
    View Code

    此时整个的服务端与客户端都可以实现了,如果客户端程序中也含有wcf服务程序(也会发布WCF服务,也作为服务端),并且接口名称与服务端(本客户端的服务端)的接口名称相同,那就必须保证服务端提供的接口名称与客户端定义的接口名称不同,或者相同名称在不同的程序集下。

  • 相关阅读:
    xmake v2.2.2, 让C/C++拥有包依赖自动构建
    xmake新增对WDK驱动编译环境支持
    记一次博客页面美化过程,分享代码.
    Java容器集合经典面试题集
    学习Redis好一阵了,我对它有了一些新的看法
    Java讲解RPC的基本实现
    项目中用到了Redis分布式锁,了解一下背后的原理
    为什么Mysql的常用引擎都默认使用B+树作为索引?
    关于浮点数与精确小数计算的理解
    通过模拟Mybatis动态代理生成Mapper代理类,讲解Mybatis核心原理
  • 原文地址:https://www.cnblogs.com/TechnologyDictionary/p/10423069.html
Copyright © 2020-2023  润新知