分散アプリケーション・テクノロジ(2)

S2Remoting.NETの.NET Remoting実装がほぼ完了した。
.NET Remoting(DNR版)を用いた場合以下のような感じでリモートメソッドコールが実行できるようになる。

こんな感じの普通にインタフェースと実行を分離したクラスがあって

public class Hello : IHello
{
	static Hello()
	{
	}
	public string Say() 
	{
		return "Hello";
	}
}
public interface IHello 
{
	string Say();
}

サーバー側にserver.diconとして

<component name="traceInterceptor" class="Seasar.Framework.Aop.Interceptors.TraceInterceptor"/>

<component name="componentInvoker" class="Seasar.Remoting.Common.Invoker.Impl.ComponentInvoker"/>

<component name="dnrAdapptor" class="Seasar.Dnr.Adaptor.DnrAdaptor" />

<component name="channelProperties" class="System.Collections.Specialized.ListDictionary" >
	<initMethod name="Add">
		<arg>"port"</arg>
		<arg>8000</arg> 
	</initMethod>
</component>

<component name="tcpChannel" class="System.Runtime.Remoting.Channels.Tcp.TcpChannel">
	<arg>channelProperties</arg>
	<arg>
		<component class="System.Runtime.Remoting.Channels.BinaryClientFormatterSinkProvider" />
	</arg>
	<arg>
		<component class="System.Runtime.Remoting.Channels.BinaryServerFormatterSinkProvider" />
	</arg>
</component>

<component class="Seasar.Dnr.Deployer.DnrAdaptorDeployer">
	<property name="Adaptor">dnrAdapptor</property>
	<property name="Channel">tcpChannel</property>
	<property name="WellKnownObjectMode">System.Runtime.Remoting.WellKnownObjectMode.SingleCall</property>
    <initMethod name="Deploy"/>
	<aspect>traceInterceptor</aspect>
</component>

<component name="hello" class="Seasar.Dnr.Exsample.Service.Hello">
	<aspect pointcut="Say">
		traceInterceptor
	</aspect>
</component>

クライアント側にclient.dicon

<component name="traceInterceptor" class="Seasar.Framework.Aop.Interceptors.TraceInterceptor" />

<component name="tcpChannel" class="System.Runtime.Remoting.Channels.Tcp.TcpChannel" />

<component name="testURI" class="System.Uri">
	<arg>"tcp://localhost:8000/"</arg>
</component>

<component name="dnrConnector" class="Seasar.Dnr.Connector.DnrConnector">
	<property name="baseURL">testURI</property>
	<property name="Channel">tcpChannel</property>
	<initMethod name="Lookup"/>
</component>

<component name="remoting" class="Seasar.Remoting.Common.Interceptor.RemotingInterceptor">
	<property name="Connector">dnrConnector</property>
</component>

<component name="hello" class="Seasar.Dnr.Exsample.Service.IHello">
	<aspect pointcut="Say">
		traceInterceptor
	</aspect>
	<aspect>remoting</aspect>
</component>

サーバープロセスを起動後、クライアント側のプロセスから以下のようにインタフェースのメソッドをコールすると

SingletonS2ContainerFactory.Init();
IS2Container container = SingletonS2ContainerFactory.Container;
IHello hello = (IHello) container.GetComponent(typeof(IHello));
Console.WriteLine(hello.Say());	

サーバ側のログ

DEBUG 2006-03-23 01:11:29,687 [1816] tcpチャンネルをChannelPriority=1で
ChannelUri=tcp://192.168.1.5:8000に登録しました。
DEBUG 2006-03-23 01:11:29,703 [1816] RegisterWellKnownServiceTypeとして"DNRAdaptor"を
WellKnownObjectMode=SingleCallで公開しました。
サーバーを起動しました、終了するには何かキーを押して下さい
DEBUG 2006-03-23 01:11:37,046 [2120] BEGIN Seasar.Dnr.Exsample.Service.Hello#Say()
DEBUG 2006-03-23 01:11:37,046 [2120] END Seasar.Dnr.Exsample.Service.Hello#Say() : Hello

クライアント側のログ

DEBUG 2006-03-23 01:11:36,937 [3568] BEGIN Seasar.Dnr.Exsample.Service.IHello#Say()
DEBUG 2006-03-23 01:11:37,078 [3568] END Seasar.Dnr.Exsample.Service.IHello#Say() : Hello
Hello

となって普通のインタフェースと実装のペアを非常に容易にリモートメソッドコールとして実行可能な事が分かってもらえると思う。
通信チャンネルやフォーマットシンクはdiconの指定によって切り替えられるので用件に応じて何時でも変更可能だ。後必要なのはサーバープロセスのホスティングタイプとして

  • コンソールexe等通常の実行プロセス
  • Windowsサービス
  • IISホスト

の3タイプが存在するが実際の利用ケースを想定するとログインしていなくても常時起動可能なWindowsサービスかIISホストを利用する事が多いと思われるのでデフォルトのWindowsサービステンプレートやIISホストの設定テンプレートがあった方がいいかなぁ