在目标C中进行长时间轮询

问题描述

| 我有一个使用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)。