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.
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.
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).
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ź.
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).
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