2013-03-25 66 views
0

我正在實現和WCF異步服務使用WsDualHttpBinding綁定雙工通信來獲取數據庫更改。異步調用WCF使用雙工通信獲取數據庫更改

我已經實施了服務,但我不知道如何從客戶端應用程序調用它。

這是代碼。

下面的代碼是WCF服務

[ServiceContract()] 
public interface ICustomerService 
{ 
     [OperationContract(IsOneWay = true)] 
     void GetAllCustomer(); 
} 


public interface ICustomerServiceCallback 
{ 
    [OperationContract(IsOneWay = true)] 
    void Callback(Customer[] customers); 
} 


[ServiceContract(Name = "ICustomerService", 
    CallbackContract = typeof(CustomerServiceLibrary.ICustomerServiceCallback), 
    SessionMode = SessionMode.Required)] 
public interface ICustomerServiceAsync 
{ 
    [OperationContract(AsyncPattern = true)] 
    IAsyncResult BeginGetAllCustomer(AsyncCallback callback, object asyncState); 
    void EndGetAllCustomer(IAsyncResult result); 
} 

[DataContract] 
public class Customer 
{ 
    [DataMember] 
    public string Name 
    { 
     get; 
     set; 
    } 


} 

}

public class CustomerService :ICustomerService,IDisposable 
{ 

    List<Customer> Customers = null; 
    ICustomerServiceCallback callback; 
    Customer customer = null; 

    string constr = "Data Source=.;Initial Catalog=WPFCache;Persist Security Info=True;User ID=sa;Password=Password$2"; 

    public CustomerService() 
    { 
     callback = OperationContext.Current.GetCallbackChannel<ICustomerServiceCallback>(); 
     SqlDependency.Start(constr); 
    } 


    public void GetAllCustomer() 
    { 

      using (SqlConnection con = new SqlConnection(constr)) 
      { 
       using (SqlCommand cmd = new SqlCommand()) 
       { 
        con.Open(); 

        cmd.Connection = con; 
        cmd.CommandText = "GetHero"; 
        cmd.CommandType = CommandType.StoredProcedure; 

        cmd.Notification = null; 

        // Create the associated SqlDependency 
        SqlDependency dep = new SqlDependency(cmd); 
        dep.OnChange += new OnChangeEventHandler(dep_OnChange); 

        SqlDataReader dr = cmd.ExecuteReader(); 
        Customers = new List<Customer>(); 
        while (dr.Read()) 
        { 
         customer = new Customer(); 
         customer.Name = dr.GetString(0); 

         Customers.Add(customer); 

        } 
       } 

       callback.Callback(Customers.ToArray()); 


      } 

    } 

    void dep_OnChange(object sender, SqlNotificationEventArgs e) 
    { 
     try 
     { 

      if (e.Type == SqlNotificationType.Change) 
      { 
       GetAllCustomer(); 
      } 
     } 
     catch (Exception ex) 
     { 

      throw ex; 
     } 
    } 


    public void Dispose() 
    { 
     SqlDependency.Stop(constr); 
    } 
} 

我主持這個WCF異步服務自我託管在一個控制檯應用程序。

這裏託管代碼

類節目 {

static void Main(string[] args) 
    { 
     StartService(); 

    } 

    internal static ServiceHost myServiceHost = null; 

    internal static void StartService() 
    { 
     Uri httpbaseAddress = new Uri("http://localhost:8087/CustomerService/"); 

     Uri[] baseAdresses = { httpbaseAddress }; 

     myServiceHost = new ServiceHost(typeof(CustomerServiceLibrary.CustomerService)); 
     myServiceHost.AddServiceEndpoint(typeof(CustomerServiceLibrary.ICustomerService), new WSDualHttpBinding(), httpbaseAddress); 

     ServiceDescription serviceDesciption = myServiceHost.Description; 

     foreach (ServiceEndpoint endpoint in serviceDesciption.Endpoints) 
     { 

      Console.WriteLine("Endpoint - address: {0}", endpoint.Address); 
      Console.WriteLine("   - binding name:\t\t{0}", endpoint.Binding.Name); 
      Console.WriteLine("   - contract name:\t\t{0}", endpoint.Contract.Name); 
      Console.WriteLine(); 

     } 

     myServiceHost.Open(); 
     Console.WriteLine("Press enter to stop."); 
     Console.ReadKey(); 

     if (myServiceHost.State != CommunicationState.Closed) 
      myServiceHost.Close(); 

    } 

} 

在客戶端應用程序已裝箱一個DuplexChannel工廠實例 這裏是代碼。

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     EndpointAddress address = new EndpointAddress(new Uri("http://localhost:8087/CustomerService")); 
     WSDualHttpBinding wsDualBinding = new WSDualHttpBinding(); 
     DuplexChannelFactory<ICustomerServiceAsync> client = new DuplexChannelFactory<ICustomerServiceAsync>(new InstanceContext(this), wsDualBinding, address); 
     App.channel = client.CreateChannel(); 
} 

現在我的問題是我怎麼能說我的服務

  • BeginGetAllCustomer
  • EndGetAllCustomer

方法。

幫助我....提前非常感謝......

回答

1

您需要:

InstanceContext instanceContext = new InstanceContext(YOUR_OBJECT_IMPLMENTS_CALLBACK); 

using (App.channel as IDisposable) 
{ 
    App.channel.YOUR_METHOD_HERE(); 
} 

this例如:

endPointAddr = "net.tcp://" + textBox2.Text + ":8000/FIXMarketDataHub"; 
       NetTcpBinding tcpBinding = new NetTcpBinding(); 
       tcpBinding.TransactionFlow = false; 
       tcpBinding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.EncryptAndSign; 
       tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Windows; 
       tcpBinding.Security.Mode = SecurityMode.None; 

       EndpointAddress endpointAddress = new EndpointAddress(endPointAddr); 

       Append("Attempt to connect to: " + endPointAddr); 

       InstanceContext instanceContext = new InstanceContext(??); 

       IMarketDataPub proxy = DuplexChannelFactory<IMarketDataPub>.CreateChannel(instanceContext,tcpBinding, endpointAddress); 

       using (proxy as IDisposable) 
       { 
        proxy.Subscribe(); 
        Append("Subscribing to market data");      
       } 

另請參閱microsoft example