1

webHttpBindingエンドポイント(Javaクライアントの場合)とnetTcpBindingエンドポイント(.NETクライアントの場合)を持つWCFサービスを作成しようとしています。

エンドポイントでは、netTcpBindingイベントのアラートを受け取るためにコールバックを使用できるようにしたいのですが、これを構成しようとすると、サービスにwebHttpBindingコールバックをサポートしないエンドポイントもあるため、WCFが文句を言います。

あるエンドポイントでコールバックを利用するが、別のエンドポイントでは利用しない方法はありますか?

4

1 に答える 1

4

いいえ、バインディングは、契約を尊重できることを検証します。コントラクトがデュプレックスコントラクトである(つまり、を指定しているCallbackContract)が、バインディングがデュプレックスを実行できない場合、検証中にスローされます。

できることは、エンドポイントによって使用される基本コントラクトと、webHttpBindingエンドポイントによって使用される最初のコントラクトから派生した別のコントラクト(今回はデュプレックスコントラクト)を用意することnetTcpBindingです。

以下のコードは、そのような契約の取り決めの例を示しています。

public class StackOverflow_7341463
{
    [ServiceContract]
    public interface ICalc
    {
        [OperationContract, WebGet]
        int Add(int x, int y);
        [OperationContract, WebGet]
        int Subtract(int x, int y);
        [OperationContract, WebGet]
        int Multiply(int x, int y);
        [OperationContract, WebGet]
        int Divide(int x, int y);
    }
    [ServiceContract(CallbackContract = typeof(ICalcNotifications))]
    public interface INotifyingCalc : ICalc
    {
        [OperationContract]
        void Connect();
        [OperationContract]
        void Disconnect();
    }
    [ServiceContract]
    public interface ICalcNotifications
    {
        [OperationContract(IsOneWay = true)]
        void OperationPerformed(string text);
    }
    public class Service : INotifyingCalc
    {
        static List<ICalcNotifications> clients = new List<ICalcNotifications>();

        #region ICalc Members

        public int Add(int x, int y)
        {
            this.NotifyOperation("Add", x, y);
            return x + y;
        }

        public int Subtract(int x, int y)
        {
            this.NotifyOperation("Subtract", x, y);
            return x - y;
        }

        public int Multiply(int x, int y)
        {
            this.NotifyOperation("Multiply", x, y);
            return x * y;
        }

        public int Divide(int x, int y)
        {
            this.NotifyOperation("Divide", x, y);
            return x / y;
        }

        #endregion

        #region INotifyingCalc Members

        public void Connect()
        {
            var callback = OperationContext.Current.GetCallbackChannel<ICalcNotifications>();
            clients.Add(callback);
        }

        public void Disconnect()
        {
            var callback = OperationContext.Current.GetCallbackChannel<ICalcNotifications>();
            clients.Remove(callback);
        }

        #endregion

        private void NotifyOperation(string operationName, int x, int y)
        {
            foreach (var client in clients)
            {
                client.OperationPerformed(string.Format("{0}({1}, {2})", operationName, x, y));
            }
        }
    }
    class MyCallback : ICalcNotifications
    {
        public void OperationPerformed(string text)
        {
            Console.WriteLine("Operation performed: {0}", text);
        }
    }
    public static void Test()
    {
        string baseAddressTcp = "net.tcp://" + Environment.MachineName + ":8008/Service";
        string baseAddressHttp = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddressHttp), new Uri(baseAddressTcp));
        host.AddServiceEndpoint(typeof(ICalc), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
        host.AddServiceEndpoint(typeof(INotifyingCalc), new NetTcpBinding(SecurityMode.None), "");
        host.Open();
        Console.WriteLine("Host opened");

        var factory = new DuplexChannelFactory<INotifyingCalc>(
            new InstanceContext(new MyCallback()),
            new NetTcpBinding(SecurityMode.None),
            new EndpointAddress(baseAddressTcp));
        var proxy = factory.CreateChannel();
        proxy.Connect();
        Console.WriteLine("Proxy connected");

        Console.WriteLine(new WebClient().DownloadString(baseAddressHttp + "/Add?x=4&y=7"));
        Console.WriteLine(new WebClient().DownloadString(baseAddressHttp + "/Multiply?x=44&y=57"));
        Console.WriteLine(new WebClient().DownloadString(baseAddressHttp + "/Divide?x=432&y=16"));

        proxy.Disconnect();

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();

        ((IClientChannel)proxy).Close();
        factory.Close();
        host.Close();
    }
}
于 2011-09-07T23:08:16.277 に答える