wcf
今になってようやくWCFをいじってみる。
最初の目標は
・configファイルは使わない(プログラムで全てやりきる)
・プロキシ生成ツールも使わない(プログラムで全てやりきる)
・RemotingのCAO相当の機能も試す
この三つ。
できたコードはコレ。
Service。参照設定でSystem.ServiceModelを参照
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace Service { [ServiceContract] public interface IStatelessService { [OperationContract] string GetDatetime(string data); } public class StatelessServiceImpl :IStatelessService { private string data_; public string GetDatetime(string data) { data_ += data; Console.WriteLine(data_); Console.WriteLine("StatelessServiceImpl GetDatetime called"); return DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"); } } [ServiceContract(SessionMode=SessionMode.Required)] public interface IstatefulService { [OperationContract] void SetName(string name); [OperationContract] string GetName(); } [ServiceBehavior( ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.PerSession)] public class statefulServiceImpl :IstatefulService,IDisposable { private string name_; public void SetName(string name) { Console.WriteLine("statefulServiceImpl SetName called"); name_ = name; } public string GetName() { Console.WriteLine("statefulServiceImpl GetName called"); return name_; } public void Dispose() { throw new NotImplementedException(); } } }
Server。参照設定でSystem.ServiceModelを参照。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel.Description; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; namespace Server { class Program { static void Main(string[] args) { try { Uri statelessSvcEndpoint = new Uri("net.tcp://localhost:8000/stateless"); ServiceHost statelessSvcHost = new ServiceHost(typeof(Service.StatelessServiceImpl), statelessSvcEndpoint); statelessSvcHost.AddServiceEndpoint( typeof(Service.IStatelessService), new NetTcpBinding(), "StatelessService.svc"); //ServiceMetadataBehavior smb = new ServiceMetadataBehavior(); //smb.HttpGetEnabled = true; //statelessSvcHost.Description.Behaviors.Add(smb); statelessSvcHost.Open(); Console.WriteLine("start stateless svc"); statelessSvcHost.ChannelDispatchers.ToList().ForEach( c => Console.WriteLine(c.Listener.Uri)); Uri statefulSvcEndpoint = new Uri("net.tcp://localhost:8000/stateful"); ServiceHost statefulSvcHost = new ServiceHost(typeof(Service.statefulServiceImpl), statefulSvcEndpoint); statefulSvcHost.AddServiceEndpoint( typeof(Service.IstatefulService), new NetTcpBinding(), "StatefulService.svc"); statefulSvcHost.Open(); Console.WriteLine("start stateful svc"); statefulSvcHost.ChannelDispatchers.ToList().ForEach( c => Console.WriteLine(c.Listener.Uri)); } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.ReadLine(); } } }
Client。参照設定でSystem.ServiceModelを参照。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ServiceModel; namespace Client { class Program { static void Main(string[] args) { try { Console.WriteLine("stateless service呼び出し"); EndpointAddress statelessSvcEp = new EndpointAddress("net.tcp://localhost:8000/stateless/StatelessService.svc"); ChannelFactory statelessSvcFac = new ChannelFactory(new NetTcpBinding(), statelessSvcEp); Service.IStatelessService statelessSvc = statelessSvcFac.CreateChannel(); Console.WriteLine(statelessSvc.GetDatetime(DateTime.Now.ToString("HH:mm:ss"))); Console.WriteLine(statelessSvc.GetDatetime(DateTime.Now.ToString("HH:mm:ss"))); Console.WriteLine("stateful service呼び出し"); EndpointAddress statefulSvcEp = new EndpointAddress("net.tcp://localhost:8000/stateful/StatefulService.svc"); ChannelFactory statefulSvcFac = new ChannelFactory(new NetTcpBinding(), statefulSvcEp); Service.IstatefulService statefulSvc = statefulSvcFac.CreateChannel(); statefulSvc.SetName("太郎"); Console.WriteLine(statefulSvc.GetName()); } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.ReadLine(); } } }
デフォルトではSingletonみたい。
RemotingのInitializeLifetimeServiceでreturn nullしてたみたいに、何かしないとインスタンスがどこかで消えちゃうかもしれない。
(調べてない)
RemotingだとChannelも公開するタイプもプロセス毎(ホントはAppDomain)になっちゃうのがイヤだったけど、WCFではそういうことはなさそう。
コレいいな・・・。