问题描述
|
我有一个使用API来在网站上获取实时更新的应用程序。他们使用所谓的长轮询技术:
长时间轮询是
传统的投票技术和
允许模拟信息
从服务器推送到客户端。用
长时间轮询,客户要求
来自服务器的信息
与普通民意测验相似然而,
如果服务器没有任何
可供客户使用的信息,
而不是发送空响应,
服务器保留请求并等待
以获得一些信息。
一旦信息可用
(或在适当的超时后),
完整的回复发送到
客户。客户通常会
立即重新请求信息
从服务器,以便服务器
几乎总是有空位
等待请求,它可以用来
传递数据以响应事件。
在Web / AJAX上下文中,长轮询是
也称为彗星编程。
长时间轮询本身并不是推动
技术,但可以在
没有真正推动的情况
可能。
基本上,这将强制您在收到响应后将请求发送回服务器。在iPhone应用程序中执行此操作的最佳方法是什么?最终这必须在后台运行。
解决方法
这正是
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和委托回调来完成同一件事,但是在这种情况下,这确实很愚蠢。
, 长轮询正在向服务器发出读取请求,服务器获取了请求,发现没有什么要发送给您,而不是不返回任何内容或“空”,而是保留了该请求直到出现有趣的事情。一旦找到东西,它将写入套接字,客户端将接收数据。
详细信息是,在整个过程中,使用通用套接字编程,客户端被阻止并挂在套接字的read调用上。
有两种方法可以解决此问题(嗯,如果您不介意在主线程上停留几秒钟,那么可以使用三种方法,但是我们不算这一种)。
将套接字处理代码放入线程中。在这种情况下,整个套接字进程位于程序内的一个独立线程中,因此它很高兴地停留在读取过程中等待响应。
使用异步套接字处理。在这种情况下,您的套接字读取不会阻塞主线程。相反,您传递了响应套接字上活动的回调函数,然后按照自己的喜好进行操作。在Mac上,有CFSocket公开了这种功能。它产生自己的线程,并使用select(2)管理套接字连接。
这是一篇关于CFSocket的不错的小文章。
CFSocket非常适合消息传递和事件的Mac习惯用法,并且可能是您进行此类工作时应该考虑的内容。还有一个基于CFSocket的Obj-C类包装器,称为ULNetSocket(以前称为NetSocket)。