いいえ、バインディングは、契約を尊重できることを検証します。コントラクトがデュプレックスコントラクトである(つまり、を指定している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();
}
}