2013-05-08 14 views
7

Przesyłamy strumieniowo dane z WCF za pomocą wywołań zwrotnych. WCF jest hostowany w IIS (ustawienia domyślne, tylko dodano net.tcp do protokołów).WCF przez net.tcp z trybem bezpieczeństwa none daje wyjątek

Staramy się wyłączyć zabezpieczenia na WCF, więc mam ustawić tryb zabezpieczeń „none”, zarówno na kliencie i na serwerze, ale pojawia się następujący CommunicationException:

połączenie z gniazdem został przerwany. Przyczyną może być błąd przetwarzania komunikatu lub przekroczenie limitu czasu odbioru przez host zdalny lub problem z zasobem sieciowym. Lokalny socket timeout był '00: 00: 59.8439844 '.

Wrzuciłem na śledzenie na służbie i TraceViewer daje mi następujący wyjątek (System.ServiceModel.ProtocolException):

Stream wymagane jest zabezpieczenie w http://www.w3.org/2005/08/addressing/anonymous, ale bez kontekstu zabezpieczeń został wynegocjowany. Jest to prawdopodobnie spowodowane tym, że zdalny punkt końcowy nie ma powiązania StreamSecurityBindingElement.

Program.cs Klient:

using System; 
using System.ServiceModel; 
using WcfClient.ServiceReference1; 

class Program { 
    static void Main() { 
     Callback callback = new Callback(); 
     InstanceContext context = new InstanceContext(callback); 
     Service1Client service1Client = new Service1Client(context, 
                  "NetTcpBinding_IService1"); 


     service1Client.GetData(0); 
     Console.Read(); 
     service1Client.Stop(); 
    } 
} 

internal class Callback : IService1Callback { 
    public void StreamSignalData(int[] result) { 
     foreach (int i in result) { 
      Console.WriteLine(DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss.fff") + 
           ": " + i); 
     } 
    } 
} 

Client app.config

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
    <bindings> 
     <netTcpBinding> 
     <binding name="NetTcpBinding_IService1"> 
      <security mode="None" /> 
     </binding> 
     </netTcpBinding> 
     <wsDualHttpBinding> 
     <binding name="WSDualHttpBinding_IService1"> 
      <reliableSession ordered="true" /> 
      <security mode="None" /> 
     </binding> 
     </wsDualHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="http://localhost/wcf-error/Service1.svc" 
     binding="wsDualHttpBinding" 
     bindingConfiguration="WSDualHttpBinding_IService1" 
     contract="ServiceReference1.IService1" 
     name="WSDualHttpBinding_IService1" /> 
     <endpoint address="net.tcp://localhost/wcf-error/Service1.svc" 
     binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IService1" 
     contract="ServiceReference1.IService1" name="NetTcpBinding_IService1"> 
     </endpoint> 
    </client> 
    </system.serviceModel> 
</configuration> 

WCF Service1.svc.cs

using System; 
using System.Net.Security; 
using System.ServiceModel; 
using System.Threading; 

[ServiceContract(SessionMode = SessionMode.Required, 
       CallbackContract = typeof(IStreamCallback), 
       ProtectionLevel = ProtectionLevel.None)] 
public interface IService1 { 
    [OperationContract] 
    void GetData(int value); 

    [OperationContract] 
    void Stop(); 
} 

public interface IStreamCallback { 
    [OperationContract(IsOneWay = true)] 
    void StreamSignalData(int[] result); 
} 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] 
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class Service1 : IService1 { 
    private Timer _timer; 

    private readonly IStreamCallback _callback = 
      OperationContext.Current.GetCallbackChannel<IStreamCallback>(); 
    public void GetData(int value) { 
     _timer = new Timer(StreamData, null, 0, 500); 
    } 

    public void Stop() { 
     _timer.Dispose(); 
    } 

    private void StreamData(object state) { 
     int[] randomNumbers = new int[50]; 
     Random random = new Random(); 
     for (int i = 0; i < 50; i++) { 
      randomNumbers[i] = random.Next(100); 
     } 
     _callback.StreamSignalData(randomNumbers); 
    } 
} 

WCF Web.config

<?xml version="1.0"?> 
<configuration> 
    <system.web> 
    <compilation targetFramework="4.0" debug="true"/> 
    </system.web> 
    <system.serviceModel> 
    <bindings> 
     <netTcpBinding> 
     <binding name="netTcpBinding" > 
      <security mode="None" /> 
     </binding> 
     </netTcpBinding> 
     <wsDualHttpBinding> 
     <binding name="wsDualHttpBinding"> 
      <security mode="None" /> 
     </binding> 
     </wsDualHttpBinding> 
    </bindings> 
    <protocolMapping> 
     <add scheme="http" binding="wsDualHttpBinding"/> 
    </protocolMapping> 
    <services> 
     <service name="Service"> 
     <endpoint address="" binding="wsDualHttpBinding" 
      bindingConfiguration="wsDualHttpBinding" 
      name="EndPointHTTP" contract="WcfService1.IService1"> 
      <identity> 
      <dns value="localhost" /> 
      </identity> 
     </endpoint> 
     <endpoint address="mex" binding="mexHttpBinding" name="mex" 
      contract="IMetadataExchange" /> 
     <endpoint binding="netTcpBinding" bindingConfiguration="netTcpBinding" 
      name="EndPointTCP" contract="WcfService1.IService1" /> 
     </service> 
    </services> 
    <behaviors> 
     <serviceBehaviors> 
     <behavior> 
      <serviceMetadata httpGetEnabled="true" /> 
      <serviceDebug includeExceptionDetailInFaults="true" /> 
      <useRequestHeadersForMetadataAddress /> 
      <dataContractSerializer /> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 
    </system.serviceModel> 
    <system.webServer> 
    <modules runAllManagedModulesForAllRequests="true"/> 
    </system.webServer> 
</configuration> 

jakieś pomysły co to może być? Większość haseł na google mówi, że konfiguracja na kliencie i serwerze powinna być taka sama (tzn. Brak bezpieczeństwa), ale nie mogę znaleźć błędu. Googling dla StreamSecurityBindingElement wymyślił No Good explenations ...

+0

Która strona (klient/usługa) wyświetla błąd w dzienniku? –

+0

@ PetarVučetin Usługa. – ahoibakk

+0

@ PetarVučetin Próbowałem umieszczać śledzenie na kliencie, ale to nie daje mi żadnych innych informacji niż wyjątek, który już rzuca. – ahoibakk

Odpowiedz

1

nie mogłem replikować problemu, ale mam taką samą konfigurację i kilka rzeczy zauważyłem:

Tworzenie namesapace w WCF Service1.svc.cs.

namespace WcfService1 
    { 
     [ServiceContract(SessionMode = SessionMode.Required, 
      CallbackContract = typeof (IStreamCallback), 
      ProtectionLevel = ProtectionLevel.None)] 
     public interface IService1 
     { 
     ..... 
     [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] 
     [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
     public 

    class Service1 : IService1 
    { 

<service name="Service"> powinny być <service name="WcfService1.Service1">. Nazwa usługi jest pełna Typ usługi.

sekcja

Usługi w config:

<services> 
    <service name="WcfService1.Service1"> 
     <endpoint address="" binding="wsDualHttpBinding" 
      bindingConfiguration="wsDualHttpBinding" 
      name="EndPointHTTP" contract="WcfService1.IService1"> 
      <identity> 
       <dns value="localhost" /> 
      </identity> 
     </endpoint> 
     <endpoint address="mex" binding="mexHttpBinding" name="mex" 
      contract="IMetadataExchange" /> 
     <endpoint binding="netTcpBinding" bindingConfiguration="netTcpBinding" 
      name="EndPointTCP" contract="WcfService1.IService1" /> 
    </service> 
</services> 

WCF Service1.svc.cs

using System; 
using System.Net.Security; 
using System.ServiceModel; 
using System.Threading; 

namespace WcfService1 
{ 
    [ServiceContract(SessionMode = SessionMode.Required, 
     CallbackContract = typeof (IStreamCallback), 
     ProtectionLevel = ProtectionLevel.None)] 
    public interface IService1 
    { 
     [OperationContract] 
     void GetData(int value); 

     [OperationContract] 
     void Stop(); 
    } 

    public interface IStreamCallback 
    { 
     [OperationContract(IsOneWay = true)] 
     void StreamSignalData(int[] result); 
    } 

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] 
    [CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] 
    public class Service1 : IService1 
    { 
     private Timer _timer; 

     private readonly IStreamCallback _callback = 
      OperationContext.Current.GetCallbackChannel<IStreamCallback>(); 

     public void GetData(int value) 
     { 
      _timer = new Timer(StreamData, null, 0, 500); 
     } 

     public void Stop() 
     { 
      _timer.Dispose(); 
     } 

     private void StreamData(object state) 
     { 
      int[] randomNumbers = new int[50]; 
      Random random = new Random(); 
      for (int i = 0; i < 50; i++) 
      { 
       randomNumbers[i] = random.Next(100); 
      } 
      _callback.StreamSignalData(randomNumbers); 
     } 
    } 
} 

oddzwaniania

Upewnij się, że uchwyt _callback.StreamSignalData (randomNumbers); gdy klient się rozłączy. Otrzymasz wyjątek komunikacji.

+0

Dzięki za twój wkład, ale niestety to nie rozwiązało mojego problemu. – ahoibakk

+0

To dziwne. No cóż - zdobyłem znaczek "działa na moim komputerze": –

Powiązane problemy