簡體   English   中英

使用 Reachability 檢查遠程主機的可用性是否明智?

[英]Is it wise to use Reachability to check for a remote host's availability?

使用 Reachability Class(來自 Apple)檢查遠程主機的可用性是否明智? 比如說,www.google.com

或者我應該使用

NSString *connectedString = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com/"]]; 

if ([connectedString length] != 0) // Host Available

哪個是最好的選擇,因為我聽說Reachability 在檢查主機可用性時有錯誤

這是檢查主機是否可達的好方法:

    NSURLResponse *response=nil;
    NSError *error=nil;
    NSData *data = nil;
    NSURLRequest *request = [NSURLRequest requestWithURL:your_url];

    data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

如果主機離線,您將收到一些錯誤代碼errornil datanil response變量。
如果主機在線並響應,則會有一些responsedataerror==nil

正如其他人所提到的,可達性檢測的是硬件的變化,而不是服務器的實際可用性。 在閱讀了很多帖子后,我想出了這段代碼。

這是 ReachabilityManager 類的完整實現,它使用 Reachability 和 URLConnection 來確保連接可用或不可用。 請注意,這取決於 Reachability 類(我使用的是 Tony Million 實現,但我確信它適用於 Apple 實現)

如果您在模擬器中測試並啟用/禁用您的無線連接,您將看到它檢測到(有時需要幾秒鍾)連接/斷開連接。 以前僅使用可達性類不起作用的東西。

我還為您的其余代碼添加了一些通知,這些通知比來自 Reachability 的通知更有效。 您可能希望以不同的方式處理此問題。

此外,這是一個單例,因此您可以從任何地方實例化。 您可以將其轉換為非靜態類並從 AppDelegate 實例化它。

如果讀者有時間為其創建一些單元測試,請告訴我,以便我們可以分享更多有關可達性的知識。

只需創建一個新的 NSObject 類並復制以下內容:

。H

#import <Foundation/Foundation.h>
@interface ReachabilityManager : NSObject

+ (void)startReachabilityWithHost : (NSURL *)hostName;

@end

.m

#import "ReachabilityManager.h"
#import "Reachability.h"

@implementation ReachabilityManager

static ReachabilityManager *_sharedReachabilityManager;
static Reachability *reachability;
static NSURL *_hostName;
static BOOL isServerReachable;
+ (void)initialize
{
    static BOOL initialized = NO;
    if(!initialized)
    {
        initialized = YES;
        _sharedReachabilityManager = [[ReachabilityManager alloc] init];
    }
}

+ (void)startReachabilityWithHost : (NSURL *)hostName{
    _hostName = hostName;

    reachability = [Reachability reachabilityWithHostname:hostName.host];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(reachabilityChanged:)
                                                 name:kReachabilityChangedNotification
                                               object:nil];
    [reachability startNotifier];
}

+ (void)stopReachability{
    [reachability stopNotifier];
    [[NSNotificationCenter defaultCenter]removeObserver:kReachabilityChangedNotification];
}

+(void)reachabilityChanged: (NSNotification *)notification{
    dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        BOOL isServerCurrentlyReachable = NO;
        do{
            isServerCurrentlyReachable = [self checkConnectivityToServer];
            BOOL wasServerPreviouslyReachable = isServerReachable;
            isServerReachable = isServerCurrentlyReachable;

            if (NO == wasServerPreviouslyReachable && YES == isServerCurrentlyReachable)
            {
                NSLog(@"REACHABLE!");
                [[NSNotificationCenter defaultCenter]postNotificationName:@"kNetworkReachabilityCustom" object:[NSNumber numberWithBool:YES]];
            }
            else if (YES == wasServerPreviouslyReachable && NO == isServerCurrentlyReachable)
            {
                NSLog(@"UNREACHABLE!");
                [[NSNotificationCenter defaultCenter]postNotificationName:@"kNetworkReachabilityCustom" object:[NSNumber numberWithBool:NO]];
            }
            [NSThread sleepForTimeInterval:5.0];
        }while(!isServerCurrentlyReachable);
    });

}


+(BOOL)checkConnectivityToServer{
    NSURLResponse *response;
    NSError *error=nil;
    NSData *data = nil;
    NSURLRequest *request = [NSURLRequest requestWithURL:_hostName];

    data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    return (data && response);

}


@end

可達性不會告訴您遠程主機是否可聯系。 它只測試第一跳,即您能否向路由器發送數據包。 如果路由器無法連接到更廣泛的互聯網,可達性仍會告訴您您有 wifi 連接。 您必須實施其他建議的解決方案之一來測試“真正的”可達性。

明智的做法是先檢查您是否有任何互聯網連接,為此我使用 Reachability。 我嘗試與服務器建立連接,只有我有互聯網。

這是有關如何使用 Reachability 的教程。 http://www.raddonline.com/blogs/geek-journal/iphone-sdk-testing-network-reachability/

NSString *connectedString = [[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://www.google.com/"]]; 

if ([connectedString length] != 0) // Host Available

您提供的代碼也應該有效,但可能無法提供所需的結果。可達性更可靠。

developer.apple.com 中的以下代碼可能對您有所幫助。

// Create the request.

NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com/"]

                        cachePolicy:NSURLRequestUseProtocolCachePolicy

                    timeoutInterval:60.0];

// create the connection with the request

// and start loading the data

NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

if (theConnection) {

    // Create the NSMutableData to hold the received data.

    // receivedData is an instance variable declared elsewhere.

    receivedData = [[NSMutableData data] retain];

} else {

    // Inform the user that the connection failed.

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM