wcf(1): 基本应用

勇哥注,下面的程序是摘自蒋金楠的文章:

他是wcf方面的权威 https://www.cnblogs.com/artech/archive/2007/02/26/656901.html

我把这个程序做为后面文章的起始代码用。


这个程序用的是vs2017。目前的wcf的hosting端只能用在.net framework里,.net core用不了。

而client端,在两边都是可以使用的。

在.net framework里,wcf功能主要引用System.ServiceMode。

在.net Core里,引用的是System.ServiceModel.xxx等一系列包(见图2)


如果想在.net Core下使用wcf的hosting端功能,只能用第三方的支持,那就是CoreWcf,下面是一些相关的文摘:

升级 WCF 服务器端项目以在 .NET 6 上使用 CoreWCF

https://learn.microsoft.com/zh-cn/dotnet/core/porting/upgrade-assistant-wcf

CoreWCF 支持策略

https://dotnet.microsoft.com/zh-cn/platform/support/policy/corewcf

探索CoreWCF:下一代.NET服务框架

https://blog.csdn.net/gitblog_00099/article/details/137003923


先放上基本程序的项目清单。

image.png

(图1)

image.png

(图2)



(一)契约 Contracts

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace Contracts
{
      [ServiceContract(Name="CalculatorService", Namespace="http://www.artech.com/")]
        public interface ICalculator
        {
           [OperationContract]
            double Add(double x, double y);
     
           [OperationContract]
           double Subtract(double x, double y);
    
           [OperationContract]
           double Multiply(double x, double y);
    
           [OperationContract]
           double Divide(double x, double y);        
       }
}

(二)服务 Services

using Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Services
{
    public class CalculatorService : ICalculator
        {
            public double Add(double x, double y)
            {
                return x + y;
            }
    
           public double Subtract(double x, double y)
           {
               return x - y;
           }
    
           public double Multiply(double x, double y)
           {
               return x* y;
           }
    
           public double Divide(double x, double y)
           {
               return x / y;
           }
       }
}


(三)宿主 Hosting

代码:

using Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace Hosting
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(CalculatorService)))
            {
                host.Opened += delegate
               {
                   Console.WriteLine("CalculaorService已经启动,按任意键终止服务!");
               };

                host.Open();
                Console.Read();
            }
        }
    }
}

app.config 配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
    <system.serviceModel>
          <behaviors>
              <serviceBehaviors>
                  <behavior name="metadataBehavior">
                      <serviceMetadata httpGetEnabled="true" httpGetUrl="http://127.0.0.1:9999/calculatorservice/metadata" />
                  </behavior>
              </serviceBehaviors>
          </behaviors>
          <services>
              <service behaviorConfiguration="metadataBehavior" name="Services.CalculatorService">
                  <endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding"  contract="Contracts.ICalculator" />
              </service>
          </services>
     </system.serviceModel>
</configuration>



(四)客户端  Client

代码:

using Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            //Thread.Sleep(2000);
            using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("calculatorservice"))
            {
                //省略代码
                ICalculator proxy = channelFactory.CreateChannel();
                using (proxy as IDisposable)
                {
                    Console.WriteLine("x + y = {2} when x = {0} and y = {1}", 1, 2, proxy.Add(1, 2));
                    Console.WriteLine("x - y = {2} when x = {0} and y = {1}", 1, 2, proxy.Subtract(1, 2));
                    Console.WriteLine("x * y = {2} when x = {0} and y = {1}", 1, 2, proxy.Multiply(1, 2));
                    Console.WriteLine("x / y = {2} when x = {0} and y = {1}", 1, 2, proxy.Divide(1, 2));
                    Console.ReadKey();
                }
            }
        }
    }
}

app.config 配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
    </startup>
    <system.serviceModel>
        <client>
            <endpoint address="http://127.0.0.1:9999/calculatorservice" binding="wsHttpBinding" 
                      contract="Contracts.ICalculator" 
                      name="calculatorservice" />
        </client>
    </system.serviceModel>
 
</configuration>


(五)运行

先运行hosting,再运行client


为了方便,可以设置多个启动项目。注意把Hosting放到最前面。

image.png


运行结果:

image.png

如果读者运行不起来,报”目标计算机积极拒绝“之类的错误,那就需要把Client和Hosting项目置为管理员方式运行。

请看勇哥这篇文章:http://47.98.154.65/?id=2285



勇哥总结一下:

wcf实现了RPC,即远程过程调用。

在这个例子里,Client和Hosting端都使用了相同的契约(即接口)

double Add(double x, double y);

因此在Client端调用Add函数时,实际上相当于由远程端执行Add,并且会返回一个double。

至于Client和Hosting之间是怎么通讯的,采用什么协议进行通讯的,这些全部都通过两者的app.config来配置进行的(也可以用代码实现)。


Client只需要知道契约即可以使用wcf的服务,这一点看Client的项目引用可以看出来。

image.png



由于wcf的通讯协议是相当丰富,从http, tcp,到pipe(进程命名管道),因此它在同一台电脑的多个进程之间,或者同一个局域网的多台电脑之间进行通讯,效率最高。在这两方面的应用,wcf有很强大的优势,你除了wcf不用做其它的选择。

如果使用http进行通讯,则可选择的就太多了,谷歌的gRPC,webApi等等,都是可以选择的。


这么强大的东西,微软却没有搞出完整版的.net core版本,真是太可惜了。


所谓时势造英雄,其实在软件界也是如此。

现在是移动互联网的天下,webApi现在是站到了风口上起飞了,wcf跌落神坛。

同样的,现在互联网从消费互联网开始落幕,转向产业互联网的时代,微软灵敏的触觉早已经知晓,全力拥抱云计算、开源跨平台、AI。
技术的更新永远来源于时势。


其实当我们站在微软的技术栈上面的时候,要知道天下技术趋势、不用大师预测更不用老师教你,只需要看下面这里:
image.png



源码下载:


链接:https://pan.baidu.com/s/1BOww4d8cnCt6DB-bK9hkAw 

提取码:k60x 

--来自百度网盘超级会员V6的分享




本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:
本帖最后由 勇哥,很想停止 于 2024-06-13 14:10:38 编辑

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864