2011-03-24 96 views
1

我有一個連接到Web服務器的iPad應用程序。我需要檢查Web服務器當時是否在運行。如果Web服務器關閉,我必須向用戶提示一條消息。我將如何做到這一點?檢測服務器是否可達

謝謝。

回答

1

這是我做的:

  1. 獲取Readability.h/m from the Apple Sample Projects,並將其放置在您的項目
  2. 安裝下面
  3. 的NetworkObserver.h/M
  4. 當應用程序開始在[ 「的AppDelegate」 didFinishLaunchingWithOptions]啓動NetworkObserver與[[NetworkObserver currentObserver]開始]
  5. 當應用程序進入backgr ound(applicationDidEnterBackground)停止它,當它進入前景(applicationWillEnterForeground)然後再次啓動它
  6. 當你需要對其進行測試,然後使用此代碼:

代碼如何使用它:

NetworkObserver *observer = [NetworkObserver currentNetworkObserver]; 
if(observer.internetActive && observer.hostActive) { 
    // Do whatever you need to do with the Network 
} else { 
    if(!observer.internetActive) { 
     if(anError) { 
      *anError = [NSError errorWithDomain:NetworkErrorDomain code:1212 userInfo:[NSDictionary dictionaryWithObject:@"Internet is not active at the moment" forKey:NSLocalizedDescriptionKey]]; 
     } 
    } else { 
     if(anError) { 
      *anError = [NSError errorWithDomain:NetworkErrorDomain code:1221 userInfo:[NSDictionary dictionaryWithObject:@"Host is cannot be reached" forKey:NSLocalizedDescriptionKey]]; 
     } 
    } 
} 

首先這裏是NetworkObserver.h

代碼
#import <Foundation/Foundation.h> 

@class Reachability; 

@interface NetworkObserver : NSObject { 
@private 
    BOOL internetActive; 
    BOOL hostActive; 

    Reachability* internetReachable; 
    Reachability* hostReachable; 
} 

@property (nonatomic) BOOL internetActive; 
@property (nonatomic) BOOL hostActive; 

@property (nonatomic, retain) Reachability* internetReachable; 
@property (nonatomic, retain) Reachability* hostReachable; 

// Checks the current Network Status 
- (void) checkNetworkStatus:(NSNotification *)notice; 

- (void) start; 
- (void) stop; 

+ (NetworkObserver *) currentNetworkObserver; 

@end 

最後的NetworkObserver.m代碼:

#import "NetworkObserver.h" 

#import "Reachability.h" 
#import "Constants.h" 

static NetworkObserver *networkObserver; 

@implementation NetworkObserver 

@synthesize internetReachable, hostReachable; 
@synthesize internetActive, hostActive; 

+(void) initialize { 
    if(!networkObserver) { 
     networkObserver = [[NetworkObserver alloc] init]; 
    } 
} 

+ (NetworkObserver *) currentNetworkObserver { 
    return networkObserver; 
} 

- (id) init { 
    self = [super init]; 
    if(self) { 
     self.internetReachable = [[Reachability reachabilityForInternetConnection] retain]; 
     // check if a pathway to a random host exists 
     DLog(@"NO.init(), host name: %@", kServerHostName); 
     self.hostReachable = [[Reachability reachabilityWithHostName:kServerHostName] retain]; 
    } 
    return self; 
} 

- (void) start { 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkNetworkStatus:) name:kReachabilityChangedNotification object:nil]; 
    [internetReachable startNotifier]; 
    [hostReachable startNotifier]; 
    [self checkNetworkStatus:nil]; 
} 

- (void) stop { 
    [internetReachable stopNotifier]; 
    [hostReachable stopNotifier]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

- (void) checkNetworkStatus:(NSNotification *)notice 
{ 
    // called after network status changes 

    NetworkStatus internetStatus = [internetReachable currentReachabilityStatus]; 
    switch (internetStatus) 
    { 
     case NotReachable: 
     { 
      DLog(@"The internet is down."); 
      self.internetActive = NO; 
      break; 
     } 
     case ReachableViaWiFi: 
     { 
      DLog(@"The internet is working via WIFI."); 
      self.internetActive = YES; 
      break; 
     } 
     case ReachableViaWWAN: 
     { 
      DLog(@"The internet is working via WWAN."); 
      self.internetActive = YES; 
      break; 
     } 
    } 

    if(notice) { 
     NetworkStatus hostStatus = [hostReachable currentReachabilityStatus]; 
     switch (hostStatus) 
     { 
      case NotReachable: 
      { 
       DLog(@"A gateway to the host server is down."); 
       self.hostActive = NO; 
       break; 
      } 
      case ReachableViaWiFi: 
      { 
       DLog(@"A gateway to the host server is working via WIFI."); 
       self.hostActive = YES; 
       break; 
      } 
      case ReachableViaWWAN: 
      { 
       DLog(@"A gateway to the host server is working via WWAN."); 
       self.hostActive = YES; 
       break; 
      } 
     } 
    } else { 
     DLog(@"No notice received yet so assume it works"); 
     self.hostActive = YES; 
    } 
} 

@end 

順便說一句,只需將DLog替換爲NSLog以使其工作(我使用此預處理器指令在釋放應用程序時將NSLog取出)。

另一方面有很多other post on Stack OverFlow that deal with that issue like this one

另請注意,NetworkObserver需要一點時間才能獲得正確的值,因此您可能無法在啓動時使用它。

+0

您說過:「還要注意,NetworkObserver需要一點時間才能獲得正確的值,因此啓動時可能無法使用它。」有什麼辦法可以知道它已經更新了「hostActive」變量的值嗎? – viral 2012-08-16 06:27:43

2

您應該使用超時值(requestWithURL:cachePolicy:timeoutInterval:)構造NSURLRequest以根本不處理任何響應。如果達到超時值,您將獲得代表回調didFailWithError:

如果你沒有得到,最終NSURLConnection應該給你一個didReceiveResponse:。您需要解釋NSURLResponse代碼,您可以在其中處理通常的HTTP響應代碼(200,404,500等)。

這是確定您是否有任何互聯網連接的不同問題 - 您應該查看包括Apple的Reachability代碼示例。

0

我認爲最簡單的解決方案是創建一個可以ping的測試文件。也許像serverping.txt這樣的東西只不過是'ok',因爲它是內容(保持數據加載到最低限度)。如果您的響應statusCode是503(或者500 ...您必須測試),那麼您知道該服務不可用。

3

我已經非常成功地使用ASIHttpRequest library附帶的Reachability類來驗證特定服務器是否可以通過網絡訪問。本博客文章介紹如何去這樣做:http://blog.ddg.com/?p=24

+0

請注意,Reachability類實際上是由Apple提供的,ASI只是包含了它,因爲它們也可以使用它。 – 2011-03-24 03:56:57

+0

實際上,根據ASI文檔,「這個類是由Andrew Donoho編寫的,作爲蘋果Reachability類的替代品。」我鏈接到的博客文章解釋了爲什麼他重新設計了Reachability類。 – Greg 2011-03-24 04:02:50

+0

感謝您的澄清,我沒有意識到這一點。詛咒他留下名字「可達性」,如果你正在使用它與Apple類衝突。我會閱讀博客文章,看看那裏發生了什麼。 – 2011-03-24 04:06:14

相關問題