długie sondaże w objective-C

Mam aplikację, która używa API, aby uzyskać aktualizacje w czasie rzeczywistym na stronie internetowej. Używają tzw. techniki długiego sondowania :

Długi sondaż jest odmianą tradycyjna technika sondażowa i umożliwia emulację informacji przejście z serwera do klienta. Z długa ankieta, klient żąda informacje z serwera w podobny sposób jak w normalnej ankiecie. Jednakże, jeżeli serwer nie posiada żadnych informacje dostępne dla klient, zamiast wysyłać pustą odpowiedź, serwer przechowuje żądanie i czeka aby niektóre informacje były dostępne. Gdy informacja stanie się dostępna (lub po odpowiednim czasie), a pełna odpowiedź jest wysyłana na klient. Klient zazwyczaj wtedy natychmiast ponownie poproś o informacje z serwera, tak aby serwer będzie prawie zawsze mieć dostępną oczekujące żądanie, które może wykorzystać do dostarczanie danych w odpowiedzi na zdarzenie. W kontekście web/AJAX, długa ankieta jest znany również jako programowanie komet.

Długie sondaże same w sobie nie są popychaniem technologii, ale może być stosowany pod okoliczności, w których prawdziwy nacisk nie jest możliwe.

Zasadniczo wymusza to wysłanie żądania z powrotem na serwer po otrzymaniu odpowiedzi. Jak najlepiej zrobić to w aplikacji na iphone ' a? To w końcu musi działać w tle.

Author: PengOne, 2011-06-10

2 answers

Jest to dokładnie taki przypadek użycia, dla którego NSURLConnection sendSynchronousRequest jest idealny:

- (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
}

Alternatywnie, można użyć asynchronicznych I / O i delegować wywołań zwrotnych, aby osiągnąć to samo, ale to byłoby naprawdę głupie w tym przypadku.

 15
Author: aroth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-10 01:15:31

Long polling składa żądanie odczytu do serwera, serwer dostaje żądania, stwierdza, że nie ma nic interesującego do wysłania, i zamiast nic nie zwracać, lub "puste", zamiast tego trzyma się żądania, dopóki nie pojawi się coś interesującego. Gdy coś znajdzie, zapisze do gniazda, a Klient otrzyma dane.

Szczegół jest taki, że przez cały ten czas, używając ogólnego programowania gniazd, klient jest zablokowany i wisi na gniazdach Czytaj sprawdzam.

Są dwa sposoby radzenia sobie z tym (cóż, trzy, jeśli nie masz nic przeciwko utknięciu w głównym wątku na kilka sekund, ale nie liczmy tego).

  1. Umieść kod obsługi gniazda w wątku. W tym przypadku cały proces gniazd znajduje się w niezależnym wątku w programie, więc szczęśliwie siedzi na odczycie czekając na odpowiedź.

  2. Użyj asynchronicznej obsługi gniazd. W takim przypadku odczyt gniazda nie blokuje głównego wątku. Zamiast tego przekazujesz funkcje wywołania zwrotnego, które odpowiadają na aktywność na gnieździe, a następnie poruszasz się w wesoły sposób. Na Macu jest CFSocket, który eksponuje tego rodzaju funkcjonalność. Wywołuje własny wątek i zarządza połączeniem gniazda za pomocą select(2).

To jest ładny mały post mówiący o CFSocket.

CFSocket dobrze pasuje do idiomu Mac przekazywania wiadomości i WKKW i prawdopodobnie jest tym, na co powinieneś zwrócić uwagę, aby to zrobić rodzaj pracy. Istnieje również wrapper klasy Obj-C zbudowany na CFSocket o nazwie ULNetSocket (dawniej NetSocket).

 5
Author: Will Hartung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-10 00:59:01