双方向通信のためのインターフェース設計
namespace SOA.WCF.Contract
{
[ServiceContract(CallbackContract = typeof(ISumResultHandler))]
public interface IArithmeticService
{
[OperationContract(IsOneWay = true)]
void ExecuteAddition(int operandA, int operandB);
}
}
コールバック契約の定義namespace SOA.WCF.Contract
{
public interface ISumResultHandler
{
[OperationContract(IsOneWay = true)]
void NotifyResult(int leftValue, int rightValue, int calculatedTotal);
}
}
サービス実装ロジックnamespace SOA.WCF.Service
{
public class MathOperationService : IArithmeticService
{
public void ExecuteAddition(int operandA, int operandB)
{
int total = operandA + operandB;
var callbackChannel = OperationContext.Current.GetCallbackChannel<ISumResultHandler>();
callbackChannel.NotifyResult(operandA, operandB, total);
}
}
}
ネットワーク構成設定<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ArithmeticBehavior">
<serviceDebug includeExceptionDetailInFaults="false"/>
<serviceMetadata httpGetEnabled="false"/>
<serviceThrottling maxConcurrentCalls="500" maxConcurrentInstances="500"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="secureTcpBinding">
<security mode="Transport">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="SOA.WCF.Service.MathOperationService" behaviorConfiguration="ArithmeticBehavior">
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8080/MathService"/>
</baseAddresses>
</host>
<endpoint address="" binding="netTcpBinding" bindingConfiguration="secureTcpBinding" contract="SOA.WCF.Contract.IArithmeticService"/>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
</configuration>
サービス起動処理public static void InitializeHosts()
{
var serviceHosts = new[]
{
new ServiceHost(typeof(MathOperationService))
};
foreach (var host in serviceHosts)
{
host.Opened += (s, e) => Console.WriteLine($"サービスホスト開始: {host.BaseAddresses[0]}");
host.Open();
}
Console.WriteLine("終了するには任意のキーを入力");
Console.ReadKey();
foreach (var host in serviceHosts)
{
host.Close();
}
}
クライアント実装class Program
{
static void Main(string[] args)
{
using (var client = new ArithmeticServiceClient(new InstanceContext(new ResultObserver())))
{
client.ExecuteAddition(7, 13);
}
Console.ReadLine();
}
}
コールバックハンドラclass ResultObserver : ISumResultHandler
{
public void NotifyResult(int leftValue, int rightValue, int calculatedTotal)
{
Console.WriteLine($"演算結果: {leftValue} + {rightValue} = {calculatedTotal}");
}
}
サービス側からのコールバック呼び出しにより、クライアント側の処理が実行され双方向通信が実現されます。