0

I am implementing and WCF Async service using WsDualHttpBinding binding for duplex communication to get database changes.

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

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

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.

  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
  • EndGetAllCustomer

Method of My service.

Help me.... A big thanks in Advance ...

Ck.Nitin
  • 161
  • 1
  • 6

1 Answers1

1

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

evgenyl
  • 7,837
  • 2
  • 27
  • 32