Подтвердить что ты не робот

Длинный опрос в objective-C

У меня есть приложение, которое использует API для получения обновлений в реальном времени на веб-сайте. Они используют так называемый метод долгого опроса:

Длительный опрос - это вариация традиционная техника опроса и позволяет эмуляцию информации нажмите от сервера к клиенту. С длительный опрос, клиент запрашивает информация с сервера в аналогично обычным опросам. Однако, если на сервере нет информация, доступная для клиента, вместо отправки пустого ответа, сервер хранит запрос и ждет для получения некоторой информации. Как только информация станет доступной (или после подходящего тайм-аута), полный ответ отправляется клиент. Обычно клиент будет немедленно перепроверить информацию с сервера, чтобы сервер почти всегда будут доступны ожидающий запрос, который он может использовать для передавать данные в ответ на событие. В контексте Web/AJAX длительный опрос также известный как программирование кометы.

Длинный опрос сам по себе не является толчком технологии, но могут использоваться в обстоятельства, при которых реальный толчок не возможно.

В основном это принудительно возвращает запрос на сервер, как только вы получите ответ. Каков наилучший способ сделать это в приложении iphone? Это в конечном итоге должно выполняться в фоновом режиме.

4b9b3361

Ответ 1

Это точно такой вариант использования, что 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
}

В качестве альтернативы вы можете использовать async-I/O и делегировать обратные вызовы для выполнения того же, но в этом случае это будет действительно глупо.

Ответ 2

Длительный опрос делает запрос на чтение сервером, сервер получает запросы, обнаруживает, что вам ничего не интересно отправить, а вместо того, чтобы ничего не возвращать или "пусто", вместо этого он удерживает запрос до тех пор, пока что-то Интересно. Как только он что-то находит, он записывает в сокет, и клиент получает данные.

Детально, что в течение всего этого времени, используя универсальное программирование сокетов, клиент блокируется и висит на вызове чтения сокетов.

Есть два способа справиться с этим (ну, три, если вы не против застревать в основном потоке в течение нескольких секунд, но не считайте это).

  • Поместите код обработки сокета в поток. В этом случае весь процесс сокета находится в независимом потоке внутри программы, поэтому он с радостью сидит за чтением, ожидая ответа.

  • Используйте асинхронную обработку сокетов. В этом случае считывание сокетов НЕ блокирует основной поток. Вместо этого вы передаете функции обратного вызова, которые реагируют на активность в сокете, а затем идут по вашему веселью. На Mac есть CFSocket, который предоставляет такую ​​функциональность. Он генерирует собственный поток и управляет соединением сокета с помощью select (2).

Это неплохая статья о CFSocket.

CFSocket хорошо вписывается в идиому Mac о передаче сообщений и событиях, и, вероятно, вы должны смотреть на эту работу. Существует также оболочка класса Obj-C, построенная на CFSocket, называемая ULNetSocket (ранее NetSocket).