C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[13]: IPCを使用してサーバーからの戻り値を取りたい


(過去ログ 136 を表示中)

[トピック内 21 記事 (1 - 20 表示)]  << 0 | 1 >>

■80210 / inTopicNo.1)  IPCを使用してサーバーからの戻り値を取りたい
  
□投稿者/ やんまー (20回)-(2016/06/23(Thu) 01:51:36)

分類:[VB.NET/VB2005 以降] 

サーバーで処理をさせて、クライアントで結果を受ける、という動作をさせたいです。

サーバーと言っても同一コンピュータ上でいいので、IPCというのでやるのが良さそうだと思いました。

以下を参考にして、一応動作させることが出来ました。

1) http://drinking-masa.cocolog-nifty.com/blog/2010/10/vbnetipcnet-rem.html
2) http://tech.ewdev.info/2014/05/1846/

ところが
1)ではサーバーはほとんど何もしておらず、接続するだけで、送った値が帰ってくるというよりも
単にクラスライブラリ上で受けて返しているだけ、ですね。

2)ではクライアントから送った値をサーバーに反映はしているものの、クライアントには何も反応しないサンプルでした。


さて、「クライアントで結果を受ける」ということを実装しようとして手が止まってしまいました。
これはどのようにすればよいのでしょうか・・・


もう少しやりたいことを具体的に申しますと、

クライアントからURLをサーバーに送る

サーバーでWEBアクセスし、ソースを得る

クライアントで、ソースを戻り値として受ける


と、こんな感じです。
サーバーでファイルに書き出してしまえば・・・と思いましたが、これだとあまりプロセス間通信を使う意味が無いような気がしました。

よろしくお願い致します。

引用返信 編集キー/
■80211 / inTopicNo.2)  Re[1]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ 774RR (417回)-(2016/06/23(Thu) 08:41:18)
No79914 の続きと言うことで

クライアント側の実装がしたいのだよね?
# サーバ側の処理はここでは考えない

微妙に状況がわからないのだけど WebClient を使わない理由はなぜだろう。
クライアント→サーバにリクエストを送り、サーバ→クライアントへの返信を受け取る処理を
メッセージループなしで行うには System.Net.WebClient が最短手順だと思うのだけど。

MSDN サンプルのほぼそのままだけど、コンソールアプリケーションにて
System.Net.WebClient w = new System.Net.WebClient();
byte[] webcontents = w.DownloadData("http://localhost/");
Console.WriteLine(Encoding.ASCII.GetString(webcontents));
だけで当方期待通りの動きを確認済み。

native なら curl あたりを提案するとこだけど、たぶん curl にできることなら WebClient でもできる。

引用返信 編集キー/
■80212 / inTopicNo.3)  Re[2]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ やんまー (21回)-(2016/06/23(Thu) 10:17:31)
774RR さん

ご回答有り難うございます。
説明すれば、教えていただけるということでしょうか・・・

このことを説明しだすと論点がそれていってしまうことが不安です。
あくまでも、サーバー側からの応答を取りたいということです。。。
それを踏まえたうえで・・・

> WebClient を使わない理由

実際には使っています。というかWebClientも使っています。
ところが、WebClient を連続で使っていると応答が戻ってこ無いことがあったのです。
そこでWebbrowserでNavigateしたところスルッとレスポンスが取れたのです。
なのでWebClientでタイムアウトになった場合はWebbrowserというようにしました。
ところがWebbrowserにはメモリを開放できないというバグが有ります。
そのため、この部分だけ切り離して、別プロセスにし1回のアクセスごとに停止してしまえばメモリも貯まらない、と考えました。

ところが、WebbrowserではXMLを読み込むと加工が入ってしまいもともとのソースが取れないことがわかりました。
そして、WebClient だとソースが取れるのにWebbrowserではダウンロードになってしまうことがあることもわかりました。
ここはWebKitで解決しそうでした。ところが、
今度はコンソールアプリケーションでは動作しない、という問題がでました。



WebClient を使わない理由、はこんなところです。
IPCでサーバー側からの応答を取る方法が知りたいです。







> No79914 の続きと言うことで
>
> クライアント側の実装がしたいのだよね?
> # サーバ側の処理はここでは考えない
>
> 微妙に状況がわからないのだけど WebClient を使わない理由はなぜだろう。
> クライアント→サーバにリクエストを送り、サーバ→クライアントへの返信を受け取る処理を
> メッセージループなしで行うには System.Net.WebClient が最短手順だと思うのだけど。
>
> MSDN サンプルのほぼそのままだけど、コンソールアプリケーションにて
> System.Net.WebClient w = new System.Net.WebClient();
> byte[] webcontents = w.DownloadData("http://localhost/");
> Console.WriteLine(Encoding.ASCII.GetString(webcontents));
> だけで当方期待通りの動きを確認済み。
>
> native なら curl あたりを提案するとこだけど、たぶん curl にできることなら WebClient でもできる。
>
引用返信 編集キー/
■80213 / inTopicNo.4)  Re[3]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ 774RR (418回)-(2016/06/23(Thu) 12:11:54)
No79931 の「プロセス間通信」というのは、オイラが誤読していないのであれば

              http                                                      IPC
(サーバー) ------ (画面表示無しの通信専用プロセス、リサイクルあり) ----- (主プログラム)

の構成してみたらどう?という意味だと思う。

主プログラムは子プロセスとして通信専用プロセスを起動する
通信専用子プロセスはサーバーと http 通信し、主プログラムに結果を返す。
(1回ごとでもいいし一定時間ごとでもいいけど)通信専用子プロセスは終了する(終了させる)と
通信専用子プロセス自体にリソースリークがあっても OS が回収してくれるんぢゃないの?
→通信専用子プロセスは WebBrowser なり WebKit を使っても問題ない

これは目的と手段がいれかわっている手だよね。
通信したい→ WebKit なら通信できる→ WebKit を使う事が目的にすり替わっている気のせいがする。
課題が「 WebBrowser/WebKit を使うこと」ならばこれでよいと思うが
課題が「所定の http 通信したい」なら、これは解決策としては遠回り杉っつか下策と思う。

主プログラムと通信専用子プロセスの間の IPC はなんでもいい。
ファイルでもいいしパイプでもいいし共有メモリでもいいだろう。
オイラなら慣れてる native で cURL.exe を起動しパイプで結果受け取るかな

--------

http も IPC の1つなわけだけど、その http を喋るサーバソフトはもうあるわけだよね。
そのサーバソフトを作り直して http でない別の IPC プロトコルを喋らせようということが聞きたいの?

> ところが、WebClient を連続で使っていると応答が戻ってこ無いことがあったのです。
その理由を追求してサーバ側なりクライアント側なりを修正するのがいちばん「まとも」な手だと思う。

通信したい→ WebClient では失敗する→失敗する原因を追究する
cookie が足らないとか、連続アクセス制限にひっかかっているとか、 UA 文字列が間違ってるとか。
オイラ的には WebClient 自体に問題があるとは思えない。

引用返信 編集キー/
■80214 / inTopicNo.5)  Re[4]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ やんまー (22回)-(2016/06/23(Thu) 13:04:15)
774RR さん

すみません。
やっぱり話が逸れてしまっていると思います・・・

いろいろご心配もありがたいのですが、
「サーバー側からの応答を取りたい」
の点をよろしくお願いいたします。。。

質問文にもありますように、ファイルに吐き出してしまえば機能そのものはなんとかなりそうですが、
それだとプロセス間通信にならないので、気になった次第です。

Webアクセスのレスポンスに限りませんでも、
例えば、1を渡したら10倍して10で返ってくる、でも良いのです。

ただ、それだとあまりにも単純すぎてクラスライブラリで*10出来てしまいそうですが、
そうではなく、あくまでもサーバーで*10した値を返せないかな、といったところです。

どうかよろしくお願いいたします。



引用返信 編集キー/
■80215 / inTopicNo.6)  Re[5]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ kaina (11回)-(2016/06/23(Thu) 14:07:30)
横から失礼。

横道に逸れた実装をしようとしているのは、やんまーさん自身なのでは…

私も774RRさんのご指摘の通り、WebClient自体に問題があるとは思えないので、

>> ところが、WebClient を連続で使っていると応答が戻ってこ無いことがあったのです。

の原因を明らかにした上で、ではどうすればよいかを考えたほうが近道だと思います。
一番怪しいのは同時接続数(デフォルトは2)なのでは無いかと思いますので、
System.Net.ServicePointManager.DefaultConnectionLimit
を変更してみてはいかがでしょうか?

引用返信 編集キー/
■80217 / inTopicNo.7)  Re[6]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ やんまー (23回)-(2016/06/23(Thu) 14:18:52)
kaina さん

すみません。
わざわざ別スレッドにしたのは単にIPC通信に関してわからなかったという点でもあるのです。

まずは、そこはいかがなのでしょうか

「サーバーで処理をさせて、クライアントで結果を受ける、という動作」
の点です。



引用返信 編集キー/
■80218 / inTopicNo.8)  Re[7]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ やんまー (24回)-(2016/06/23(Thu) 14:26:41)
もしかすると私の言う

「サーバーからの応答」

「WEBサーバーからの応答」と誤解なさっているのでしょうか・・・?

そうではなく、単に同一コンピューターの
サーバープログラムのことを指しています。

クライアント(10) → サーバー(受け取った値を10倍にして返す) → クライアント(受け取った値を表示 「100」)

このようなことが出来るのか、という質問でした。

引用返信 編集キー/
■80219 / inTopicNo.9)  Re[8]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ Zip (1回)-(2016/06/23(Thu) 14:31:53)
No80218 (やんまー さん) に返信
> もしかすると私の言う
>
> 「サーバーからの応答」
> を
> 「WEBサーバーからの応答」と誤解なさっているのでしょうか・・・?
>
> そうではなく、単に同一コンピューターの
> サーバープログラムのことを指しています。
>
> クライアント(10) → サーバー(受け取った値を10倍にして返す) → クライアント(受け取った値を表示 「100」)
>
> このようなことが出来るのか、という質問でした。
>
引用返信 編集キー/
■80220 / inTopicNo.10)  Re[9]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ Zip (2回)-(2016/06/23(Thu) 14:35:31)
ゴメンナサイ。名前入れてEnter押したら投稿されてしまいました。

ところで、クライアントの送信内容をサーバ側で受け取れたのならば、
サーバー→クライアントに同じ仕組みを入れればいいんじゃないですか?

リモート通信のクライアント・サーバという用語は、
狭義では、「自分」→「相手」と読み替えた方がいいです。
これは、あくまでも単方向のものなので、
双方向でこの仕組みを用意しないといけない、ということになります。
引用返信 編集キー/
■80221 / inTopicNo.11)  Re[7]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ Hongliang (436回)-(2016/06/23(Thu) 14:36:50)
.NET Remotingは、呼び出す箇所からの観点で言えば、ただのメソッド呼び出しです。
ですから、処理条件を引数で渡し、処理の結果を返値で受け取ります。
2番目のリンク先ではサーバ側でイベントを発生させていますが、そうではなくこの部分にサーバ側の処理を記述して結果を返値として返せばいいです。
// MarshalByRefObjectとかSerializableとかが絡んでくるけど。

なお、.NET Remotingは現在すでにWCFに置き換えられています。後方互換性のために残されていますけど。

それから、単にIPCといった場合、プロセス間通信という意味でしかなく、特定の技術を指す物ではありません。TCP/IPもIPCの一種です。
.NET Remotingではパイプを使用したチャネルに対して「IPCチャネル」と名付けていますが、これをIPCと略すと混乱を招くこともあります。リンク先はともかく、やんまーさんご自身は「.NET Remoting」の名を一切出されていないので。
引用返信 編集キー/
■80222 / inTopicNo.12)  Re[8]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ やんまー (25回)-(2016/06/23(Thu) 15:02:25)
Hongliang さん


畏れ入ります。

> .NET Remotingは、呼び出す箇所からの観点で言えば、ただのメソッド呼び出しです。
> ですから、処理条件を引数で渡し、処理の結果を返値で受け取ります。
> 2番目のリンク先ではサーバ側でイベントを発生させていますが、そうではなくこの部分にサーバ側の処理を記述して結果を返値として返せばいいです。
> // MarshalByRefObjectとかSerializableとかが絡んでくるけど。


RaiseEventでメソッドを実行してやれば良いのはわかるのですが、返すとしたらどう返すかわからなくなってしまいました。
1つ目のサンプルでは一応返していますが、クラスライブラリで
Return "Get Msg :" & AMsg
しているだけで、サーバープログラムの方では何もしていませんよね。。。

これで言うと
"Get Msg :" & AMsg
という文字列を、サーバープログラムの方で組み立てて返すにはどう書くのかな・・・という事がわからなかったのです・・・。


すみません。多分そうとう低レベルなところで悩んでいます。。。

引用返信 編集キー/
■80223 / inTopicNo.13)  Re[10]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ 774RR (419回)-(2016/06/23(Thu) 15:07:55)
IPC って「プロセス間でデータをやり取りする手段一般」なので、
https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%82%BB%E3%82%B9%E9%96%93%E9%80%9A%E4%BF%A1
そういう目的に使える技法ならどれを使っても問題ない。
というか、手段なんてのは目的に応じて使い分けるもの。

> クライアント(10) → サーバー(受け取った値を10倍にして返す) → クライアント(受け取った値を表示 「100」)
> このようなことが出来るのか、という質問でした。

質問が「できるか、できないか」であるなら回答は「できる」で終了なわけだ。
質問が更に発展して「どうすればよいか」あるいは「どの技法を使えばよいか」となるならば、
回答は「自分の目的に最適な技法を自分で選択すればよい」となる。
案件が要求しているところの詳細はオイラたち読者にはわからないから判断は自分でするしかない。

http だってできるわけだ
http://localhost/cgi-bin/tentimes.cgi?val=10
をクライアントがサーバに要求したら、サーバからは
<html><p>multiplied values=100</p></html>
が返信される、ってのも立派な IPC っす。

引用返信 編集キー/
■80224 / inTopicNo.14)  Re[10]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ やんまー (26回)-(2016/06/23(Thu) 15:09:43)
Zip さん

ありがとうございます。

そうなんですね。

というとは自分から相手に通信した際の戻り値は待ち受ける事はできず、
戻り値 = Fanction
みたいに簡単には行かないって言うことでしょうか。

例えば
自分から10を送信したら、
相手が10*10=100を計算したら、
その結果は非同期的に相手が送ってくるのを受ける、という感じにしかならないってことでしょうか・・・。

引用返信 編集キー/
■80225 / inTopicNo.15)  Re[9]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ Hongliang (437回)-(2016/06/23(Thu) 15:20:39)
> RaiseEventでメソッドを実行してやれば良いのはわかるのですが、返すとしたらどう返すかわからなくなってしまいました。
> 1つ目のサンプルでは一応返していますが、クラスライブラリで
> Return "Get Msg :" & AMsg
> しているだけで、サーバープログラムの方では何もしていませんよね。。。

???
たとえば、サーバ側の処理が「Integerを受け取ってその2倍の値を返す」なら、
サーバ側の記述は
Public Function Mul2(ByVal src As Integer) As Integer
  Return src * 2
End Function
になるだけですよね?
クライアント側は
Dim ret As Integer = remoteObject.Mul2(10)
と普通にメソッドを呼び出すだけ。

引用返信 編集キー/
■80226 / inTopicNo.16)  Re[10]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ やんまー (27回)-(2016/06/23(Thu) 15:26:36)
Hongliang さん

あれ・・・
そんなに簡単に呼び出せますか・・?

サーバー(相手側)の Function Mul2 は実行できない認識でした。

呼ぶとしたら、クラスライブラリでRaiseEventでメソッド(非Function)を呼び出せるだけだと・・・。

試してみます!
引用返信 編集キー/
■80227 / inTopicNo.17)  Re[10]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ やんまー (28回)-(2016/06/23(Thu) 15:35:42)
Hongliang さん


Mul2 をクラスライブラリに宣言する?必要があるのですかね・・・コンパイルが通りませんよね。。。

クラスライブラリに宣言したとして、
RaiseEvent で実行するのではないでしょうか??

でもこれだと戻り値が取れないのですが・・・・。
引用返信 編集キー/
■80230 / inTopicNo.18)  Re[11]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ Hongliang (438回)-(2016/06/23(Thu) 16:13:41)
// 2番目のリンク先を前提にしています。

サーバは、IpcSharedObjectを.NET Remotingのサーバチャネルを使って公開します。
クライアントは、.NET Remotingの上記サーバチャネルからIpcSharedObjectを取得します。
クライアントはこのIpcSharedObjectに定義されているメソッドを呼び出します。
一見単なるインスタンスメソッドの呼び出しですが、IpcSharedObjectの実体はサーバにあり、メソッド内の処理はサーバ側で実行されています。

というだけの話ですが…。
2番目のリンク先ではIpcSharedObjectにSendMessageというメソッドを定義していますが、これは自由に定義できますからMul2にでもなんでもすればいいです。
引用返信 編集キー/
■80235 / inTopicNo.19)  Re[12]: IPCを使用してサーバーからの戻り値を取りたい
□投稿者/ Hongliang (439回)-(2016/06/23(Thu) 19:36:52)
サーバ側のプロジェクト(=実行ファイル)に実際の処理を記述したい、って要求でしょうか。
私は、
・dllに定義するのはMustInheritなMarshalByRefObject継承クラス
・サーバ側で上記クラスから派生させた実装クラスを記述する。
という手法をとっていました。

ところで繰り返しになりますが、.NET Remotingはレガシーな技術であり、.NETのリモーティング技術はWCFに移行しています。
古い物のお守りならともかく、そうでないなら今更学ぶ意味はないです。
引用返信 編集キー/
■80242 / inTopicNo.20)  Re[12]: IPCを使用してサーバーからの戻り値を取りたい
 
□投稿者/ やんまー (29回)-(2016/06/24(Fri) 00:03:17)
Hongliang さん

たびたびありがとうございます。

やはりクラスライブラリに

Public Function Mul2(ByVal src As Integer) As Integer
Return src * 2
End Function

を書くという話でしたか。
クラスライブラリに書いても、実際には実行しているのはサーバですよ、ということですね。

このサンプルで言うと、このサーバのフォームのほうにFunctionプロシージャを実装して値を返したいのですが、
やっぱりちょっと難しそうですね。。。

プロセス間通信 VB.NET で検索するとこのリモーティングがトップに来るので
これしかないのかと思いましたが、他にもパイプなどあるようですので、
他の方法も考えてみます。


ちなみに余談ですが、
この2番めのサンプルって実際には動作しませんよね?

 System.InvalidOperationException: 有効ではないスレッド間の操作:
 コントロールが作成されたスレッド以外のスレッドからコントロール 'label1' がアクセスされました


別のスレッドからフォーム上にアクセス出来ない。ってことですよね。invokeを使う必要がありますよね?


引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -