以前、.NET で Google 製シリアライズツール ProtocolBuffers が使えるようになるライブラリ protobuf-net を紹介しました。
この protobuf-net は WCF 向けの機能も提供していて、ProtocolBuffers でシリアル化したデータを WCF の通信で使うことができます。使い方を簡単に説明すると、ProtoBehaviorAttribute を OperationContractAttribute と一緒に指定してやるだけ。
using System; using System.ServiceModel; using ProtoBuf; using ProtoBuf.ServiceModel; namespace WcfProtoBufSample { // ProtocolBuffers でシリアル化するので // DataContract や DataMember ではなく、 // 専用の属性を指定する [ProtoContract] public class Person { [ProtoMember(1)] public string Name { get; set; } [ProtoMember(2)] public int Age { get; set; } } [ServiceContract] public interface IPersonService { // ProtocolBuffers を使ってシリアル化するオペレーションに // ProtoBehaviorAttribute を付ける [ProtoBehavior] [OperationContract] void Echo(Person person); } public class PersonService : IPersonService { public void Echo(Person person) { // ProtocolBuffers を使ってシリアル化されたか確認するために // メッセージの中身も出力 Console.WriteLine(OperationContext.Current.RequestContext.RequestMessage); Console.WriteLine("{0}({1})", person.Name, person.Age); } } class Program { static void Main(string[] args) { string address = "net.pipe://localhost/Person"; ServiceHost host = new ServiceHost(typeof(PersonService)); host.AddServiceEndpoint(typeof(IPersonService), new NetNamedPipeBinding(), address); host.Open(); IPersonService client = ChannelFactory<IPersonService>.CreateChannel( new NetNamedPipeBinding(), new EndpointAddress(address)); client.Echo(new Person() { Name = "桂馬", Age = 17 }); Console.ReadLine(); ((IClientChannel)client).Close(); host.Close(); } } }
ProtocolBuffers を使ってシリアル化されたか確認するために、Message の内容を出力しています。実行結果は下図の通り。
protobuf-net 配布サイトのドキュメントによると、DataContractSerializer や XmlSerializer よりも protobuf-net の方が、高速にシリアル化・逆シリアル化できるし、サイズも小さいそう。通信速度を追い求めるなら、WCF + ProtocolBuffers の組み合わせを検討するのもいいかもしれませんね。