热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

(十六).net学习之SOAWebService

SOA-WebService一、SOA的思想,分布式服务1.SOA2.优势3.数据总线二、建立webservice1.关于webservice2.具体实现三、WCF多


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.具体实现

///


/// Header:分配个加密钥 账号密码加密
///
///

public class CustomSoapHeader : System.Web.Services.Protocols.SoapHeader
{
private string userName = string.Empty;
private string passWord = string.Empty;
public CustomSoapHeader()//必须有一个无参数的构造函数
{ }
///
/// 构造函数
///

/// 用户名
/// 密码
public CustomSoapHeader(string userName, string passWord)
{
this.userName = userName;
this.passWord = passWord;
}
///
/// 获取或设置用户用户名
///

public string UserName
{
get { return userName; }
set { this.userName = value; }
}
///
/// 获取或设置用户密码
///

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

主要改动是服务地址的改动和约束&#xff08;因为我们的类重命名了&#xff09;的改动

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

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

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

4&#xff09;新建一个ConsoleApplication&#xff0c;命名为ConsoleAppSelfHost&#xff0c;增加对刚刚建好的WCF库的项目引用。

添加 System.ServiceModel引用&#xff0c;修改代码如下&#xff1a;

using System.ServiceModel;
namespace ConsoleAppSelfHost
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host &#61; new ServiceHost(typeof(WcfServiceLibrary.DataService)))
{
host.Open();
Console.WriteLine("wcf data service is running&#xff01;");
Console.Read();//阻塞宿主程序结束&#xff0c;期间供客户端调用该wcf服务
host.Close();
}
}
}
}

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

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

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

经过修改&#xff0c;最终宿主程序的配置文件如下&#xff1a;

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

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


2、windows service宿主

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

1&#xff09;继续使用上述的WCF服务类库

2&#xff09;新建一个windows service项目&#xff0c;命名为WindowsServiceHost&#xff0c;增加对刚刚建好的WCF库的项目引用。

添加 System.ServiceModel引用&#xff0c;重命名Service1为WCFService&#xff0c;代码如下&#xff1a;

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

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

}

3&#xff09;配置文件和自宿主方式一样。

4&#xff09;增加安装包程序

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

5&#xff09;我们通过在Visual Studio的Command Prompt模式下运行如下命令&#xff1a;

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

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


3、IIS宿主

IIS宿主的使用相当简单。

1&#xff09;新建wcf 服务应用程序&#xff0c;该应用程序可以被发布到IIS&#xff0c;即可完成IIS的寄宿。

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

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

访问http://127.0.0.1/WcfService1Study/MyWcfService.svc&#xff0c;即可看到wsdl内容。

2&#xff09;新建web应用程序&#xff0c;添加服务引用&#xff08;wcf地址 http://127.0.0.1/WcfService1Study/MyWcfService.svc&#xff09;即可调用wcf了。

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


4、WAS宿主

博主还没有对WAS宿主的大体认识&#xff0c;故借鉴大牛博客介绍如下&#xff1a;

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







推荐阅读
  • 本文总结了初学者在使用dubbo设计架构过程中遇到的问题,并提供了相应的解决方法。问题包括传输字节流限制、分布式事务、序列化、多点部署、zk端口冲突、服务失败请求3次机制以及启动时检查。通过解决这些问题,初学者能够更好地理解和应用dubbo设计架构。 ... [详细]
  • python zookeeeper 学习和操作
    1.zookeeeper介绍ZooKeeper是一个为分布式应用所设计的分布的、开源的协调服务,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,简化分布式应用协调及其管理的 ... [详细]
  • Zookeeper为分布式环境提供灵活的协调基础架构。ZooKeeper框架支持许多当今最好的工业应用程序。我们将在本章中讨论ZooKeeper的一些最显着的应用。雅虎ZooKee ... [详细]
  • 分布式大型互联网企业架构!
    2019独角兽企业重金招聘Python工程师标准摘要:开发工具1.EclipseIDE:采用Maven项目管理,模块化。2.代码生成: ... [详细]
  • HadoopYARN集群是一个通用的资源管理平台,可为各类计算框架提供资源的管理和调度。其核心是通过一个全局的资源管理器来实现分离资源管理与作业调度监控。Hadoop ... [详细]
  • HotFrameLearning热门框架学习(目录)-I、项目介绍-II、专辑栏目一、RedisRedis简介Redis环境安装配置Redis客户端连接 ... [详细]
  • dubbo学习 一 dubbo概述
    1,背景1,网站刚开时候的时候可能所有的功能业务都在一个应用里面2,当业务不断复杂,流量不断增多的时候,就需要将原先的一个应用划分成多个独立的应用。3,当分出来的业务越来越多的时候 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 新手学习java中,Java新手
    本文目录一览:1、java初学者怎么入门2、新 ... [详细]
  • 分库分表  ShardingJDBC (详解 1/6)
    狂创客圈经典图书:《NettyZookeeperRedis高并发实战》面试必备+面试必备+面试必备【博客园总入口】疯狂创客圈经典图书:《SpringCloud、Nginx高并发核心 ... [详细]
  • Ajax智能匹配检索(含图含完整代码)
    使用谷歌搜索引擎的用户都知道,只要在文本框中输入部分关键字,就能显示相关搜索提示信息列表。如图:   本技术的核心是通过ASP.NETAjaxControlToolkit中的Aut ... [详细]
  • SpringCloud之eureka注册中心入门
    eureka注册中心一、基本概念SpringCloud封装了Netflix公司的eureka作为自己微服务的注册中心。这个注册中心和dubbo中的zookeeper很相似,简单来说 ... [详细]
author-avatar
色花君子fds_181
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有