2011-06-10 75 views
12

我有一個應用程序使用API​​在網站上獲得實時更新。他們用他們所說的long-polling technique目標中的長輪詢-C

長輪詢是 傳統的輪詢技術的變化和 允許信息 推送仿真從服務器到客戶端。通過長時間輪詢,客戶端以類似於正常輪詢的方式向服務器請求 信息,其中 爲 。但是,如果服務器沒有任何 信息可用於客戶端, 而不是發送空響應, 服務器保存該請求並等待 可用的某些信息,但是, 。 一旦信息變得可用 (或在適當的超時之後), 完整響應被髮送到 客戶端。客戶通常會立即 立即重新請求信息 從服務器,以便服務器 將幾乎總是有一個可用的 等待請求,它可以使用到 傳遞數據以響應事件。 在web/AJAX上下文中,長輪詢是 也被稱爲Comet編程。

長輪詢本身不是推動 技術,但可以在 情況下使用,其中真實推動不是 可能。

基本上這會強制一旦你有迴應的請求回到服務器。在iPhone應用程序中執行此操作的最佳方法是什麼?這最終必須在後臺運行。

+0

目前尚不清楚你在找什麼。看來你有這個概念,那麼你的問題是什麼? – Saphrosit 2011-06-10 00:32:50

+0

請注意,除非您正在進行VoIP,音頻流或GPS,否則這不適用於iOS的後臺。否則,您的應用會被暫停。 – 2011-06-10 01:12:27

回答

15

這也正是那種用例的那NSURLConnection sendSynchronousRequest是完美的:

- (void) longPoll { 
    //create an autorelease pool for the thread 
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 

    //compose the request 
    NSError* error = nil; 
    NSURLResponse* response = nil; 
    NSURL* requestUrl = [NSURL URLWithString:@"http://www.mysite.com/pollUrl"]; 
    NSURLRequest* request = [NSURLRequest requestWithURL:requestUrl]; 

    //send the request (will block until a response comes back) 
    NSData* responseData = [NSURLConnection sendSynchronousRequest:request 
          returningResponse:&response error:&error]; 

    //pass the response on to the handler (can also check for errors here, if you want) 
    [self performSelectorOnMainThread:@selector(dataReceived:) 
      withObject:responseData waitUntilDone:YES]; 

    //clear the pool 
    [pool drain]; 

    //send the next poll request 
    [self performSelectorInBackground:@selector(longPoll) withObject: nil]; 
} 

- (void) startPoll { 
    //not covered in this example: stopping the poll or ensuring that only 1 poll is active at any given time 
    [self performSelectorInBackground:@selector(longPoll) withObject: nil]; 
} 

- (void) dataReceived: (NSData*) theData { 
    //process the response here 
} 

或者,你可以使用異步I/O和委託回調來完成同樣的事情,但是這真的是一種在這種情況下是愚蠢的。

+1

在主機回覆響應之前,阻止NSURLConnection與NSURLErrorTimedOut失敗的原因是什麼?你如何配置使用'NSURLConnection'時長輪詢的時間? – 2011-06-10 01:20:22

+4

@傑里米:[這個答案](http://stackoverflow.com/questions/1424608/nsurlconnection-timeout)將覆蓋。基本上,你只需用'requestWithURL:cachePolicy:timeoutInterval:'替換'requestWithUrl:',指定一個任意大的超時間隔。 – aroth 2011-06-10 01:26:39

+0

通過使用異步NSURLConnection使此路線有什麼好處? – 2012-01-26 17:04:15

5

長輪詢正在向服務器發送讀取請求,服務器獲取請求,發現沒有任何興趣發送給您,而不是不返回任何內容或「空白」,而是保持請求直到出現一些有趣的東西。一旦它發現了什麼,它會寫入套接字並且客戶端接收到數據。

詳細情況是,在整個時間裏,使用通用套接字編程,客戶端被阻塞並掛在套接字上讀取調用。

有兩種方法可以解決這個問題(好吧,如果你不介意在主線程中停留幾秒鐘,但是我們不計算那個)。

  1. 將套接字處理代碼放在一個線程中。在這種情況下,整個套接字進程在程序中是一個獨立的線程,所以它很高興地坐在讀取等待響應的地方。

  2. 使用異步套接字處理。在這種情況下,您的套接字讀取不會阻塞主線程。相反,你傳入回調函數來響應套接字上的活動,然後開始快樂的方式。在Mac上,有CFSocket可以暴露這種功能。它產生自己的線程,並使用select(2)管理套接字連接。

This是一個不錯的職位談論CFSocket。

CFSocket非常適合消息傳遞和事件的Mac成語,並且可能是您在做這類工作時應該考慮的內容。還有一個構建在CFSocket上的Obj-C類封裝器,名爲ULNetSocket(以前稱爲NetSocket)。