(十六).net学习之SOA-WebService

news2024/12/26 23:14:26

SOA-WebService

  • 一、SOA的思想,分布式服务
      • 1.SOA
      • 2.优势
      • 3.数据总线
  • 二、建立webservice
      • 1.关于webservice
      • 2.具体实现
  • 三、WCF多宿主协议
      • 1、自托管宿主
      • 2、windows service宿主
      • 3、IIS宿主
      • 4、WAS宿主

一、SOA的思想,分布式服务

1.SOA

  1. SOA:面向服务架构,搭建分布式服务的设计思想
  2. 分布式示意图如下,每个系统独立开来,调用时在通过数据总线。
    在这里插入图片描述

2.优势

把系统/功能模块/微服务等拆分到不同的服务器,提升承载能力

3.数据总线

数据总线是指分布式框架,比如dubbo、zookeeper、DNS等

二、建立webservice

1.关于webservice

  1. Http传输信道,决定数据在服务器之间是什么格式传递的
  2. XML的数据格式,通过Http传输解析得到的有用数据
  3. SOAP协议,简单对象访问协议是交换数据的一种协议规范,是一种轻量的、简单的、基于XML的协议,它被设计成在WEB上交换结构化的和固化的信息。
  4. WSDL:Web服务描述语言,是为描述Web服务发布的XML格式,属于webservice的标配
  5. UDDI:是一种用于描述、发现、集成Web Service的技术,它是Web Service协议栈的一个重要部分。通过UDDI,企业可以根据自己的需要动态查找并使用Web服务,也可以将自己的Web服务动态地发布到UDDI注册中心,供其他用户使用。
  6. 了解了一些概念性的东西之后,我想关于如何使用VS创建一个WebService项目也不用做多介绍了,这里只需要记住其以.asmx为后缀,集成System.Web.Services.WebService,并且使用特性WebService标记类,WebMethod标记服务方法就行了。而在调用端调用该WebService时只要在项目中添加服务引用即可,这一步骤VS会基于工具svcUtil.exe和WSDL生成一个代理,为我们屏蔽了服务调用的复杂性。

一般而言,我们将WebService用来做为公司内部各个系统之间的服务调用,在这个情况下一般也不需要去考虑权限相关的问题。但是有时候如果需要为外部应用提供服务,则需要重点考虑下权限。关于WebService的权限验证方式,可以采用

Form认证或windows认证 ,这中方式通过配置就可以完成。但实际开发中我们通常使用服务方法里面添加账号密码参数

或者添加SoapHeader来实现。下面我们就来看下如何使用SoapHeader方式来实现WebService的权限验证。
  首先需要定义一个继承自System.Web.Services.Protocols.SoapHeader,然后在方法中添加特性SoapHeader,具体看下面代码的实现。

2.具体实现

/// <summary>
/// Header:分配个加密钥  账号密码加密
/// 
/// </summary>
public class CustomSoapHeader : System.Web.Services.Protocols.SoapHeader
{

    private string userName = string.Empty;
    private string passWord = string.Empty;
    public CustomSoapHeader()//必须有一个无参数的构造函数
    { }

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="userName">用户名</param>
    /// <param name="passWord">密码</param>
    public CustomSoapHeader(string userName, string passWord)
    {
        this.userName = userName;
        this.passWord = passWord;
    }

    /// <summary>
    /// 获取或设置用户用户名
    /// </summary>
    public string UserName
    {
        get { return userName; }
        set { this.userName = value; }
    }

    /// <summary>
    /// 获取或设置用户密码
    /// </summary>
    public string PassWord
    {
        get { return passWord; }
        set { this.passWord = value; }
    }
    public bool Validate()
    {
        return this.UserName.Contains("Eleven") && this.PassWord.Contains("123456");
    }
}
public class MyWebService : System.Web.Services.WebService
{
    public CustomSoapHeader SoapHeaderProp { get; set; }

    [WebMethod]
    public string HelloWorld()
    {
        return "Hello World";
    }

    [WebMethod]
    public string HelloWorldWithAuth(string name_password)
    {
        if (true) { }
        return "Hello World";
    }
    [WebMethod]
    public string GetName(int i)
    {
        return $"{i}加菲猫";
    }
    [WebMethod]//webservice的方法就没有重载
    public int Plus(int x, int y)
    {
        return x + y;
    }
    [WebMethod]
    [SoapHeader("SoapHeaderProp")]
    public string GetInfo(int id, string name)
    {
        if (!this.SoapHeaderProp.Validate())
        {
            throw new SoapException("身份验证失败", SoapException.ClientFaultCode);
        }
        return Newtonsoft.Json.JsonConvert.SerializeObject(new
        {
            Id = id,
            Name = name,
            Remark = $"This is {id} {name}"
        });
    }

    [WebMethod]
    [SoapHeader("SoapHeaderProp")]
    public UserInfo GetUser(int id)
    {
        if (!this.SoapHeaderProp.Validate())
        {
            throw new SoapException("身份验证失败", SoapException.ClientFaultCode);
        }
        return new UserInfo()
        {
            Id = id,
            Name = "楠nan",
            Age = 27
        };
    }
using (MyWebServiceTest.MyWebServiceSoapClient client = new MyWebServiceTest.MyWebServiceSoapClient())
{
    MyWebServiceTest.CustomSoapHeader header = new MyWebServiceTest.CustomSoapHeader();
    header.UserName = "Eleven";
    header.PassWord = "123456";

    int iResult = client.Plus(12, 33);//45
    MyWebServiceTest.UserInfo userInfo = client.GetUser(header, 1);
    //List<MyWebServiceTest.UserInfo> userList = client.GetUserList(header);
    var userList = client.GetUserList(header);
}

三、WCF多宿主协议

WCF有多种宿主方式:1、自托管宿主,2、windows service宿主,3、IIS宿主,4、WAS宿主

1、自托管宿主

利用WCF提供的ServiceHost提供的Open()和Close()方法。

新建WCF服务库
新建WCF宿主应用程序
1)新建一个解决方案,名称为WcfService1Study。新建一个WCF服务库如下图:
在这里插入图片描述

2)我们将接口和类名分别重命名IDataService和DataService(读者自便),简化其中代码如下(只是为了实验而已)

//IDataService.cs
namespace WcfServiceLibrary
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
[ServiceContract]
public interface IDataService
{
[OperationContract]
CompositeType GetData();
}

// 使用下面示例中说明的数据约定将复合类型添加到服务操作。
// 可以将 XSD 文件添加到项目中。在生成项目后,可以通过命名空间“WcfServiceLibrary.ContractType”直接使用其中定义的数据类型。
[DataContract]
public class CompositeType
{
    bool boolValue = true;
    string stringValue = "Hello ";

    [DataMember]
    public bool BoolValue
    {
        get { return boolValue; }
        set { boolValue = value; }
    }

    [DataMember]
    public string StringValue
    {
        get { return stringValue; }
        set { stringValue = value; }
    }
}

}

//DataService.cs
namespace WcfServiceLibrary
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“Service1”。
public class DataService : IDataService
{
public CompositeType GetData()
{
//仅仅返回一个类
return new CompositeType();
}
}
}
到此,我们的WCF类库已经建好了。

3)修改App.config

默认在不修改配置文件的情况下,vs会自动给我们的服务配置到一个端口,如下 http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1/

我们修改App.config如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>

  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" />
  </system.web>
  <!-- 部署服务库项目时,必须将配置文件的内容添加到 
  主机的 app.config 文件中。System.Configuration 不支持库的配置文件。-->
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary.DataService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8081/WcfServiceLibrary/DataService/" />
          </baseAddresses>
        </host>
        <!-- Service Endpoints -->
        <!-- 除非完全限定,否则地址将与上面提供的基址相关 -->
        <endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary.IDataService">
          <!-- 
              部署时,应删除或替换下列标识元素,以反映
             用来运行所部署服务的标识。删除之后,WCF 将
              自动推断相应标识。
          -->
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <!-- Metadata Endpoints -->
        <!-- 元数据交换终结点供相应的服务用于向客户端做自我介绍。 --> 
        <!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除-->
        <!--<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>-->
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- 为避免泄漏元数据信息,
          请在部署前将以下值设置为 false -->
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
          <!-- 要接收故障异常详细信息以进行调试,
          请将以下值设置为 true。在部署前设置为 false 
            以避免泄漏异常信息-->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

</configuration>

主要改动是服务地址的改动和约束(因为我们的类重命名了)的改动

vs2012集成了wcf的测试客户端,ctrl+F5即可启动并测试wcf服务,效果如下: ![在这里插入图片描述](https://img-blog.csdnimg.cn/6f1416d119fe4d56951e60a13683f58f.png)

注意这里的【配置文件】菜单,里面包含有客户端对应的配置信息,接下来我们会用到。

到这里,我们的WCF库已经建好、配置好,也测试通过了。接下来建立宿主程序。

4)新建一个ConsoleApplication,命名为ConsoleAppSelfHost,增加对刚刚建好的WCF库的项目引用。

添加 System.ServiceModel引用,修改代码如下:

using System.ServiceModel;

namespace ConsoleAppSelfHost
{
    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(WcfServiceLibrary.DataService)))
            {
                host.Open();

                Console.WriteLine("wcf data service is running!");
                Console.Read();//阻塞宿主程序结束,期间供客户端调用该wcf服务

                host.Close();
            }
        }
    }
}

5)修改ConsoleApplication的App.config,将第三步中标红文字操作的内容拷贝到配置文件即可。

6)测试运行,如下:
在这里插入图片描述
查了好久都没有找到解决方案~~~最后仔细看了下这个错误,“未经处理的异常: System.InvalidOperationException: 服务“WcfServiceLibrary.DataService”有零个应用程序(非基础结构)终结点。这可能是因为未找到应用程序的配置文件,或者在配置文件中未找到与服务名称匹配的服务元素,或者服务元素中未定义终结点。”,问题是出在配置文件,我试着将WCF服务库的配置文件中的services节点拷贝到宿主程序配置中,测试,通过!

我的理解:在这种自宿主方式下,WCF服务库的配置文件其实只是用来测试的,其能真正对外服务则需要宿主程序进行配置,即宿主程序就是服务端,而WCF服务库在这种方式下其实就是一个类库,仅仅提供dll即可。

经过修改,最终宿主程序的配置文件如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <system.serviceModel>
    <services>
      <service name="WcfServiceLibrary.DataService">
        <endpoint address="" binding="basicHttpBinding" contract="WcfServiceLibrary.IDataService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8081/WcfServiceLibrary/DataService/" />
          </baseAddresses>
        </host>
      </service>
    </services>

    <client>
      <endpoint address="http://localhost:8081/WcfServiceLibrary/DataService/" binding="basicHttpBinding" contract="WcfServiceLibrary.IDataService"></endpoint>
    </client>
  </system.serviceModel>
</configuration>

运行,通过,大功告成。通过宿主Console窗口可以查看效果(在宿主运行期间,即wcf服务打开的时候,通过WCF的地址也可查看wsdl)。

2、windows service宿主

Windows Service宿主的实现就是依赖Windows Service项目,在Windows服务类(继承了ServiceBase类)的OnStart()和OnStop()方法中启动和关闭WCF服务的功能。

1)继续使用上述的WCF服务类库

2)新建一个windows service项目,命名为WindowsServiceHost,增加对刚刚建好的WCF库的项目引用。

添加 System.ServiceModel引用,重命名Service1为WCFService,代码如下:

namespace WindowsServiceHost
{
public partial class WCFService : ServiceBase
{
ServiceHost _host = null;
public WCFService()
{
InitializeComponent();
}

    protected override void OnStart(string[] args)
    {
        if (_host != null)
        {
            _host.Close();
            _host = null;
        }
        _host = new ServiceHost(typeof(WcfServiceLibrary.DataService));
        _host.Open();
    }

    protected override void OnStop()
    {
        if (_host != null)
        {
            _host.Close();
            _host = null;
        }
    }
}

}

3)配置文件和自宿主方式一样。

4)增加安装包程序

在WCFService的设计模式下右键【添加安装程序】即可。

5)我们通过在Visual Studio的Command Prompt模式下运行如下命令:

E:\testProjects\WcfService1Study\WindowsServiceHost\bin\Debug>InstallUtil WindowsServiceHost.exe
即可完成对服务宿主的安装。

6)在新安装的windows服务没有启动的时候,我们查看WCF的wsdl(配置的地址 http://localhost:8081/WcfServiceLibrary/DataService/)是无法访问的,当启动该服务之后,即可成功访问,说明Wcf服务成功寄宿在windows服务内。

3、IIS宿主

IIS宿主的使用相当简单。

1)新建wcf 服务应用程序,该应用程序可以被发布到IIS,即可完成IIS的寄宿。

本人修改了项目中的IService.cs为IMyWcfService.cs,Service.svc为MyWcfService.svc,CompositeType为MyWcfClass,读者自行随意修改。

我们将其发布地址设置为:http://127.0.0.1/WcfService1Study/

访问http://127.0.0.1/WcfService1Study/MyWcfService.svc,即可看到wsdl内容。

2)新建web应用程序,添加服务引用(wcf地址 http://127.0.0.1/WcfService1Study/MyWcfService.svc)即可调用wcf了。

web.config的内容都是自动添加的,每次更新服务应用,web.config也会更新。

4、WAS宿主

博主还没有对WAS宿主的大体认识,故借鉴大牛博客介绍如下:

WAS是IIS 7.0的一部分,但也可以独立地安装与配置。WAS支持所有可用的WCF传输协议、端口与队列。
利用WAS托管服务与IIS宿主托管服务的方法并没有太大的区别,仍然需要创建svc文件,同时在IIS中需要在站点中创建应有程序指向托管应用程序,还可以设置访问服务的别名与应用程序池。
由于WAS诉诸支持所有的绑定,因此此时的服务绑定并不会受到宿主的限制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/115540.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一个umi4的项目适配到FireFox60.7.1esr版本上的从头到尾

项目场景&#xff1a; 一个使用umi4创建的大屏项目&#xff0c;用户的浏览器使用的是火狐60.7.1的稳定版。然后就报错了&#xff01;&#xff01;&#xff01; 为什么不让用户换谷歌嘞&#xff0c;咱也不知道。那咱就搞兼容吧~~ 贴个浏览器的版本图片&#xff1a; 问题历程 …

【springboot】从解决@valid失效问题 到根据判断放行的更灵活替代方案 再到优雅的打日志

文章目录前言valid失效问题替代方案前言 valid 可以帮助我们节省很多代码 比较方便 但操作失误时 可能会失效 达不到我们预期效果&#xff1b; valid会有个问题 因为注解过于方便 反而会导致拦截后 错误日志的收集会比较麻烦 &#xff0c;以及在面对有时需要拦截 有时不需要拦截…

机器学习中的模型选择和评估

机器学习中的模型选择和评估1. 介绍2. 模型拟合效果2.1欠拟合与过拟合表现方式2.2 避免欠拟合与过拟合的方法3.实例分析3.1鸢尾花数据集3.2 对鸢尾花数据进行聚类1. 介绍 在机器学习系统中&#xff0c;如何训练出更好的模型、如何判断模型的效果&#xff0c;以及模型是否过拟合…

【内存对齐】一篇文章带你看懂内存对齐(万字详细介绍+代码样例)

目录 为什么需要内存对齐 性能 范围 原子性 结论 数据模型 C 的内存对齐 具名要求 平凡类 标准布局类 平凡类与标准布局类总结 标准布局类的内存对齐 普通的标准布局类 带有位域的标准布局类 手动指定对齐大小的标准布局类 非标准布局类的内存对齐 GLSLang 的…

分布式事务(3):AT模式实战-Seata

1 介绍 Seata&#xff08;Simple Extensible Autonomous Transaction Architecture&#xff0c;简单可扩展自治事务框架&#xff09;是 2019 年 1 月份蚂蚁金服和阿里巴巴共同开源的分布式事务解决方案。Seata 开源半年左右&#xff0c;目前已经有接近一万 star&#xff0c;社…

信息系统项目管理师考试总结

1、结果展示 从结果上看&#xff0c;论文刚刚过&#xff0c;案例分析差两份&#xff0c;选择题差五分。 问题一&#xff1a;案例分析中&#xff0c;计算题可以拿到分&#xff0c;提高案例分析的通过率。计算题比较客观。可以在下一次考试中多准备准备。 问题二&#xff1a;客观…

QUIC的诞生

背景 自1999年HTTP/1.1被提出以来&#xff0c;它已经稳定地被使用超过了20个年头。不过经典并不意味着完美&#xff0c;HTTP/1.1中一个连接同一时刻只能处理一个HTTP请求&#xff0c;如果当前的请求没有结束之前&#xff0c;其他的请求只能处于阻塞状 态。这一“对头阻塞”问题…

权限管理的配置思路

1.在main.js中引入permission.js 2.permission.js中通过vuex中getters.access_token进行路由的重定向 直接import ‘.permission’

MSF基本使用和控制台命令

前言 ● Msfconsole使用接口 ○ 最流行的用户接口 ○ 几乎可以使用全部MSF功能 ○ 控制台命令支持TAB自动补全 ○ 支持外部命令的执行&#xff08;系统命令等&#xff09; ○ 点击鼠标启动 / msfconsole -h -q -r -v / exit ○ help / &#xff1f; / help vulns 控制台命令 …

【Python】利用Python实现精准三点定位(经纬度坐标与平面坐标转换法求解)

【Python】利用Python实现精准三点定位&#xff08;经纬度坐标与平面坐标转换法求解&#xff09; 众所周知&#xff0c;如果已知三个点的坐标&#xff0c;到一个未知点的距离&#xff0c;则可以利用以距离为半径画圆的方式来求得未知点坐标。 如果只有两个已知点&#xff0c;则…

【Array数组】面试前基础知识点深度记忆总结

写本篇博客的原因是发现有人遇到了以下误区&#xff0c; 1、在我面试别人的过程中&#xff0c;我想让他说一下数组的一些内置方法和含义&#xff0c;然后他条例思路不太清晰&#xff0c;跳动着说&#xff0c;所以遗漏了很多&#xff0c;或许按照es5到es6是一个指导顺序&#xf…

51单片机——独立按键实验,小白讲解,相互学习

按键介绍&#xff1a; 按键是一种电子开关&#xff0c;使用时轻轻按开关按钮就可式开关接通&#xff0c;当松手时&#xff0c;开关断开。开发板上使用的按键及内部简易图如下图&#xff1a; 按键管脚两端距离长的表示默认是导通状态&#xff0c;距离短的默认是断开状态&#xf…

Pandas-根据数据表1中的字段a,筛选出数据表2中也包含字段a的数据

前言 本文是该专栏的第18篇,后面会持续分享python的数据分析知识,记得关注。 假设现在有个数据分析的需求,如下: 数据表1中有几十万条数据,数据表2中有几万条数据,两张数据表1和2有两个相同的字段phone,现在需要将数据表1和数据表2中,phone字段存在相同的行,保留下来…

redis集群操作

Redis集群1 集群2 集群架构图3 集群细节4 集群搭建4.1.创建集群4.2.查看集群状态4.3.添加主节点4.4.添加从节点4.5.删除副本节点4.6.集群在线分片1 集群 Redis在3.0后开始支持Cluster(模式)模式&#xff0c;目前redis的集群支持节点的自动发现&#xff0c;支持slave-master选举…

Nmap系统扫描实战

今天继续给大家介绍渗透测试相关知识&#xff0c;本文主要内容是Nmap系统扫描实战。 免责声明&#xff1a; 本文所介绍的内容仅做学习交流使用&#xff0c;严禁利用文中技术进行非法行为&#xff0c;否则造成一切严重后果自负&#xff01; 再次强调&#xff1a;严禁对未授权设备…

解决Win系统cad激活安装失败问题,AutoCad 2022 中文/英文正式详细安装教程

Autodesk AutoCAD 2022简称“cad 2022”是一款功能强大的CAD三维绘图辅助设计软件。autocad 2022适用于二维绘图、详细绘制、设计文档和基本三维设计&#xff0c;广泛应用于机械设计、工业制图、工程制图、土木建筑、装饰装潢、服装加工等多个行业领域。CAD2022新特征&#xff…

线径看板帮助电线电缆厂提高生产效率的工作原理

当今&#xff0c;市场上出现了越来越多的电线电缆品牌&#xff0c;电线电缆市场的竞争越来越激烈&#xff0c;电线厂家稍有不慎&#xff0c;出现了产品不规范、不合格的异常情况&#xff0c;就很可能会被市场淘汰&#xff0c;被消费者所抛弃。那么&#xff0c;要怎样才能够保障…

MVC(Model,View,Controller)

MVC是指Model&#xff08;模型层&#xff0c;数据&#xff09;&#xff0c;View&#xff08;视图层),Controller(控制层&#xff09; 核心是DispathcherServlet&#xff08;一个Servlet&#xff09; (1) 客户端的请求提交给DispathcherServlet (2&#xff09;DispathcherServl…

【动态规划篇】斐波那契数列拆分词句三角矩阵

&#x1f320;作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《数据结构与算法要啸着学》 &#x1f387;座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;…

基于Java(JSP+Servlet)+Mysql实现的(Web)简易的工资管理系统【100010062】

1.问题描述 一个公司下分为若干部门&#xff0c;每个部门有若干职员和经理&#xff0c;每个部门经销若干种商品。工资由基本工资、产品销售业绩奖、若干种保险的扣除等组成。其中的销售业绩奖按以下方式设计&#xff1a;职员按其完成额的 5% 提成&#xff0c;经理按其部门完成…