ASIHTTPRequest Understanding persistent connection reuse
来源:互联网 发布:微信网页授权域名 编辑:程序博客网 时间:2024/06/06 11:50
转自:http://groups.google.com/group/asihttprequest/browse_thread/thread/49f58c66f00d993a/ce14ee901960e92a
问:
Hey all,
Either I see a problem in the ASI stuff, or am not understanding how
persistent connections are supposed to work in it. Either way...
I've integrated a031a030f949 into my codebase (was HEAD not too long
ago if it isn't still) in order to add Keep-Alive support to my
project. I'm still in the "get it back to where it was before
upgrading" stage, so I haven't done any work to get Keep-Alives
working.
I use the NSOperation method of doing requests. I create a request
(sometimes ASIHTTPRequest, sometimes ASIFormDataRequest) every time I
want to do a new transaction.
The behavior I'm seeing is that at the start of the app, the
connections all work. After that, none of them work. They all have an
error as follows:
2010-03-08 10:00:59.977 MyApp[47253:207] RESTHelper[0x54207f0]: Error
was Error Domain=ASIHTTPRequestErrorDomain Code=1 UserInfo=0x5413a80
"A connection failure occurred"
2010-03-08 10:01:00.018 MyApp[47253:207] RESTHelper[0x54207f0]: Error
userInfo is {
NSLocalizedDescription = "A connection failure occurred";
NSUnderlyingError = Error Domain=NSPOSIXErrorDomain Code=57
UserInfo=0x1293800 "Operation could not be completed. Socket is not
connected";
own to reuse? That seems in keeping with the
ASIHTTPRequest#connectionCanBeReused property. I notice that each
ASIHTTPRequest has its own connection pool, and I don't understand why
that would be, since it's an instance variable, not global.
Any help you can offer would be immensely appreciated. :)
Jimmy
答:
Hi Jimmy
> persistent connections are supposed to work in it. Either way...
ASIHTTPRequest has a connection pool, stored in the static array persistentConnectionsPool. Each item in this pool is actually a dictionary that contains:
* information about the host, port and scheme (eg http) the connection is for
* a reference to the request that is currently using a connection (if there is one)
* a reference to the stream used for the request
* an ID that uniquely identifies the connection
* a date corresponding with when the connection should expire
When a request is started, it first looks in the connection pool to see if there is a connection it can reuse. It will attempt to reuse a connection if:
* The host, port and scheme are the same as the request
* The date the connection is supposed to expire has not yet passed
* The connection is not already in use (if it has a value for the request key, it is already in use)
If it finds a connection to use, the request will set its connectionInfo property to the dictionary for the connection it will use. If not, it creates a new connectionInfo dictionary (since it will need to create a new connection) and adds it to the pool. If it finds any connections that should have expired, it removes them from the pool.
Behind the scenes, CFNetwork keeps connections open as long as there is a stream attached to that connection that hasn't been closed. So, when a request finishes, we actually keep the readStream open so a subsequent request can use the connection - once a new request starts and its stream has been opened, we close the old stream.
Each connection's unique ID is used to 'tag' the readStream to tell CFNetwork 'reuse the connection that matches this id, or create a new connection if you can't find a connection that matches this id'. As far as I know, there is no way to access to the actual connection itself - all you can do is to provide CFNetwork with a hint as to your intention.
You shouldn't really need to do anything special to make persistent connections work. connectionCanBeReused is really only used internally - it has a public accessor so I can see what a request is doing in tests. The only property you should generally need to worry about is shouldAttemptPersistentConnection - if you set this to NO, ASIHTTPRequests won't attempt to use persistent connections at all.
The first step in debugging problems with persistent connections should be to turn on DEBUG_PERSISTENT_CONNECTIONS (the easiest way is to modify ASIHTTPRequestConfig.h). This will cause ASIHTTPRequest to print information about how it is using and reusing connections to the console.
Also, check the headers the server you are connecting to returns. If it returns a Keep-Alive header, ASIHTTPRequest can use the information about when the connection should expire to prevent the kind of problem you've been seeing (I'm guessing, it is trying to use connections that should have been closed). If it isn't returning a keep-alive header, ASIHTTPRequest will attempt to reuse the connection for 60 seconds after the request using it finishes. Depending on the server you're connecting to, this may be the wrong number entirely - servers tuned for performance may well close unused connections much earlier.
I think the main flaw in the current implementation is ASIHTTPRequest won't attempt to retry if the server closes the connection - I hope to look at this fairly soon.
I hope this makes sense!
Best
Ben
- ASIHTTPRequest Understanding persistent connection reuse
- IPVS源代码分析-----persistent connection和fwmark
- TCP连接复用(TCP Connection Reuse)
- TCP连接复用(TCP Connection Reuse)
- TCP连接复用(TCP Connection Reuse)
- ASIHTTPRequest "A connection failure occurred" error
- ASIHTTPRequest "A connection failure occurred" error
- ASIHTTPRequest "A connection failure occurred" error
- How to cancel a persistent connection using NSURLConnection?
- HTTP长连接 Persistent Connections与Connection: Keep-Alive
- Advanced Persistent Threat: Understanding the Danger and How to Protect Your Organization
- Understanding
- ASIHTTPRequest
- ASIHTTPRequest
- ASIHTTPRequest
- ASIHTTPRequest
- ASIHTTPRequest
- ASIHTTPRequest
- vs2010 的syslink control无法支持 多字节字符集
- HOJ2688 Color Segment
- cast 和convert用法详解
- Phone Gap问题集中解决
- Andriod 学习之六 Activity - ListView
- ASIHTTPRequest Understanding persistent connection reuse
- spoj227. Ordering the Soldiers
- 带有CheckBox的CListCtrl中Check状态的获取
- ubuntu搭建jsp环境
- socket 地址结构体定义
- Html标签页的实现说明及结合JS基于对象特性的实现对比
- char *p = "123"和char a[] = "123"根本就不同 .
- mac 锐捷
- ibatis 的 $ 与 # 区别