2016-05-30 2 views
0

У меня есть собственная WCF-служба с одноранговой привязкой. Я использую DuplexChannel для получения ответов. Соединение с ServiceHost работает, но когда обратный вызов вызывается, я получаю вышеупомянутый ArgumentException, хотя я не использую TransactionFlowProperties. РеализацияWCF: ArgumentException: TransactionFlowProperty уже существует

[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;} 
} 

Мои IService:

[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 
    } 
} 

Мой обратный вызов службы:

public interface ICallbackService 
{ 

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

Исполнительное обратного вызова класса обслуживания в моем клиентском приложении:

[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 и класс пользователя находятся в отдельном клиентском приложении:

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

Это, как я начинаю ServiceHost в моем приложении сервера:

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

Если вы это поняли, лучше всего, если вы опубликуете ответ в качестве ответа и отметьте его, а не отредактируете исходное сообщение и заголовок. – lgaud

ответ

0

Я решил эту проблему с помощью NetTcpBinding. Вышеприведенный код работает сейчас.

Смежные вопросы