我有一个使用API在网站上获取实时更新的应用程序。他们使用他们所谓的long-polling technique:
长轮询是一种变体 传统的民意调查技术 允许模拟信息 从服务器推送到客户端。同 长轮询,客户要求 来自服务器的信息 与普通民意调查类似的方式。然而, 如果服务器没有 为客户提供的信息, 而不是发送空响应, 服务器保存请求并等待 有些信息可供使用。 一旦信息可用 (或在适当的超时后),a 完整的回复发送到 客户。那时客户通常会 立即重新请求信息 从服务器,使服务器 几乎总会有一个可用的 等待它可以使用的请求 提供数据以响应事件。 在web / AJAX上下文中,长轮询是 也称为Comet编程。
长期民意调查本身并不是一种推动力 技术,但可以使用 真正推动不是的情况 可能的。
基本上,这会在您收到回复后强制将请求发回服务器。在iPhone应用程序中执行此操作的最佳方法是什么?这最终必须在后台运行。
答案 0 :(得分: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 :(得分:5)
长轮询正在向服务器发出读取请求,服务器获取请求,发现没有什么东西可以发送给你,而不是什么也不返回,或者“空”,它反而坚持请求有趣的出现了。一旦找到了什么,就会写入套接字,客户端会收到数据。
详细说明,在整个过程中,使用通用套接字编程,客户端被阻塞并挂在套接字读取调用上。
有两种方法可以解决这个问题(好吧,如果你不介意在主线程上停留几秒钟就会有三种方法,但是我们不计算那个)。
将套接字处理代码放在一个线程中。在这种情况下,整个套接字进程位于程序中的一个独立线程中,因此它很快就会停留在等待响应的读取上。
使用异步套接字处理。在这种情况下,您的套接字读取不会阻止主线程。相反,你传入回调函数,响应套接字上的活动,然后以你的快乐方式。在Mac上,有CFSocket公开了这种功能。它产生自己的线程,并使用select(2)管理套接字连接。
This是一个很好的小帖子,谈论CFSocket。
CFSocket非常适合消息传递和事件的Mac习惯用法,可能就是你应该在做这类工作时看到的。还有一个基于CFSocket构建的Obj-C类包装器,名为ULNetSocket(以前称为NetSocket)。