2016-05-30 11 views
0

Ich habe einen selbst gehosteten WCF-Dienst mit einer Peer-to-Peer-Bindung. Ich verwende einen Duplexkanal, um Antworten zu erhalten. Die Verbindung mit dem ServiceHost funktioniert, aber wenn der Callback aufgerufen wird, erhalte ich das oben erwähnte ArgumentException, obwohl ich keine TransactionFlowProperties verwende.WCF: ArgumentException: TransactionFlowProperty ist bereits vorhanden

[ServiceContract(SessionMode = SessionMode.Allowed, CallbackContract = typeof(ICallbackService))] 
public interface IService 
{ 
    [OperationContract(IsOneWay = true)] 
    void Login(string email, string password); 

    [OperationContract(IsOneWay = true)] 
    void Logout(int userId); 
} 

[DataContract] 
public class User 
{ 
    [DataMember] 
    public string Email {get; set;} 

    [DataContract] 
    public string Password {get; set;} 
} 

Mein IService Implementierung:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)] 
public class Service : IService 
{ 
    private static Dictionary<ICallbackService, ICallbackService> pair = new Dictionary<ICallbackService, ICallbackService>(); 
    private static Dictionary<string, ICallbackService> clients = new Dictionary<string, ICallbackService>(); 

    private ICallbackService callback; 

    public Service(){} 

    public void Login(string email, string password) 
    { 
    // User user = getAllUsers().Find(u => u.Email.ToLower() == email.ToLower() && u.Password == password); 
      User user = new User(){Email = email, Password = password}; //for testing purposes 
     callback = OperationContext.Current.GetCallbackChannel<ICallbackService>(); 

     if (user != null) 
     { 
      Console.WriteLine("user : " + email + " has logged in"); 
      clients.Add(email, callback); 
      callback.Authenticate(true); 
     } 
     else callback.Authenticate(false); 
    } 

    public void Logout(int userId) 
    { 
     //TODO 
    } 
} 

My Callback-Service:

public interface ICallbackService 
{ 

    [OperationContract(IsOneWay = true)] 
    void Authenticate(bool authenticated); 
} 

Die Umsetzung Callback-Service-Klasse in meiner Client-Anwendung:

[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Single, UseSynchronizationContext = false)] 
public class Client : Service.ICallbackService, 
{ 
    public bool Authentication { get; internal set; } 

    public Client() 
    { 
    } 

    public void Authenticate(bool authenticated) 
    { 
     Console.WriteLine("authentication : " + authenticated); 
     Authentication = authenticated; 
    } 

}

Proxy-Klasse und Benutzerklasse ist in einer separaten Client-Anwendung:

public class Proxy : IService 
{ 
    public Proxy(InstanceContext context) 
    { 
     init(context);   
    } 

    private void init(InstanceContext context) 
    { 
     NetTcpBinding binding = new NetTcpBinding(); 
     binding.Security.Mode = SecurityMode.None; 
     binding.Security.Mode = SecurityMode.Transport;  

     // binding.CloseTimeout = TimeSpan.FromSeconds(1); 
     // binding.OpenTimeout = TimeSpan.FromSeconds(2); 
     // binding.ReceiveTimeout = TimeSpan.FromSeconds(15); 
     // binding.SendTimeout = TimeSpan.FromSeconds(15); 

     DuplexChannelFactory<IService> channel = new DuplexChannelFactory<IService>(context, binding, new EndpointAddress("net.tcp://localhost:4242")); 
     service = channel.CreateChannel(); 
    } 

    public void Login(string email, string password) 
    { 
     service.Login(email, password); 
    } 

    public void Logout(int id) 
    { 
     service.Logout(id); 
    } 
} 

public class User 
{ 
    Client client; 
    IService service; 

    public User() 
    { 
     client = new Client(); 
     InstanceContext context = new InstanceContext(client); 
     service = new Proxy(context); 
    } 

    public void Login(string email, string password) 
    { 
     service.Login(email, password); 
     bool valid = client.Authentication; 
     if(valid) Console.WriteLine("Login successful"); 
    } 
} 

Dies ist, wie ich meine Servicehost in meiner Server-Anwendung starten:

public class Server 
{ 

    public static void Main(string[] args) 
    { 
     Service service = new Service(); 
     ServiceHost host = host = new ServiceHost(service, new Uri("net.tcp://localhost:4242")); 
     host.Open(); 

     Console.WriteLine("opened server ..."); 
     Console.ReadLine(); 
    } 
} 
+0

Wenn Sie es herausgefunden haben, ist es am besten, wenn Sie die Antwort als Antwort posten und sie als beantwortet markieren, anstatt den ursprünglichen Beitrag und Titel zu bearbeiten. – lgaud

Antwort

0

ich dieses Problem eines NetTcpBinding Verwendung gelöst. Der obige Code funktioniert jetzt.

Verwandte Themen