本节书摘来自异步社区《微软云计算Windows Azure开发与部署权威指南》一书中的第6章,第6.6节,作者: 尹成 , 郝庭毅 , 张俊强 , 孙奉刚 , 寇睿明 更多章节内容可以访问云栖社区“异步社区”公众号查看。
6.6 AppFabric服务总线服务Remoting的应用程序开发
本节将带领大家通过微软发布的Windows Azure Training Kit里的示例学习AppFabric服务总线的服务Remoting的应用程序开发。使用的训练包与6.3节一样,是WATK June2012.exe。示例项目目录为WATKLabsServiceBusServiceRemoting,进行该项目开发所需要的软件环境为(针对Windows 7操作系统)。
① IIS 7(开通ASP.NET、WCF HTTP Activation)。
② Microsoft .NET Framework 4.0。
③ Microsoft Visual Studio 2010。
④ Windows Azure Tools for Visual Studio 1.7。
⑤ Windows Azure Libraries for .Net 1.7。
首先介绍该示例工程的项目背景。有一个虚拟的银行,受管理规则的规定,要分为两部分:投资和零售。IT必须重构已存在客户的关系管理系统(以下简称CRM)让两个部分即使不在同一个企业网络内也都能访问到客户数据。已经建立的CRM Web服务大量使用了WCF技术,并且部署在本地运行。
最开始,IT部门决定将CRM Web服务继续部署在投资实体的本地,并将一部分功能通过托管在Windows Azure服务总线上的另一个服务来公开,让零售实体可以访问到。这样便将服务和客户端应用程序需要做的改变最小化了。
在第二阶段,投资实体外包了其应用程序服务部署。这样一来便将与零售实体共享的服务的部署位置更改了,并使用了工作者角色部署。但是由于服务总线命名空间允许服务继续以新的位置发布,于是客户端并不需要做任何改变,甚至对服务部署位置的改变毫无察觉。
本节将通过一个简单的实例程序来介绍服务总线应用程序的开发,该实例程序由服务端和客户端组成,服务端将服务托管到服务总线上,客户端则调用托管在服务总线上的服务。
本节的实例就是对该情形做简单的模拟。实例的解决方案包括两个由投资实体部署的两个服务,一个是CRM数据服务,为投资实体提供应用程序服务;另一个是FI Public服务,使用第一个服务将CRM的部分功能暴露给零售实体访问。实例的解决方案如图6-45所示。
安装步骤与6.3节一致,此处不再赘述。
1.步骤一:运行本地的服务
① 以管理员身份运行Visual Studio 2010,打开SourceEx1-ServiceBusRemotingBegin目录下的ServiceRemoting.sln文件。
该解决方案包含的工程如表6-3所示,目录结构如图6-46所示。
② 配置解决方案启动客户端、CRM数据服务、FI Public服务。在Solution Explore中右键单击ServiceRemoting解决方案,选择Set StartUp Projects。在“Solution 'ServiceRemoting' Property Pages”对话框中单击“Multiple startup projects”单选按钮,并将FictionalInvestment.Crm.Data、FictionalInvestment.Public.Services和FictionalRetail.Crm.Client 3个工程对应的Action设为Start。调整3个工程的顺序,确保与图6-47一致,单击“OK”完成更改。
![721834e9d5a888efd5b8616c2c6971c599723c4a](https://i-blog.csdnimg.cn/blog_migrate/0f01915b2c1fd2f37a85d5da35be8b3c.png)
![4b0924d3645ca4844d700e681f9490161b57e48a](https://i-blog.csdnimg.cn/blog_migrate/ebf34f6a2951a7b6496f91f698316d02.png)
③ 按F5键,构建解决方案并启动服务和客户端应用程序。
④ 注意每个服务都会显示器监听地址,CRM数据服务和FI Public服务当前使用net.tcp并监听的是环回测试地址。
⑤ 切换到Fictional Retail CRM Client应用程序。该窗体程序给出客户列表和当前在两个实体中办理的业务。
⑥ 在窗体程序中选择某些客户左侧的选择框,单击“Move to Fictional Retail Bank”,把一个或几个投资实体的客户移动到零售。通过观察CRM数据服务和FI Public服务的控制台信息可以知道该操作是否成功,如图6-48所示。
![f95a15f0a2a3c4eb0ee91ffceedf82613c5b2b52](https://i-blog.csdnimg.cn/blog_migrate/a9411691f81d8a43f705d9fcaa22b436.png)
⑦ 在两个控制台程序中按“ENTER”键终止服务,然后退出客户端应用程序。
2.步骤二:申请数据服务命名空间
该部分在6.2节中介绍过,读者可参考前面内容,此处不再赘述。
3.步骤三:配置访问控制服务用于身份认证
① 进入服务总线门户,单击左侧面板的“Service Bus,Access,Control&Caching”链接,选择Services项目下的Service Bus项目,如图6-49所示。
② 选择命名空间,单击上方的“Access Control Service”按钮,如图6-50所示。
![0846c7931686317b9444e7f72fedc62d1f0a2f08](https://i-blog.csdnimg.cn/blog_migrate/734564febac1197a6862bc7b133a57fa.png)
③ 进入访问控制服务门户后,选择左侧面板中的“Service Identities”,如图6-51所示。
![f1b22868aaff1b18465263365bfcea1df64a579e](https://i-blog.csdnimg.cn/blog_migrate/8418fa797d8b6820c44166a17b490341.png)
④ 单击“Add”链接,添加一个新的Identity,如图6-52所示。
⑤ 在Add Service Identity页面中,在Service Identity Settings下的Name字段输入“fictionalInvestment”,在Credential Settings下选择“Symmetric Key”,单击“Generate”按钮生成该证书的对称密钥,记录下该密钥,在接下来的步骤中将用到。最后将Expiration Date改成“”,然后单击“Save”按钮,如图6-53所示。
![e0331b6a8f55ffe233c6b1dfec37796ac3c607ad](https://i-blog.csdnimg.cn/blog_migrate/d9015afbfd8bccab32e2980e0a4e6128.png)
⑥ 现在,单击“Add”链接,为“fictionalInvestment”身份添加一个新的证书,如图6-54所示。
⑦ 在Add Credential页面中,单击“Password”作为证书类型。然后在Password字段填入上一步得到的对称密钥。最后把Expiration Date改为“”,单击“Save”,如图6-55所示。
⑧ 在Edit Service Identity页面中,单击“Save”按钮保存目前所做的所有更改,如图6-56所示。
⑨ 重复操作⑤~⑧,再创建一个名为“fictionalRetail”的新身份。
10 接下来需要创建一些规则,这些规则将发行人的身份映射到一些声明上,服务总线通过这些声明来确定该发行者可以做哪些操作。单击左侧的“Rule groups”连接,如图6-57所示。首先创建“fictionalInvestment”身份的“Send”规则。
11 在Rule Groups页面中,单击“Rule Groups”下的“Default Rule Group for ServiceBus”进行编辑,如图6-58所示。
![94ebb53164fa1a84449e4e1d02c45645e3322b93](https://i-blog.csdnimg.cn/blog_migrate/1fc2b775cc298daf976f40d50f6a15c4.png)
12 在Edit Rule Group页面中,单击“Add”添加新规则,如图6-59所示。
![14bfce92e0525097f2d324390975d221c0d37acc](https://i-blog.csdnimg.cn/blog_migrate/71d6ce72eeb55371e00871c317114e1f.png)
13 在Add Claim Rule页面中,在If下选“Access Control Service”单选框作为Input claim issuer。在“Input claim type”下选择“Select type”,使用默认值。在“Input claim value”下选择“Enter value”,并输入“fictionalInvestment”。在“Then”下选择“Enter type”作为Output claim type,并输入“net.windows.servicebus.action”。选择Enter value作为Output claim value并输入“Listen”,然后单击“Save”按钮,如图6-60所示。
14 接下来为“fictionalInvestment”身份添加一个“Send”规则。在Edit Rule Group页面,单击“Add”添加一个新的规则。在Add Claim Rule页面,在“If”下选择“Access Controls Service”作为Input claim issuer,在“Input claim type”下选择“Select type”并使用默认值。在“Input claim value”下选择“Enter value”并输入“fictionalInvestment”。在“Then”下选择“Enter type”作为output claim type并输入“net.windows.servicebus.action”。选择“Enter value”作为Output claim value,并输入“Send”。然后单击“Save”按钮,如图6-61所示。
15 最后,为“fictionalRetail”发行者添加“Send”规则。在Edit Rule Group页面,单击“Add”添加一个新的规则。在Add Claim Rule页面,在“If”下选择“Access Controls Service”作为Input claim issuer,在“Input claim type”下选择“Select type”并使用默认值。在“Input claim value”下选择“Enter value”并输入“fictionalRetail”。在“Then”下选择“Enter type”作为output claim type并输入“net.windows.servicebus.action”。选择“Enter value”作为Output claim value,并输入“Send”。然后单击“Save”按钮,如图6-62所示。
16 在Edit Rule Group页面中,单击“Save”保存全部更改,如图6-63所示。
![d7962e3aefd8750feec085197001f64b4a536951](https://i-blog.csdnimg.cn/blog_migrate/2087b9591311e8c9ee4d7002286fb20e.png)
图6-62 为“fictionalRetail”发行者添加“Send”规则
4.步骤四:配置服务监听Windows Azure服务总线
FI Public服务注册在服务总线上,通过特定的、可发现的URI地址暴露出服务,使无论位于什么地方的人都可以访问,即使有防火墙阻隔。Windows Azure服务总线架构如图6-64所示。
在服务总线上公布FI Public服务非常容易。只需要为服务总线添加一个引用,把服务使用的NetTcpBinding绑定改为NetTcpRelayBinding,然后将端点地址改为在云端的新地址。
① 以管理员身份运行Visual Studio 2010,打开SourceEx1-ServiceBusRemotingBegin下的Begin.sln文件。
② 在Solution Explorer中右键单击Fictional Investment.Public.Services工程,选择“Add Reference”。在.NET标签页中,选择“Microsoft.ServiceBus”,单击“OK”按钮。
③ 打开FictionalInvestment.PublicServices下的App.config文件,找到system.ServiceModel节点下的services节点中名为“FictionalInvestment.PublicServices.CrmPublicService”的endpoint节点。
④ 更新address属性值为“sb://[YOUR-NAMESPACE].servicebus.windows.net/CrmPublicService”,其中,[YOUR-NAMESPACE].为项目定义的服务总线命名空间。
⑤ 将binding属性的值由netTcpBinding改为netTcpRelayBinding。
⑥ 最后,为这个endpoint节点添加一个behaviorConfiguration属性,并将值设为serviceBus CredentialBehavior。下一步中会定义该行为。更改后的endpoint节点如图6-65所示。
![fd7ef703f34f0318488c60b243ec4abb2bd1047a](https://i-blog.csdnimg.cn/blog_migrate/7d064cb8980294831340e84f525197e7.png)
⑦ 在system.serviceModel中,添加上一步中添加的行为配置。该行为为服务总线提供用来验证服务发布者的证书。添加下面的代码段,将issuerSecret属性的值设为创建“fictionalInvestment”发行者时记下的Current Key。
<configuration>
<system.serviceModel>
<services>
...
</services>
<client>
...
</client>
<behaviors>
<endpointBehaviors>
<behaviorname="serviceBusCredentialBehavior">
<transportClientEndpointBehaviorcredentialType="SharedSecret">
<clientCredentials>
<sharedSecretissuerName="fictionalInvestment"
issuerSecret="[YOUR_FI_ISSUER_KEY]"/>
</clientCredentials>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
⑧ 将下面代码插入system.serviceModel区域。
<configuration>
...
<system.serviceModel>
...
<extensions>
<behaviorExtensions>
<addname="transportClientEndpointBehavior"
type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement,Microsoft.ServiceBus, Version=
.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</behaviorExtensions>
<bindingExtensions>
<addname="netTcpRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement,Microsoft.ServiceBus, Version=.0, Culture= neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingExtensions>
</extensions>
</system.serviceModel>
</configuration>
⑨ 为完成将服务发布到服务总线上需要做的更改,还要配置服务的连接模式。打开FictionalInvestment.PublicServices工程下的Program.cs文件,将下面的代码插入Main函数的开始处。
internalstaticvoid ()
{
// Tcp: All communication to the Service Bus is performed using outbound TCP connections.
// Http: All communication to Service Bus is performed using outbound HTTP connections.
// AutoDetect: The Service bus client automatically selects between TCP and HTTP connectivity.
Microsoft.ServiceBus.ServiceBusEnvironment.SystemConnectivity.Mode =
Microsoft.ServiceBus.ConnectivityMode.AutoDetect;
using (ServiceHost serviceHost = new ServiceHost(typeof(CrmPublicService)))
{
...
}
}
5.步骤五:配置客户端应用程序以连接Windows Azure服务总线上的服务
① 在客户端应用程序中添加对Microsoft.ServiceBus的引用。在Solution Explorer中右键单击FictionalRetail.Crm.Client工程,选择“Add Reference”。在.NET标签页中,选择“Microsoft.ServiceBus”,单击“OK”按钮。
② 打开FictionalRetail.Crm.Client工程中的App.config文件,定位到system.serviceModel下的endpoint节点。
③ 更新address属性值为“sb://[YOUR-NAMESPACE].servicebus.windows.net/CrmPublicService”,其中,[YOUR-NAMESPACE].为为项目定义的服务总线命名空间。
④ 将binding属性的值由netTcpBinding改为netTcpRelayBinding。
⑤ 最后,为这个endpoint节点添加一个behaviorConfiguration属性,并将值设为serviceBus CredentialBehavior。下一步中会定义该行为。更改后的endpoint节点如图6-66所示。
![70d251d44b7f8b76140de92e43abf6ad7748ae28](https://i-blog.csdnimg.cn/blog_migrate/a32632f4a186096d0e659cb04cdee6c4.png)
⑥ 在system.serviceModel中,添加上一步中添加的行为的配置。该行为为服务总线提供用来验证客户端应用程序的证书。添加下面的代码段,将issuerSecret属性的值设为创建“fictionalInvestment”发行者时记下的Current Key。
<configuration>
<system.serviceModel>
<client>
...
</client>
<behaviors>
<endpointBehaviors>
<behaviorname="serviceBusCredentialBehavior">
<transportClientEndpointBehaviorcredentialType="SharedSecret">
<clientCredentials>
<sharedSecretissuerName="fictionalRetail"
issuerSecret="[YOUR_FR_ISSUER_KEY]"/>
</clientCredentials>
</transportClientEndpointBehavior>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
⑦ 将下面的代码插入system.serviceModel区域。
<configuration>
...
<system.serviceModel>
...
<extensions>
<behaviorExtensions>
<addname="transportClientEndpointBehavior"
type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Version=.0, Culture= neutral, PublicKeyToken=31bf3856ad364e35"/>
</behaviorExtensions>
<bindingExtensions>
<addname="netTcpRelayBinding"
type="Microsoft.ServiceBus.Configuration.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=.0, Culture= neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingExtensions>
</extensions>
</system.serviceModel>
</configuration>
⑧ 设置客户端应用程序的连接模式。右键单击FictionalRetail.Crm.Client工程下的Main.cs文件,选择View Code命令,在Main类的构造方法开始处插入下面的代码。
public ()
{
// Tcp: All communication to the Service Bus is performed using outbound TCP connections.
// Http: All communication to Service Bus is performed using outbound HTTP connections.
// AutoDetect: The Service bus client automatically selects between TCP and HTTP connectivity.
Microsoft.ServiceBus.ServiceBusEnvironment.SystemConnectivity.Mode =
Microsoft.ServiceBus.ConnectivityMode.AutoDetect;
this.client = new PublicServiceClient();
this.InitializeComponent();
}
6.验证结果
现在使用服务总线测试程序验证结果。
配置解决方案运行CRM数据服务和FI Public服务。在Solution Explorer中右键单击ServiceRemoting解决方案,选择“Set StartUp Projects”。在Solution’ServiceRemoting’Property Pages对话框中选择“Multiple startup projects”选项,将Fictional.Investment.Crm.Data和Fictional.Investment. Public.Services工程的Action设为Start,并且二者顺序与此相同,其他工程都设为None。
按F5键构建并运行应用程序。
等待两个服务启动并分别显示状态信息。注意FI Public服务正在监听的URI地址的协议是“sb”,URI中包含命名空间。
在Solution Explorer中,右键单击FictionalRetail.Crm.Client,选择“Debug”→“Start new instance”,启动客户端应用程序。
客户端应用程序将其从链接到的服务总线上发布的服务检索到的客户数据放在同一个列表中。
从列表中选择一个或几个客户,单击“Move to Fictional Retail Bank”运行结果如图6-67所示。
① 可以看到客户端应用程序正常工作,与服务在本地监听时一样。这表明客户端不在投资实体网络中也能够通过服务总线连接到该服务。
② 在两个控制台程序中,按“Enter”键终止程序,然后退出客户端应用程序。
![4999eb17234f75da9fb64374fde632d5a7da1ff6](https://i-blog.csdnimg.cn/blog_migrate/c96106a2ed27fc4b39f0bea932e0c7a6.png)