CFNetwork 持久连接(保持活动)

发布于 2024-12-10 01:14:35 字数 1963 浏览 0 评论 0原文

我试图通过 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 技术交流群。

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

发布评论

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

评论(2

不奢求什么 2024-12-17 01:14:35

我一直在为同样的事情而苦苦挣扎。

看来关键是确保请求的所有流设置完全相同。特别是,您必须为所有请求将完全相同的字典对象传递给 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.

陌若浮生 2024-12-17 01:14:35

添加 CFNetwork.framework

#import

add CFNetwork.framework

and #import <CFNetwork/CFHTTPStream.h>

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