zoukankan      html  css  js  c++  java
  • WCF 采用net.tcp协议实践

    概述

        与Socket相比,WCF真是爽得不得了,其基本指导思想为SOA——面向服务。

        其基本配置在于ABC(Address,Binding,Contract),通常,只要这三个因素配置对了,那么,基本上就无限接近目标了。

        剩下的配置,就可能是行为(Behavior),安全(Security)等。

        在所有绑定中,为什么要选择net.tcp,是因为其比较快(我这也是道听途说,究竟有多快,没有进行过测试);但是,缺点就是,net.tcp方式只能是WCF对WCF的通信。

        而其繁琐复杂的配置,网上已经有诸多工程师做了很多无私的奉献。

    步骤

        原文参考:http://hi.baidu.com/guolulang/item/b5bdb01ccb23810ce65c36d6

                          http://www.cnblogs.com/Gyoung/archive/2012/12/11/2812555.html

    Step1:设置“打开或关闭Windows功能”

        打开红色框内的功能

    CN1

    Step2:设置IIS

    选中Default Web Site ——点击“绑定”——确保网站绑定对话框中有“net.tcp”(默认端口号808),如果没有,则“添加”

    image

    选中项目——高级设置——确保有“net.tcp”

    image

    Step3:设置“服务”

    image

    Step4:设置配置文件

        只需将下文中的******替换即可。

    S4.1服务端模板

        替换Address(主机名+端口+文件路径形式的名称);

        替换Contract(服务接口全名)

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <system.serviceModel>
        <!--描述绑定-->
        <bindings>
          <netTcpBinding>
            <binding name="netTcpBindConfig" closeTimeout="00:30:00"
                    openTimeout="00:30:00" receiveTimeout="00:30:00" sendTimeout="00:30:00"
                    transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
                    hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                    maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10"
                    maxReceivedMessageSize="2147483647">
              <readerQuotas maxDepth="2147483647"
                              maxStringContentLength="2147483647"
                              maxArrayLength="2147483647"
                              maxBytesPerRead="2147483647"
                              maxNameTableCharCount="2147483647" />
              <reliableSession ordered="true"  inactivityTimeout="00:01:00" enabled="false" />
              <security mode="None">
                <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"></transport>
                <message clientCredentialType="Windows" />
              </security>
            </binding>
          </netTcpBinding>
        </bindings>
        <!--描述服务-->
        <services>
          <service name="DataSync.Services.DataSyncServiceImpl" behaviorConfiguration="WFServiceBehavior">
            <host>
              <baseAddresses>
                <add baseAddress="net.tcp://localhost:808/DSServiceImpl"/>
              </baseAddresses>
            </host>
            <endpoint address=""
                      contract="DataSync.Interfaces.IDataSyncEntry"
                      binding="netTcpBinding"
                      bindingConfiguration="netTcpBindConfig" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
        <!--描述行为-->
        <behaviors>
          <serviceBehaviors>
            <behavior name="WFServiceBehavior">
              <serviceMetadata httpGetEnabled="true"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
              <dataContractSerializer maxItemsInObjectGraph="6553600"/>
            </behavior>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
        <!--
            若要在调试过程中浏览 Web 应用程序根目录,请将下面的值设置为 True。
            在部署之前将该值设置为 False 可避免泄露 Web 应用程序文件夹信息。
          -->
        <directoryBrowse enabled="true"/>
      </system.webServer>
    
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
    
    </configuration>

    S4.2客户端模板

        替换Address(指定寄宿的地址,如****/***.svc,而不是上文的DSServiceImpl);

        替换Contract(服务接口全名)

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <system.serviceModel>
            <bindings>
                <netTcpBinding>
                    <binding name="NetTcpBinding_IDataSyncEntry">
                        <security mode="None" />
                    </binding>
                </netTcpBinding>
            </bindings>
            <client>
                <endpoint address="net.tcp://75wojoax/WcfWays/DataSyncServiceImpl.svc"
                    binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IDataSyncEntry"
                    contract="Remote.IDataSyncEntry" name="NetTcpBinding_IDataSyncEntry" />
            </client>
        </system.serviceModel>
    </configuration>

    问题

    P1 需重启IIS

    问题描述:未能从程序集“System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中加载类型“System.ServiceModel.Activation.HttpModule”。

    解决办法(执行以下命令,以重启IIS):

    如果安装了 .NET Framework 4,随后启用了 .NET Framework 3.5 WCF HTTP 激活,则会发生此错误。若要解决该问题,请在 Visual Studio 2010 命令提示符下运行下面的命令行: aspnet_regiis.exe -i -enable 参见:http://msdn.microsoft.com/zh-cn/library/aa751852.aspx

    P2 需匹配的协议

    问题描述:找不到具有绑定 NetTcpBinding 的终结点的与方案 net.tcp 匹配的基址。注册的基址方案是 [http]。

    解决方案:确保服务端和客户端均使用NetTcpBinding协议。

    参考:http://www.cnblogs.com/liulun/archive/2011/11/25/2263873.html

     

    P3需匹配的协议

    问题描述:无法调度消息,因为终结点地址“net.tcp://localhost/DataSyncServiceImpl.svc”上的服务对该地址的协议不可用。

    解决方案:

    1)确保服务端和客户端均使用NetTcpBinding协议;

    2)如果服务端使用了安全配置,如

    <security mode="None">
      <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"></transport>
      <message clientCredentialType="Windows" />
    </security>

    则,客户端也需要使用同类的协议,如

    <bindings>
        <netTcpBinding>
            <binding name="NetTcpBinding_IDataSyncEntry">
                <security mode="None" />
            </binding>
        </netTcpBinding>
    </bindings>

    或者代码中

    var binding = new NetTcpBinding();
    binding.Security = new NetTcpSecurity()
    {
        Mode = SecurityMode.None
    };

     

    P4 契约返回DataTable

    问题描述:使用DataTable作为返回值

    解决方案

    1) 网上传说——使用命名的DataTable,即为DataTable的TableName赋一个名称(试了一下,不行);

    2) 传递DataSet可以。

    public System.Data.DataSet TestDataTable()
    {
        DataTable dt = new DataTable("result");
        dt.TableName = "navigateData";
        dt.Columns.Add("Name",typeof(string));
        var dr = dt.NewRow();
        dr["Name"] = "pz";
        dt.Rows.Add(dr);
    
        dr = dt.NewRow();
        dr["Name"] = "pz2";
        dt.Rows.Add(dr);
    
        var ds = new DataSet();
        ds.Tables.Add(dt);
    
        return ds;
    }

     

    P5 使用Channel Factory

    问题描述:客户端可以直接“引用服务”以生成***Client,但是,这不利于修改。

    修改了接口之后,没有办法及时通知到客户端,除了“更新服务饮引用”之外。

    解决方案:客户端引用服务接口,并使用Channel Factory进行解耦,则客户端只依赖接口。

    public static DataSync.Interfaces.IDataSyncEntry CreateDataSyncEntryServices()
    {
        EndpointAddress addr = new EndpointAddress("net.tcp://75wojoax/WcfWays/DataSyncServiceImpl.svc");
        var binding = new NetTcpBinding();
        binding.Security = new NetTcpSecurity()
        {
            Mode = SecurityMode.None
        };
        var channel = new ChannelFactory<DataSync.Interfaces.IDataSyncEntry>(binding, addr);
        var service = channel.CreateChannel();
        return service;
    }
  • 相关阅读:
    Struts2框架的学习遇到的问题1
    博客开通第100天
    RTK(Real Time Kinematic)实时动态差分定位技术
    HSRP 协议/ VRRP 协议(热备份路由协议)
    PKI 公钥基础设施
    路由器的工作原理
    VLAN基础知识
    Linux系统的 粘滞位、sgid和suid
    Kali Linux三步安装中文输入法(极简)
    ACL 包过滤技术
  • 原文地址:https://www.cnblogs.com/pengzhen/p/3792823.html
Copyright © 2011-2022 走看看