zoukankan      html  css  js  c++  java
  • WCF与Asp.Net Web Application的深度整合方法

    在开发实践中,一种常见的情形是:先按照典型的方式开发了一个asp.net web application, 后来因为某些原因(例如,希望为其增加通过手机客户端操作的功能),希望为其增加更多的访问方式,当然,这时候服务端的解决方案当然首选WCF.

    但是,如果将WCF与现有的web application进行合适的整合,需要慎重处理.同样的操作,通过普通的Web Service模式和原来的应用程序内部调用相比, 性能可能会下降数十倍甚至更多,而这种性能的大幅度下降是我们所不希望看到的.

    为了在提供Service访问接口的同时,不降低现有的系统性能,亦不破坏原有的系统架构,我采取了如下的方案:

    1. 将WCF服务内嵌到Web Application项目中.

    选择将WCF服务嵌入到Web Application中(而不是另外新建一个项目), 有两重目的:

    (1) WCF服务可以直接调用原WebApp中的功能,而不需要通过复制代码,或是破坏原有架构的方式来实现. 复制代码可能带来一系列的不利后果,这个不再冗述,改变原有的WebApp架构则带来高昂的成本,或是进一步的性能下降.

    (2) WebApp自身不再需要通过任何一种channel来调用WCF功能, 它可以像使用一个普通类那样直接创建一个服务类的实例, 并调用其方法. 这一点很重要. 实际上,服务的主要使用者还是WebApp, 或者说, 如果不考虑增加客户端的种类,根本就不需要引进WCF,这些功能本来就是WebApp的一部分. 而如果将这些功能从WebApp中完全独立出去, 势必造成WebApp去访问服务时, 需要通过某种channel来进行通讯, 而这必然会带来一定的性能下降, 对于有些高频度使用的功能来说, 这可能会带来非常明显的响应速度障碍. 而通过将WCF服务嵌入到WebApp项目中,则完全消除了由于引入WCF而带来的对WebApp自身造成的性能影响.

    操作方法:

    直接在VS中添加新项—>WCF Serivce 即可.

    另外, 在Web.config中要增加相应的Service配置: 在根节点<configuration>下增加<system.serviceModel> 节点(如果已经有了...那你就不用添加了...), 其配置内容如下:

    <system.serviceModel>
      <services>
        <service name="Goodbaby.TestService">
        </service>
      </services>
    </system.serviceModel>

    其中,Service的name取决于实际项目的命名空间和服务类名.

    2. 开放Named Pipes channel, 使得托管在同一台服务器上的其它应用程序可以可以通过named pipes访问WCF服务.

    Named pipes channel是WCF的各种通讯方式中性能最高的一种, 但是它只能被同一主机的另一个应用程序所调用. 如果在实践中该服务器上只部署了这一个应用程序, 则可以忽略这一节. 但是如果在服务器上还部署了其它的应用程序, 并且它们有访问WebApp功能的需求, 则使用Named pipes就是最佳选择.

    在WCF中, 通过netNamedPipeBinding来实现Named pipes channel, 因此只需要配置一个使用该Binding的endpoint即可.

    操作方法:

    在Web.config的service节点下, 添加相应的endpoint, 配置内容如下:

    <service name="Goodbaby.TestService">
      <endpoint address=""
                binding="netNamedPipeBinding"
                contract="Goodbaby.ITestService">
      </endpoint>
      <host>
       <baseAddresses>
         <add baseAddress="net.pipe://localhost/WebApp/WebService/TestService.svc"/>
       </baseAddresses>
      </host>
    </service>

    这里在上面添加的service下面又添加了一个endpoint节点和一个host节点. 其中, endpoint中未指定address, 代表它将使用baseAddress, binding设置为内置的netNamedPipeBinding, 而contract是WCF服务所使用的接口名.

    baseAddress中,net.pipe表示这是一个Named pipes channel, 由于该channel只能在本机调用, 所以它的主机地址应该总是localhost, WebApp是实际的应用程序名, 后面的WebService是项目中的一个文件夹名, 而TestService.svc则是WCF服务所在的文件名.

    在IIS上启用named pipes(net.pipe binding)支持

    本来,在web.config中完成配置后就可以测试服务了,但是IIS默认是不支持net.pipe binding的,所以需要进行以下步骤以启用.

    (1)打开控制面板—> Turn windows features on or off—>Microsoft .Net Framework 3.5.1(这个版本号取决于实际安装的版本), 勾选Windows Communication Foundation Non-HTTP Activation, 保存.

    (2)选中IIS的Default web site(或是其它的自己添加的网站),在右侧的Actions面板中点击Bindings(如下图:).

    image

    在弹出的面板中确认是否已经添加了net.pipe binding:

    image

    (3) 展开Default web site, 点击选中具体的web application名, 在右侧的actions面板中点击advanced settings, 如下图:

    image

    在弹出的设置面板中确认Enabled Protocols是否包含了net.pipe.

    (4) 重置IIS.

    如果完成上述设置后, 仍然不能正常浏览服务, 可能需要重置iis.

    打开一个cmd命令窗口, 输入以下命令:

    >cd\windows\microsoft.net\framework\v4.0*

    最后一个目录是版本号, 请按实际安装的版本号为准.

    然后执行aspnet_regiis –i

    执行完成以后, 执行iisreset

    (5) 在IIS中浏览服务.

    在IIS的Content View中选中WCF服务文件(TestService.svc), 右击, Browse, 应该会看到默认的服务浏览界面:

    You have created a service.

    To test this service, you will need to create a client and use it to call the service......

    3.对于局域网中的用户,尽量采用TCP channel来访问WCF 服务.

    TCP channel的性能大约比普通的http快十倍左右, 在服务端要启用tcp channel与上述的named pipes非常类似, 增加一个endpoint, 并且在IIS上开启相应的支持即可, 具体做法由于与第2节极为相似, 不再详细说明.

    4.HTTP channel也应当保留

    典型的HTTP channel(也就是一般意义上的web service)虽然性能较差,但是其穿越防火墙的能力和通用性上的优势是其它channel所不能比拟的,当前面几种channel都不能使用时,应当使用http channel与WCF服务进行通讯.

    其具体的实现方式与其它的binding亦非常类似, 而且也是各种资料里提及最多的, 这里不再详细列出.

    总结

    借助于WCF对通讯方式的整合, 当实现多种访问渠道时, 对项目的实际修改只是在web.config中增加endpoint(及相应的对binding的配置,如果需要的话), 这使得无论通过什么方式去访问WCF服务, 甚至于不把它当作一个服务, 而是直接作为项目的一个类来看待, 执行的都是相同的代码, 这避免了将同样的功能复制好几份存储于不同的项目中,同时也保证了在各种上下文中都达到性能的最优.

    ---------------------------------------------

    作者:夏狼哉
    博客:http://www.cnblogs.com/Moosdau

    如需引用,敬请保留作者信息,谢谢

  • 相关阅读:
    JVM学习-垃圾回收算法
    JVM学习-jvm判断对象已死的方法
    JVM学习-jvm内存区域
    python 多线程
    Python+unittest+requests+excel实现接口自动化测试框架
    linux 运行tensorflow文件缺少_bz2问题及解决
    获取url地址
    微信小程序的小问题(2)
    微信小程序的小问题(1)
    前端知识
  • 原文地址:https://www.cnblogs.com/Moosdau/p/2788956.html
Copyright © 2011-2022 走看看