如何使用 ASIHTTP 保持连接处于活动状态?我需要发出多个请求,但无法打开然后关闭请求连接

发布于 2024-10-26 14:48:26 字数 1322 浏览 2 评论 0原文

我有一个方法,我调用它来使用 GET 发出 Web 服务请求。看起来像这样:

- (UIImage*)getImageWithSeriesGUID:(NSString*)seriesGUID ImageID:(int)imageID {

NSString * unescapedString = RIVERWOODS_GET_IMAGE(seriesGUID, imageID);

NSURL *url = [[NSURL alloc] initWithString:[unescapedString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];


ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

[request setRequestMethod:@"GET"];
[request addRequestHeader:@"Connection" value:@"Keep-Alive"];

[request startSynchronous];
NSError *error = [request error];
if (!error) {
    NSData *response = [request responseData];
    //NSLog(@"Size: %@",[response length]);
    NSString *content = [[[NSString alloc] initWithData:response
                                               encoding:NSUTF8StringEncoding] autorelease];
    NSLog(@"Data: %@", content);
    UIImage *image = [UIImage imageWithData:response];
    return image;
}

return nil;
 }

这种方法工作正常,但速度非常慢。另一方面,我正在迭代 for 循环,因此如果我需要收集的图片数组有 20 个图像,则此方法会被调用 20 次。我希望提高这个过程的效率,并且我认为我应该能够迭代我需要在此方法中收集的所有图像 ID。

在我看来,进展如此缓慢的原因是我们不断打开和关闭多个请求。我拉入的图像平均约为 15kb。

我的问题:我可以做什么来改变这个方法,以便提高效率并利用 HTTP keep-alive 功能?我想,我可以不传递图像 ID,而只传递需要创建的数组的计数,然后在请求方法中设置某种 for 循环,然后允许我传回一系列图像......

这是要走的路吗?我有什么遗漏的吗?我感谢您的帮助和意见!

I have a method that I call to make web service requests using GET. It looks like this:

- (UIImage*)getImageWithSeriesGUID:(NSString*)seriesGUID ImageID:(int)imageID {

NSString * unescapedString = RIVERWOODS_GET_IMAGE(seriesGUID, imageID);

NSURL *url = [[NSURL alloc] initWithString:[unescapedString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];


ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];

[request setRequestMethod:@"GET"];
[request addRequestHeader:@"Connection" value:@"Keep-Alive"];

[request startSynchronous];
NSError *error = [request error];
if (!error) {
    NSData *response = [request responseData];
    //NSLog(@"Size: %@",[response length]);
    NSString *content = [[[NSString alloc] initWithData:response
                                               encoding:NSUTF8StringEncoding] autorelease];
    NSLog(@"Data: %@", content);
    UIImage *image = [UIImage imageWithData:response];
    return image;
}

return nil;
 }

This approach works ok, but it is just REALLY slowly. On the other end I am iterating through a for loop so this method gets called 20 times if the picture array I need to collect has 20 images. I am looking to improve the efficiency of this process, and I am thinking that I should be able to iterate through all the image Id's I need to collect right here in this method.

It seems to me that the reason this goes so slowly is because the multiple requests that we keep opening and closing. THe images I am pulling in are on average ~15kb.

My question: What can I do to change this method around to make it so I can improve efficiency and take advantage of the HTTP keep-alive features? I am thinking that instead of passing in an image ID, I can just pass in the count of the array I need to make, and then setup a for-loop of some sorts here in the request method which would then allow me to pass back an array of images...

Is that the way to go? Is there something I am missing? I appreciate your help and input!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

落日海湾 2024-11-02 14:48:26

这之所以慢得要命,是因为您正在逐一地同步执行请求(无论如何这始终是禁忌)。您需要重构您的下载方法,以异步和并发方式工作。

我以这种方式请求线路数据的方法如下:

  • 创建一个全局网络连接“控制器”(可从您的应用程序委托访问),它可以在需要时动态创建 ASINetworkQueue,并在没有请求时释放
  • 它请求到 ASIHTTPRequest 的子类中,并覆盖这些子类中的完成/失败方法(如果您愿意,可以让它们使用返回的数据触发通知;或者写入磁盘并使用它们的引用更新数据库)。
  • 对于每个请求,获取队列引用,并将您的请求添加到队列中。
  • 队列将根据需要增长和缩小

如果我在我的计算机前,我会在 github 上查看一个这样的示例,但实际上唯一困难的部分是全局连接管理器,并且 ASI* 人员编写了一个很好的示例 此处,位于 gist.github 上。另外,对上述内容的更好解释(我从中学到的)是 此处

The reason why this is slow as hell is that you're doing the requests synchronously (which is always a no-no anyway), one-by-one. You need to refactor your download method to work asynchronously, and concurrently.

My approach to requesting data on the wire in that manner is as follows:

  • Create a global network connection 'controller' (accessible from your App Delegate), which can create an ASINetworkQueue on the fly when required and release it when no requests remain
  • Wrap your requests into a subclass of ASIHTTPRequest, and override the done/fail methods in those subclasses (make them fire a notification with returned data if you like; or write to disk and update a db with their reference).
  • For every request, grab the queue reference, and add your request to the queue.
  • The queue will grow and shrink as needed

If I were at my computer I'd check into github an example of this, but really the only difficult part is the global connection manager, and the ASI* guys have written a great example here on gist.github. Also, a better explanation of the above (where I learnt it from) is here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文