длительный опрос в объективе-C - PullRequest
12 голосов
/ 10 июня 2011

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

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

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

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

Ответы [ 2 ]

15 голосов
/ 10 июня 2011

Это именно тот вариант использования, для которого идеально подходит 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
}

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

5 голосов
/ 10 июня 2011

При длительном опросе выполняется запрос на чтение к серверу, сервер получает запросы, обнаруживает, что отправлять вам ничего интересного, и вместо того, чтобы ничего не возвращать или «пустой», вместо этого удерживает запрос до чего-то интересный Как только он что-то находит, он пишет в сокет, и клиент получает данные.

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

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

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

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

Этот - хороший небольшой пост, рассказывающий о CFSocket.

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

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