Самостоятельно размещенный WCF может подключаться к локальному хосту, но не может подключаться удаленно. - PullRequest
0 голосов
/ 01 января 2019

У меня есть собственная служба Windows C # WCF .Net 4.6.1, которая взаимодействует с другой собственной службой 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, но яЯ не уверен, что делать с этим или если это означает что-то важноеЯ уверен, что это как-то связано с безопасностью, но я не знаю, что и куда добавить.

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Во-первых, Nettcpbinding использует режим безопасности транспорта и аутентифицирует клиента с учетными данными Windows по умолчанию.
WCF выдает исключение, что сервер отклонил учетные данные клиента, что является режимом безопасности по умолчанию для NetTCP в WCF
Затем, когда мы меняем конфигурацию сервера и повторно размещаем сервис, мы должны заново генерировать прокси-класс клиента при его вызове.кроме того, нам может потребоваться изменить адрес конечной точки в конфигурации клиента, поскольку по умолчанию генерируется Localhost.

Я могу с этим смириться, но очень хотел бы знать, как это сделать без защиты.

Наконец, когда мы изменили защиту на None, клиенту не нужно предоставлять учетные данные для вызова службы.Я предлагаю вам повторно разместить службу и заново сгенерировать клиентский прокси-класс.Я сделал демо, желаю, чтобы это было полезно для вас.

Серверная часть (консольное приложение)

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>

Не стесняйтесь, дайте мне знатьесли есть что-нибудь, с чем я могу помочь.

0 голосов
/ 02 января 2019

Я добавил следующий код, и он работает:

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), "");

Я могу с этим смириться, но очень хотел бы знать, как это сделать без защиты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...