简体   繁体   English

使用双工通信对WCF进行异步调用以获取数据库更改

[英]Async call of WCF using Duplex Communication to get Database change

I am implementing and WCF Async service using WsDualHttpBinding binding for duplex communication to get database changes. 我正在使用WsDualHttpBinding绑定实现WCF异步服务,以进行双工通信以获取数据库更改。

I have implemented the Service but I dont know how to call it from Client application. 我已经实现了服务,但是我不知道如何从客户端应用程序中调用它。

Here is the code. 这是代码。

The below code is WCF Service 下面的代码是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);
    }
}

I have hosted this WCF Async Service as self hosting in a Console Application. 我已经将此WCF异步服务托管为控制台应用程序中的自助主机。

Here the hosting code 这里的托管代码

class Program { 课程计划{

    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();

    }

}

In client Application have crated a DuplexChannel factory instance Here is the Code. 在客户端应用程序中创建了一个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(); 
    }

Now My question is How I can call the 现在我的问题是我该如何称呼

  • BeginGetAllCustomer BeginGetAllCustomer
  • EndGetAllCustomer EndGetAllCustomer

Method of My service. 我的服务方式。

Help me.... A big thanks in Advance ... 帮帮我...。在此先感谢...

You need: 你需要:

  InstanceContext instanceContext = new InstanceContext(YOUR_OBJECT_IMPLMENTS_CALLBACK);

and

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

from this example: 这个例子:

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

See also microsoft example 另请参阅Microsoft示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM