C#2008 SP1
このコードを使用して、クライアントのWebサイトに接続しています。これはソフトフォンアプリケーション用です。ユーザーが電話をかける前に、ソフトフォンはアクティブなインターネット接続があるかどうかをテストする必要があります。
だから、私がしたいのは、クライアントのWebサイトに接続するためにhttpWebRequestクラスを使用することです。応答に問題がなければ、インターネット接続を続行できます。
しかし、対応に時間がかかりすぎることに気づきました。これが非常に効率的なテスト方法ではないかどうかはわかりません。
しかし、私が彼らのウェブサイトを閲覧すると、ページをロードするのに1秒もかかりません。しかし、HttpWebRequestクラスを使用すると時間がかかりすぎます
したがって、この要件は次のとおりです。
時には、クライアントのオフィスでプロキシが使用されます。私はTCPClientクラスを使用できません(プロキシプロパティがありません)。
プロキシはSOCKSをサポートしていないため、Socketsクラスを使用できません。
タイムアウトプロパティを使用する必要があります。そのため、WebClientクラスを使用できません。これは、応答が返されるまでソフトフォンがフリーズするためです。したがって、数秒後にタイムアウトします。
だから私が考えることができる唯一のものはHttpWebRequestクラスです。
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.xxxxxxxxx.com");
request.Timeout = 5000;
request.Credentials = CredentialCache.DefaultNetworkCredentials;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode == HttpStatusCode.OK)
{
Console.WriteLine("IsSIPServerAvailable: " + response.StatusCode);
isAvailable = true;
}
======== p\Invokeを使用して編集====
[DllImport("wininet.dll", CharSet = CharSet.Auto)]
private extern static bool InternetGetConnectedState(ref InternetConnectionState_e lpdwFlags, int dwReserved);
[Flags]
enum InternetConnectionState_e : int
{
INTERNET_CONNECTION_MODEM = 0x1,
INTERNET_CONNECTION_LAN = 0x2,
INTERNET_CONNECTION_PROXY = 0x4,
INTERNET_RAS_INSTALLED = 0x10,
INTERNET_CONNECTION_OFFLINE = 0x20,
INTERNET_CONNECTION_CONFIGURED = 0x40
}
// In function for checking internet
InternetConnectionState_e flags = 0;
bool isConnected = InternetGetConnectedState(ref flags, 0);
P/Invokeを使用して InternetGetConnectedState を呼び出してみてください。これにより、接続が構成されているかどうかがわかります。次に InternetCheckConnection を使用して、サービスへの特定の接続を確認してください。これは(時々)接続を直接接続するよりも高速ですが、完全な接続を前もって行うよりも優れているかどうかをテストして確認します。
実際の通信に使用するソフトフォンは何ですか?それはHTTP/HTTPSを介して同じWebサイトに行きますか?もしそうなら、それは絶対に正しい方法です-次のステップは、なぜそんなに時間がかかるのかを解明することです。
リクエストする前にネットワーク接続は確実にアップしていますか?あなたは間違いなくnot事前にリクエストをしているのですか私はあなたが応答を破棄していないことに気付いたので、私は尋ねます-それが他の場所でも発生した場合、特定のサーバーへの接続をいくつかしか与えていない接続プールに対して実行していることがわかるかもしれません。道徳はalwaysHttpWebResponse
sをusing
ステートメントに入れることです。もちろん、それはnotがあなたのケースで問題になるかもしれませんが、試してみる価値はあります。
実際のアプリケーションが他の場所に接続する場合は、テストもチェックする必要があります。基本的には、できるだけ実物に近づけてください。
興味深いことに、あなたはそれが「ソフトフォン」アプリケーションだと言っています-これは実際に動作していますかonコンパクトなフレームワークを使用した何らかの説明の電話ですか、それともデスクトップアプリですか?
クライアントにWCF呼び出しを行うのと同じような状況で、クライアントが(何らかの理由で)到達できない場合は時間がかかりすぎます。私がしたことは、未加工のTCPソケットからクライアントアドレスへのソケットです...そこ。
これにより、到達しようとしているエンドポイントと通信できるかどうかを判断するための最も速く正確な答えが得られました。これの唯一の欠点は、接続しない送信タイムアウトと受信タイムアウトのオプションしかないため、ソケットでタイムアウトを自分で管理する必要があることです。
それはこのようなものになります...
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
IAsyncResult result = socket.BeginConnect("www.xxxxxxxxx.com", 80, null, null );
//I set it for 3 sec timeout, but if you are on an internal LAN you can probably
//drop that down a little because this should be instant if it is going to work
bool success = result.AsyncWaitHandle.WaitOne( 3000, true );
if ( !success )
{
throw new ApplicationException("Failed to connect server.");
}
// Success
//...
}
finally
{
//You should always close the socket!
socket.Close();
}
私の目の前で使用した実際のコードはありませんが、これで一般的なパスに進むはずです。
Microsoft.VisualBasic.Devices名前空間を参照して、NetworkAvailableEventHandlerデリゲートとNetworkクラスを使用できます。 Network.IsAvailableプロパティとNetwork.NetworkAvailabilityChangedイベントを使用して、ネットワークが存在する(または後で影響を受ける)ことを確認し、サーバーにHTTP GETを実行してサーバーが存在するかどうかを確認します。
これは、「ネットワークが見えない」のではなく、もう少し具体的に問題を報告するのに役立ちます。
Microsoft.VisualBasicへの参照を追加し、usingステートメントMicrosoft.VisualBasic.Deviceを追加することをお勧めします。次のコード行を使用して、ネットワークへの接続を確認できます。
public static bool isConnectedToNetwork {
get {
Network network = new Network();
return network.IsAvailable;
}
}
request.GetResponse()
itselfただし、ホスト名を解決できない場合は例外が発生します。そのため、try-catchを使用してSystem.Net.WebException
、Status
プロパティでエラーステータスを確認します。ただし、どのステータスがインターネットがないことを正確に示しているのかはわかりません。ほとんどの応答は、DNSまたはその他の接続の問題が原因である可能性もあります。