CFNetwork 持久连接(保持活动)
我试图通过 Apple CFNetwork 框架使用持久 HTTP 连接来减少服务器开销。然而,关于它的文档很少。我能找到的唯一信息表明,只要设置了适当的标志,框架就会代表开发人员回收流:
CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, methodString, url, kCFHTTPVersion1_1);
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Keep-Alive"), CFSTR("120")); <--- This line
//Set message body if we're posting
if (msDetails.eType == HttpRequestDetails::POST)
{
CFDataRef bodyRef = CFDataCreate(kCFAllocatorDefault, (const UInt8*)msDetails.strBody.c_str(), msDetails.strBody.length());
CFHTTPMessageSetBody(request, bodyRef);
CFRelease(bodyRef);
}
//Create the read stream...
CFReadStreamRef ReadStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request);
//...use persistent connections..
CFReadStreamSetProperty(ReadStream, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue); <--- This line
//...enable SSL if the URL is https
if(msDetails.strURL[4] == 's')
{
//Hey an https request
CFMutableDictionaryRef pDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(pDict, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse);
CFDictionarySetValue(pDict, kCFStreamPropertySocketSecurityLevel, kCFStreamSocketSecurityLevelSSLv3);
CFReadStreamSetProperty(ReadStream, kCFStreamPropertySSLSettings, pDict);
CFRelease(pDict);
}
CFReadStreamOpen(ReadStream);
上面的代码会导致“CFNetwork 内部错误”。如果我删除 CFReadStreamSetProperty(ReadStream, kCFStreamPropertyHTTPAttemptPercientConnection, kCFBooleanTrue) 调用,那么我将不再收到错误。还值得一提的是,我在读取完数据后就关闭了readstream,但也许我需要自己管理流池?
有人有任何文档、示例或教程可以推荐给我吗?我热衷于继续使用 CFNetwork 的东西,因为我们有一个客户坚持认为我们必须尽量减少对 Obj-C 的使用。
I am trying to reduce our server overheads by using persistent HTTP connections via the Apple CFNetwork framework. However there is little documentation about it. The only information I could find suggested that the framework recycles streams on behalf of the developer as long as the appropriate flags are set:
CFHTTPMessageRef request = CFHTTPMessageCreateRequest(kCFAllocatorDefault, methodString, url, kCFHTTPVersion1_1);
CFHTTPMessageSetHeaderFieldValue(request, CFSTR("Keep-Alive"), CFSTR("120")); <--- This line
//Set message body if we're posting
if (msDetails.eType == HttpRequestDetails::POST)
{
CFDataRef bodyRef = CFDataCreate(kCFAllocatorDefault, (const UInt8*)msDetails.strBody.c_str(), msDetails.strBody.length());
CFHTTPMessageSetBody(request, bodyRef);
CFRelease(bodyRef);
}
//Create the read stream...
CFReadStreamRef ReadStream = CFReadStreamCreateForHTTPRequest(kCFAllocatorDefault, request);
//...use persistent connections..
CFReadStreamSetProperty(ReadStream, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue); <--- This line
//...enable SSL if the URL is https
if(msDetails.strURL[4] == 's')
{
//Hey an https request
CFMutableDictionaryRef pDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(pDict, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse);
CFDictionarySetValue(pDict, kCFStreamPropertySocketSecurityLevel, kCFStreamSocketSecurityLevelSSLv3);
CFReadStreamSetProperty(ReadStream, kCFStreamPropertySSLSettings, pDict);
CFRelease(pDict);
}
CFReadStreamOpen(ReadStream);
The above code causes a "CFNetwork internal error". If I remove the CFReadStreamSetProperty(ReadStream, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue) call then I no longer receive the error. It is also worth mentioning that I close the readstream once I have finished reading the data, but maybe I need to manage the stream pool myself?
Does anyone have any documentation, examples or tutorials they can refer me to? I'm keen to keep using the CFNetwork stuff as we have a client that insists we must minimize our use of Obj-C.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我一直在为同样的事情而苦苦挣扎。
看来关键是确保请求的所有流设置完全相同。特别是,您必须为所有请求将完全相同的字典对象传递给 kCFStreamPropertySSLSettings。它们具有相同的内容是不够的,您必须重复使用完全相同的词典。
I've been struggling with the same thing.
It seems the key is to make sure all the stream settings are exactly the same for the requests. In particular, you have to pass in the EXACT same dictionary object to kCFStreamPropertySSLSettings for all the requests. It isn't enough that they have the same contents, you have to re-use the exact same dictionary.
添加
CFNetwork.framework
和
#import
add
CFNetwork.framework
and
#import <CFNetwork/CFHTTPStream.h>