DOBON.NET DOBON.NETプログラミング掲示板過去ログ

VB.NETのHttpChannelを2つ使いたい

環境/言語:[VB.NET]
分類:[.NET]

2012/02/06(Mon) 11:07:50 編集(投稿者)
2012/02/06(Mon) 10:53:56 編集(投稿者)

VB.NETで、プロセス間通信の相互送受信を作っています。

アプリケーション間で値の受け渡しをするプログラムを作っています。
それでHttpChannelを使っているのですが、送信のチャネルを設定すると、受信のチャネルが設定できません。
また、その逆で、受信のチャネルを設定すると、送信のチャネルが設定できません。

同時に2つのHttpChannelを使うことは、出来ないのでしょうか?
また、出来ないとしたら、何か他の方法はないでしょうか?

教えてください。よろしくお願いします。
チャネル登録周り、実際の送受信周りはどんなコード or App.config になっていますか?
2012/02/06(Mon) 13:41:44 編集(投稿者)
2012/02/06(Mon) 13:40:12 編集(投稿者)

Hongliangさん、返信ありがとうございます。

CLASSでの宣言
Dim ch2 As New HttpChannel()
Dim WithEvents obj2 As New DATA_CLASS.DATA_Class

送信の部分
Dim ch1 As New HttpChannel()
ChannelServices.RegisterChannel(ch1, False)
RemotingConfiguration.RegisterWellKnownClientType( _
GetType(DATA_CLASS.DATA_Class), "http://localhost:9000/obj1uri")

受信の部分
ch2 = New HttpChannel(9001)
ChannelServices.RegisterChannel(ch2, False)
Dim ref1 As ObjRef = RemotingServices.Marshal(obj2, "obj1uri")
AddHandler obj2.CalledClient, AddressOf obj1_CalledClient
ch2.StartListening(Nothing)

となっています。
DATA_CLASS.DATA_Classというのは、値を引き渡すクラスです。

このコードは、クライアント側でサーバー側は、逆の記述になっています。
一つのプロセス(厳密には AppDomain)にチャネルを複数使用する場合、それぞれのチャネルには独自の名前が必要になります。
HttpChannel のコンストラクタのオーバーロードのうち Hashtable を渡すものを使って、name キーに追加しておくことで、名前を指定できます。
http://msdn.microsoft.com/ja-jp/library/dkfd3wha.aspx
簡易的には、HttpServerChannel / HttpClientChannel を使えばコンストラクタ引数に直接名前を渡すことができます。

ところで気になったのですが、ひょっとして両プロセスとも通信用クラスとして DATA_CLASS.DATA_Class を使っていませんか?
RemotingConfiguration.RegisterWellknownClientType を使ってるってことはリモートのオブジェクトを new でアクティベートしたいということのように思いますが、それだとどっちの AppDomain のインスタンスを指すのか混乱するような……?
Hongliangさん

返信ありがとうございます。

> 一つのプロセス(厳密には AppDomain)にチャネルを複数使用する場合、それぞれのチャネルには独自の名前が必要になります。
HttpChannel のコンストラクタのオーバーロードのうち Hashtable を渡すものを使って、name キーに追加しておくことで、名前を指定できます。

なるほど、そういう方法があったんですね。
早速試してみます。


> 簡易的には、HttpServerChannel / HttpClientChannel を使えばコンストラクタ引数に直接名前を渡すことができます。

使っているVB.NETのバージョンが、Microsoft Visual Vasic 2010 だったことを書き忘れていました。
なので、 使っているものがHttpChannelになっています。


> ところで気になったのですが、ひょっとして両プロセスとも通信用クラスとして DATA_CLASS.DATA_Class を使っていませんか?
> RemotingConfiguration.RegisterWellknownClientType を使ってるってことはリモートのオブジェクトを new でアクティベートしたいということのように思いますが、それだとどっちの AppDomain のインスタンスを指すのか混乱するような……?

そうだったのですか。
両方とも、DATA_CLASS.DATA_Class を使っています。
ということは、値を返すクラスは別々にしないと、混乱して動かない可能性があるってことですか?
Hongliangさん

下記のようにしてみましたが、
チャネル 'http' は既に登録されています。
というエラーになってしましました。

Dim prop1 As IDictionary
prop1 = New Hashtable()
prop1("Name") = "http1"
prop1("port") = "9000"
Dim ch1 As New HttpChannel( _
prop1, _
Nothing, _
New BinaryServerFormatterSinkProvider() _
)
ChannelServices.RegisterChannel(ch1, False)
Dim ref1 As ObjRef = RemotingServices.Marshal(obj1, "obj1uri")
AddHandler obj1.CalledClient, AddressOf obj1_CalledClient
ch1.StartListening(Nothing)

Dim prop2 As IDictionary
prop2 = New Hashtable()
prop2("Name") = "http2"
prop2("port") = "9001"
Dim ch2 As New HttpChannel( _
prop2, _
Nothing, _
New BinaryServerFormatterSinkProvider() _
)
ChannelServices.RegisterChannel(ch2, False)
RemotingConfiguration.RegisterWellKnownClientType( _
GetType(DATA_CLASS.DATA_Class), _
"http://localhost:9000/obj1uri")

エラーが出たのは、
ChannelServices.RegisterChannel(ch2, False)
の部分です。

何か、記述が違うのでしょうか?
私の先の投稿も、そこで URL を貼った MSDN のページも、"Name" というキーは書いてないです。

> 使っているVB.NETのバージョンが、Microsoft Visual Vasic 2010 だったことを書き忘れていました。
> なので、 使っているものがHttpChannelになっています。
HttpServerChannel / HttpClientChannel が使えない理由は、VB2010 だからではなく、プロジェクトの対象フレームワークが .NET Framework 4 Client Profile だからかと。

> ということは、値を返すクラスは別々にしないと、混乱して動かない可能性があるってことですか?
期待した動作にはならないかもしれません。期待通りに動くかもしれません。
試されてみてご報告いただければ、今後同様なことをやろうとする人たちに有益な情報になるでしょう。
// 最近は .NET Remoting は WCF に移行しているようなので、そういう人たちが今後現れるかどうかは微妙なところかもしれませんが。
Hongliangさん

いろいろとありがとうございます。

> 私の先の投稿も、そこで URL を貼った MSDN のページも、"Name" というキーは書いてないです。

Nameというキーでは、なかったです。
nameという名前でした。
大文字小文字で判別するんですね。


> HttpServerChannel / HttpClientChannel が使えない理由は、VB2010 だからではなく、プロジェクトの対象フレームワークが .NET Framework 4 Client Profile だからかと。

プロジェクトの対象フレームは、Hongliangさんの言う通りで、
.NET Framework 4 Client Profileでした。
対象のフレームワークを.NET Framework 4にしてやってみようと思います。


> 期待した動作にはならないかもしれません。期待通りに動くかもしれません。
> 試されてみてご報告いただければ、今後同様なことをやろうとする人たちに有益な情報になるでしょう。
> // 最近は .NET Remoting は WCF に移行しているようなので、そういう人たちが今後現れるかどうかは微妙なところかもしれませんが。

一応、先ほどやってみたのですが、期待通りには動かず、値を渡してくれませんでした。
最近は、WCFに移行しつつあるんですね。
少し調べたのですが、使い方がわからなかったので、今のままで出来ない場合は、
WCFにしようかと考えていたのですが……。
.NET Framework 4に直して、HttpServerChannel / HttpClientChannel をつかったところ、値の受け渡しに成功しました。

しかし、この先の環境上で、WCFになる可能性が出てきました……。
でも、成功したので良かったです。

Hongliangさん
ご丁寧な説明ありがとうございました。
本当に助かりました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板