トップ «前の日記(2003-07-29) 最新 次の日記(2003-07-31)» 編集

日々の破片

Subscribe with livedoor Reader
著作一覧

2003-07-30

_ 夏の日

とは到底思えない日が続くので、気分はまだ6月。しかし、着々とその日は近づくのであった。

_ SoapHttpClientProtocol

まとめると、
public class GeneratedSpecialized : SoapHttpClientProtocol {
  ...
}
...
for (;;) {
  using (GeneratedSpecialized s = new Specialized()) {
    s.Url = "http://....";
    s.WebMethod();
  }  // 暗黙にs.Dispose()が呼び出される。
  Thread.Sleep(300); // 相手IISのセッションタイムアウト時間
}
とした場合、相手からのRSTを受けているにもかかわらず、同一ソケットを利用して2度目のリクエストを出している。
しかし、そのリクエストはエラーと認識されない(まあ、ありえる)。
そのため、必ず、s.Timeoutミリ秒待つことになる。
というのが、問題点。
もっとも大きな問題点は、Disposeの呼び出しが下層にあるソケットの明示的なshutdown呼び出しにならないことにある。そのため、間歇的な呼び出しは、必ず失敗することになる。
java.net.HttpUrlConnectionは、disconnect()を持つが、これに相当する機能が無い。
たとえば、こんな方法はどうだろうか。
public class ProxyProxy : GeneratedSpecialized {
  protected override WebRequest* GetWebRequest(Url u) {
    return WebRequest.Create(u);  // 常に作り直し
  }
}
 
うまく行くだろうなぁ、と思うが、なんだかなぁ、という感じ。

_ ありゃ?

************** 例外テキスト **************
System.InvalidOperationException: XML ドキュメントを生成中にエラーが発生しました。 ---> System.InvalidCastException: 指定されたキャストは有効ではありません。
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriter1.Write13_Register(Object[] p)
   --- 内部例外スタック トレースの終わり ---
   at System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter, Object o, XmlSerializerNamespaces namespaces, String encodingStyle)
Flag属性enumとは関係ないようだ。なんでだ?
-HTTPSだとうまく動く。よもや、タイミングでは?
タイミングいろいろ変えてもだめだ。MSマジックだな。

_ RST防止

上で、HttpWebRequestのインスタンスを再作成する例を挙げたが、そもそもHttpWebRequest自体が内部にSocketを抱え込んでるから、あの方法ではだめ。
protected override WebRequest GetWebRequest(Uri uri)
{
    HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(uri);
    if (last) // 連続してリクエストを出す場合、最後のリクエストのみ設定
    {
        wr.KeepAlive = false;
    }
    return wr;
}
 
結局、まともにHTTPと付き合う必要がある。ちなみに、HttpWebRequest#Connectionに対して"Close"を代入すると例外になる(MSDNに明記されている)ので、KeepAliveプロパティを利用する。
というわけで、簡単お気楽.NETプログラミングでもプロトコルの知識は必須ということで。

_ HTTPSならOK

わかった。と思う。バッファリングの最中に、シリアライゼーションが完了したと思って、誤って送信してしまうからだ。Content-Lengthが良く見るとおかしい。

その結果、500なレスポンスがHTMLで戻ってくるから、デシリアライゼーションに失敗しているというのが、InvalidCastExceptionなんだろう。

_ 別解

試す気は無いが、LifeTimeServiceのデフォルトの有効期間が5分らしいので、これで引き伸ばすというテもあるようだ。

でも、この場合、SoapClientProxy自体をdisposeしてnewで作り直すようにコードしているわけだから、仮にうまく動いてもこれは変だと思う。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|

ジェズイットを見習え