簡體   English   中英

自托管WCF可以連接到localhost,但不能連接遠程

[英]Self-hosted WCF can connect to localhost but can't connect remote

我有一個自托管的C#WCF .Net 4.6.1 Windows服務,該服務與另一個自托管的WCF服務進行通信。 當兩個服務都在同一台服務器上時,這工作正常。 但是,當我將服務器移至另一台計算機時,出現此錯誤:

System.ServiceModel.CommunicationException:套接字連接已中止。 這可能是由於處理您的消息時出錯,遠程主機超出了接收超時或潛在的網絡資源問題引起的。 兩台計算機上都沒有運行防火牆,使用http://192.168.1.129:6253/eTutorWcfService (在應用程序中使用net.tcp)時,我得到了響應。

客戶端app.config

<bindings>
    <basicHttpBinding>
        <binding name="BasicHttpBinding_IeTutorMessage" />
    </basicHttpBinding>
    <netTcpBinding>
        <binding name="NetTcpBinding_IeTutorMessage" />
    </netTcpBinding>
</bindings>

<client>
    <endpoint name="BasicHttpBinding_IeTutorMessage" 
        address="http://localhost:6253/eTutorWcfService" 
        binding="basicHttpBinding"
        bindingConfiguration="BasicHttpBinding_IeTutorMessage" 
        contract="eTutorServiceReference.IeTutorMessage" />
    <endpoint name="NetTcpBinding_IeTutorMessage"
        address="net.tcp://localhost:6254/eTutorWcfService"
        binding="netTcpBinding"   
        bindingConfiguration="NetTcpBinding_IeTutorMessage"
        contract="eTutorServiceReference.IeTutorMessage" >
        <identity>
            <servicePrincipalName value = ""/>
        </identity>
    </endpoint>
</client>

服務器app.config

<services>
    <service name="eTutorServer.eTutorWcfService" 
             behaviorConfiguration="myeTutorServiceBehavior">
        <host>
            <baseAddresses>
                <add baseAddress="http://localhost:6253/eTutorWcfService"/>
                <add baseAddress="net.tcp://localhost:6254/eTutorWcfService"/>
            </baseAddresses>
        </host>
        <endpoint  
            address="http://localhost:6253/eTutorWcfService" 
            binding="basicHttpBinding" 
            contract="eTutorServer.IeTutorMessage" />
        <endpoint 
            address="net.tcp://localhost:6254/eTutorWcfService" 
            binding="netTcpBinding" 
            contract="eTutorServer.IeTutorMessage" />
        <endpoint 
            address="mex" 
            binding="mexHttpBinding" 
            contract="IMetadataExchange"/>
        <endpoint 
            address="mex" 
            binding="mexTcpBinding" 
            contract="IMetadataExchange"/>
    </service>
</services>
<behaviors>
    <serviceBehaviors>
        <behavior name="myeTutorServiceBehavior">
            <serviceMetadata httpGetEnabled="true"/>
        </behavior>
    </serviceBehaviors>
</behaviors>

客戶端代碼:

EndpointAddress address = new EndpointAddress("net.tcp://" + eTutorServiceIp + ":6254/eTutorWcfService");
eTutorServiceReference.IeTutorMessageClient client = new eTutorServiceReference.IeTutorMessageClient("NetTcpBinding_IeTutorMessage", address);

try
{
    rtn = client.eTutorMessage(itm);
    client.Close();
}

當客戶端嘗試連接時,服務器的輸出窗口會顯示SecurityTokenValidationException但是我不確定該怎么辦或不確定是否有意義。 我確定這與安全性有關,但是我不知道在哪里添加內容。

首先,Nettcpbinding使用傳輸安全模式,默認情況下使用Windows憑據對客戶端進行身份驗證。
WCF引發服務器拒絕客戶端憑據的異常,WCF中NetTCP的默認安全模式是什么
然后,當我們更改服務器配置並重新托管服務時,應在調用它時重新生成客戶端代理類。 此外,由於Localhost是默認生成的,因此我們可能需要在客戶端配置中更改端點地址。

我可以忍受這一點,但真的很想知道如何在沒有安全性的情況下做到這一點。

最后,當我們將安全性更改為“無”時,客戶端不需要提供憑據即可調用服務。 我建議您重新托管服務並重新生成客戶端代理類。 我做了一個演示,希望對您有用。

服務器端(控制台應用程序)

class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost sh=new ServiceHost(typeof(MyService)))
            {
                sh.Opened += delegate
                {
                    Console.WriteLine("Service is ready......");
                };
                sh.Closed += delegate
                {
                    Console.WriteLine("Service is closed");
                };
                sh.Open();
                Console.ReadLine();
                sh.Close();

            }
        }
    }
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        string SayHello();
    }
    public class MyService : IService
    {
        public string SayHello()
        {
            return "Hello Stranger";
        }
}

App.config中

<system.serviceModel>
    <services>
      <service behaviorConfiguration="Service1Behavior" name="VM1.MyService">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="mybinding" contract="VM1.IService" >
        </endpoint>
        <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:13007/"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <bindings>
      <netTcpBinding>
        <binding name="mybinding">
          <security mode="None">
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="Service1Behavior">
          <serviceMetadata />
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

客戶端。

ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
            try
            {
                Console.WriteLine(client.SayHello());
            }
            catch (Exception)
            {

                throw;
            }

App.config中

    <system.serviceModel>
        <bindings>
            <netTcpBinding>
                <binding name="NetTcpBinding_IService">
                    <security mode="None" />
                </binding>
            </netTcpBinding>
        </bindings>
        <client>
<!--we may need to change the generated endpoint address to autual server IP address.-->
            <endpoint address="net.tcp://10.157.13.69:13007/" binding="netTcpBinding"
                bindingConfiguration="NetTcpBinding_IService" contract="ServiceReference1.IService"
                name="NetTcpBinding_IService" />
        </client>
</system.serviceModel>

請隨時告訴我是否有什么我可以幫助的。

我添加了以下代碼,它可以正常工作:

client.ClientCredentials.Windows.ClientCredential.UserName = runAs;
client.ClientCredentials.Windows.ClientCredential.Password = runAsPassword;
client.ClientCredentials.Windows.ClientCredential.Domain = runAsDomain;

但是,我想在沒有安全性的情況下執行此操作,因為它將被放置在多個服務器上,而這些服務器都沒有公共IP。 我嘗試添加到綁定中,但是在客戶端上這不是有效的節點,而在服務器上,它將停止啟動服務。 我試圖將以下代碼添加到服務器,但無法打開ServiceHost:

serviceHost.AddServiceEndpoint(typeof(eTutorWcfService), new NetTcpBinding(SecurityMode.None), "");

我可以忍受這一點,但真的很想知道如何在沒有安全性的情況下做到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM