それを埋めるのに苦労したのでメモ。
NET Remotingを使って、サーバーとクライアントの通信までは、サンプル通りなのですが
送ったデータは、コンソールに出力して終わり?
サーバーのデータとかイベントを起こす方法が書いていないのです。
Microsoft以外のブログなどには、違う方法でやっているのですが、どうもしっくりきません。
散々調べてわかったことは、実に単純なことでした。
静的メンバにすればよかったのです。
リモートオブジェクトはクライアントから接続されたとき、自動的に作られますが
静的メンバなら、インスタンスが作られる前に初期化しておけます。
ライフタイムが経過してインスタンスが破棄されても、静的メンバは残りますし、
一つだから、複数のクライアントとサーバーで共有できます。
サーバーの例
・クライアントからサーバーFormのイベントをコール
スレッドプールで動くので、UI操作は注意(要Invoke or BeginInvoke)
public static class CommonConstants
{
public const string Server = "myserver";
public const string Object = "mymessage";
public const string IPCURI = "ipc://" + Server + "/" + Object;
}
public class RemoteServer
{
public RemoteServer(Func<string, string> OnCalled)
{
// サーバチャネル作成
// System.Runtime.Remotingを参照設定に追加しておくこと
System.Collections.IDictionary properties = new System.Collections.Hashtable();
properties["portName"] = CommonConstants.Server;
properties["authorizedGroup"] = "Users"; // Usersグループに公開 (PowerUsers,Administratorsも含む)
IpcServerChannel serverChannel = new IpcServerChannel(properties, null);
ChannelServices.RegisterChannel(serverChannel, true);
RemoteClass.callEvent += OnCalled; // イベントを登録 (staticなのでクラス名で)
// クライアントが接続したとき、自動的にサーバー側でインスタンス作成される
RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemoteClass), CommonConstants.Object, WellKnownObjectMode.Singleton);
}
}
public class RemoteClass : MarshalByRefObject
{
// lockオブジェクト
private static object syncRoot = new Object();
/// <summary>クライアントからサーバ側を呼び出す。(注:別スレッド)</summary>
public static event Func<string, string> callEvent;
/// <summary>リモートコール</summary>
public string Call(string str)
{
lock (syncRoot) // 必要なら
{
return callEvent(str);
}
}
}
【関連する記事】