2015年03月16日

.NET Remotingによるプロセス間通信

C#でプロセス間通信をやろうとしたら、MSDNのサンプルには肝心なところが抜けていて
それを埋めるのに苦労したのでメモ。

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);
}
}
}


ブックマークボタン
posted by 知命 at 00:00| Comment(0) | Programming | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

検索する
投稿する
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。