WebSocket 協(xié)議
百度百科
http://www.tuicool.com/articles/7zyMvy6
HTML5一種新的協(xié)議,實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工通信,一開(kāi)始的握手需要借助HTTP請(qǐng)求完成;
傳統(tǒng)的HTTP請(qǐng)求采用輪詢拐揭,而HTTP的header是非常長(zhǎng)的,這樣會(huì)占用很多帶寬顷锰;
WebSocket API中挥萌,瀏覽器只需要做一個(gè)握手的動(dòng)作绰姻,然后,瀏覽器和服務(wù)器之間形成了一條快速通道引瀑,兩者之間就直接可以數(shù)據(jù)互相傳送狂芋;
HTTP的keep-alive是把多個(gè)http請(qǐng)求合并為一個(gè),而Websocket是一個(gè)新協(xié)議憨栽;
多出的 Upgrade帜矾,Connection字段表明是websocket請(qǐng)求;
-
數(shù)據(jù)幀格式
基本的數(shù)據(jù)幀為一個(gè)opcode屑柔、一個(gè)payload長(zhǎng)度和發(fā)送的應(yīng)用數(shù)據(jù)
Paste_Image.png
1. 測(cè)試用例
2. 技術(shù)點(diǎn)
NSOperation
NSOperation 方法說(shuō)明
(void)start; 啟動(dòng) operation
isFinished, isExecuting 狀態(tài)標(biāo)識(shí)
在start函數(shù)里處理設(shè)計(jì)要執(zhí)行的功能
設(shè)計(jì) operation
設(shè)計(jì)一個(gè)基礎(chǔ)的SRTWebSocketOperation<SRWebSocketDelegate>, 并代理處理SR webSocket的close及fail事件屡萤;
SRAutobahnOperation : SRTWebSocketOperation 實(shí)際設(shè)計(jì)執(zhí)行的子operation, 并處理delegate中消息接收的事件;
設(shè)計(jì)了三個(gè)測(cè)試接口:
SRAutobahnTestResultOperation 結(jié)果
SRAutobahnTestCaseInfoOperation 信息
SRAutobahnTestCaseCountOperation 數(shù)目
SRAutobahnTestUpdateReportsOperation 更新
每個(gè)接口創(chuàng)建對(duì)應(yīng)的url測(cè)試operation queue
NSOperationQueue
addDependency //依賴任務(wù)完成偶才開(kāi)始執(zhí)行其他任務(wù)
addOperation__bridge
__bridge 關(guān)鍵字來(lái)實(shí)現(xiàn)id類型與void*類型的相互轉(zhuǎn)換掸宛;
__bridge_retained 是編譯器替我們做了retain工作死陆;
__bridge_transfer 是編譯器替我們做了release工作;
NSURL 使用
NSURLComponents
NSURLQueryItem
BLOCK
block copy 唧瘾?措译?? 使用copy有什么用途饰序?领虹?//[textMessageHandler copy]
__block 定義變量,讓block內(nèi)部可改變
手動(dòng)KVO
willChangeValueForKey / didChangeValueForKey 即時(shí)狀態(tài)不變化也能觸動(dòng)observation菌羽?
DSP
DSP中的block使用self不會(huì)引起循環(huán)引用掠械,使用weakSelf的是為了減少self的生命周期;因?yàn)閎lock肯定會(huì)執(zhí)行注祖;
- 使用 dispatch_group_t 同步
diapatch_group_create / dispacth_group_enter / dispatch_group_wait / dispatch_group_leave - 使用 dispatch_semaphore_t 進(jìn)行同步
- dispatch_data_t
某種程度上跟NSData類型相似猾蒂;
它的獨(dú)特屬性是它可以基于零碎的內(nèi)存區(qū)域,對(duì)組合內(nèi)存進(jìn)行連接管理是晨;
dispatch_data_t c = dispatch_data_create_concat(a, b);
它并不把數(shù)據(jù)copy到一個(gè)單獨(dú)的更大的內(nèi)存區(qū)域肚菠,相反的只是簡(jiǎn)單簡(jiǎn)單持有a和b對(duì)象;
類似的罩缴,你可以使用dispatch_data_create_subrange來(lái)創(chuàng)建一個(gè)不做任何拷貝操作的子區(qū)域蚊逢; - dispatch_benchmark
測(cè)試代碼執(zhí)行的平均納秒數(shù),只在調(diào)試和性能分析上起作用箫章;
編譯相關(guān)
attribute ((vector_size (32))); 占32字節(jié)
_Alignof(type-name) 某類型的對(duì)齊要求
3. 結(jié)構(gòu)設(shè)計(jì)
4. 模塊
Internal 模塊
SRPinningSecurityPolicy : SRSecurityPolicy
使用 Security 框架
- evaluateServerTrust
遍歷serverTrust對(duì)象烙荷,檢查是否與pinnedCertificates中的某個(gè)證書(shū)一致,當(dāng)驗(yàn)證所有pinned證書(shū)都正確時(shí)檬寂,返回YES终抽,否則NO; - updateSecurityOptionsInStream
設(shè)置NSStream對(duì)象的安全屬性策略桶至,支持TLS昼伴,是否支持證書(shū)鏈;
SRProxyConnect :NSObject
使用 NSStreamDelegate 代理镣屹,使用 CFNetwork 框架圃郊;
處理url的代理設(shè)置,有代理連接代理女蜈,無(wú)代理直接訪問(wèn)host持舆;
屬性:http與socket代理,SSL支持伪窖,輸入數(shù)據(jù)數(shù)組
- initWithURL:(NSURL *)url
初始化工作吏廉,檢查url是否需要SSL;
創(chuàng)建寫(xiě)數(shù)據(jù)的 dispatch_queue惰许,初始化輸入數(shù)據(jù)數(shù)組 - _configureProxy 取得系統(tǒng)代理并設(shè)置代理
_fetchPAC 根據(jù)url自動(dòng)發(fā)現(xiàn)代理席覆,再調(diào)用_runPACScript取得代理設(shè)置
_runPACScript 運(yùn)行PAC的JS腳本取得代理設(shè)置
_readProxySettingWithType 讀取http或socket代理設(shè)置保存 - _openConnection
NSStream Foundation架構(gòu)中定義
_initializeStreams 根據(jù)url跟代理配置連接參數(shù),調(diào)用CFStreamCreatePairWithSocketToHost 創(chuàng)建socket的read和write stream汹买;
NSInputStream / NSOutputStream open 打開(kāi)stream佩伤; - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode;
處理socket的read/write stream的代理事件,包括連接晦毙、錯(cuò)誤生巡、數(shù)據(jù)事件的處理;
如果stream打開(kāi)成功见妒,檢查是否有http代理孤荣,如果有發(fā)送http代理連接請(qǐng)求; - _didConnect
表示根據(jù)代理設(shè)置已連接成功的處理,返回盐股;
設(shè)置input/outputStream為nil钱豁,取消代理,回調(diào)_completion疯汁; - _writeData
這個(gè)數(shù)據(jù)只會(huì)是代理連接的請(qǐng)求數(shù)據(jù)牲尺;
將數(shù)據(jù)寫(xiě)入到outStream中,并做錯(cuò)誤與超時(shí)處理幌蚊; - _processInputStream
讀取inputStream的數(shù)據(jù)放入到input隊(duì)列中谤碳;
CFHTTPMessageAppendBytes 將數(shù)據(jù)放入到代理頭中,
調(diào)用_proxyProcessHTTPResponseWithData檢查代理是否連上了溢豆;
SRDelegateController :NSObject
設(shè)置DSP或者Operation來(lái)處理delegate的block蜒简;
IOConsumerPool :NSObject
存儲(chǔ)管理poolSize個(gè)SRIOConsumer;
- consumerWithScanner
從pool中取出一個(gè)SRIOConsumer或者創(chuàng)建一個(gè)漩仙,并設(shè)置參數(shù)返回consumer臭蚁; - returnConsumer
向pool中添加一個(gè)consumer;
IOConsumer
管理io接口屬性
- resetWithScanner
根據(jù)傳入?yún)?shù)設(shè)置stream_scanner / data_callback函數(shù)指針讯赏,設(shè)置_bytesNeeded/_readToCurrentFrame/_unmaskBytes
SRRunLoopThread :NSThread 自定義線程類
通過(guò)自定義main 中 runloop來(lái)控制循環(huán)不退出垮兑,同時(shí)記錄線程的 runloop
- main 函數(shù):添加一個(gè)空的 runloop source,并加入到 current runloop中漱挎,保持線程一直阻塞等待事件觸發(fā)系枪?
Utilities 模塊
提供各種C接口工具函數(shù)
SRHash
對(duì)數(shù)據(jù)進(jìn)行sha1或者base64編碼
SHA1: Secure Hash Algorithm 安全哈希算法
Base64:網(wǎng)絡(luò)上最常見(jiàn)的用于傳輸8Bit字節(jié)代碼的編碼方式之一,返回一個(gè)字符串磕谅;
SRHTTPConnectMessage
根據(jù)request私爷,secureKey,協(xié)議版本膊夹,cookie及協(xié)議衬浑,來(lái)生成一個(gè)CFHTTPMessageRef的Http消息頭;
CFHTTPMessageSetHeaderFieldValue:設(shè)置http消息頭的字段放刨,包括GET/Host/Cookie/Authorization/Connection/Sec-WebSocket-Key/Sec-WebSocket-Version/Sec-WebSocket-Protocol以及request中的key字段工秩;
SRURLUtilities
- SRURLRequiresSSL
取得NSURL中的host,port进统,schema組織成一個(gè) https://127.0.0.1:90像是的字符串助币; - SRURLRequiresSSL
檢查NSURL的schema中是否為wss還是https(表示SSL協(xié)議); - SRStreamNetworkServiceTypeFromURLRequest
把NSURLRequest中的networkServiceType轉(zhuǎn)換為NSStream類型的字符串螟碎;
服務(wù)類型包括:默認(rèn)正常眉菱、VoIP、Video掉分、Background俭缓、Voice及Call Signaling克伊;
SRSIMDHelpers
對(duì)數(shù)據(jù)進(jìn)行SIMD的處理,使用多數(shù)據(jù)流能夠加快數(shù)據(jù)處理华坦?
- SIMD
SIMD:Single Instruction Multiple Data 單指令多數(shù)據(jù)流愿吹,能夠復(fù)制多個(gè)操作數(shù),并把它們打包在大型寄存器的一組指令集季春;
以加法指令為例,單指令單數(shù)據(jù)(SISD)的CPU對(duì)加法指令譯碼后消返,執(zhí)行部件先訪問(wèn)內(nèi)存载弄,取得第一個(gè)操作數(shù);之后再一次訪問(wèn)內(nèi)存撵颊,取得第二個(gè)操作數(shù)宇攻;隨后才能進(jìn)行求和運(yùn)算。而在SIMD型的CPU中倡勇,指令譯碼后幾個(gè)執(zhí)行部件同時(shí)訪問(wèn)內(nèi)存逞刷,一次性獲得所有操作數(shù)進(jìn)行運(yùn)算。這個(gè)特點(diǎn)使SIMD特別適合于多媒體應(yīng)用等數(shù)據(jù)密集型運(yùn)算;
Socket Rocket 模塊
SRWebSocket
主要連接接口及數(shù)據(jù)處理在這里面
SRWebSocketDelegate : handle status and message events
Constructor / open
屬性:涉及NSURLRequest妻熊、SRSecurityPolicy夸浅、SRDelegateController、SRIOConsumer等對(duì)象扔役;
- (instancetype)initWithURLRequest:(NSURLRequest *)request protocols:(NSArray<NSString *> *)protocols allowsUntrustedSSLCertificates:(BOOL)allowsUntrustedSSLCertificates
根據(jù)請(qǐng)求URL帆喇,協(xié)議,是否接受不信任的SSL證書(shū)亿胸,來(lái)創(chuàng)建請(qǐng)求坯钦;
SRSecurityPolicy用來(lái)處理設(shè)置stream的安全策略;
這個(gè)函數(shù)用于處初始化各個(gè)參數(shù)侈玄; - open
超時(shí)處理婉刀、SRProxyConnect進(jìn)行連接;
在block中取得連接的 input/outputStream
如果需要驗(yàn)證SSL序仙,在接收到stream數(shù)據(jù)后對(duì)證書(shū)進(jìn)行驗(yàn)證突颊; - didConnect
生成隨機(jī)key,生成并發(fā)送webSocket的http連接請(qǐng)求消息潘悼;
_pumpWriting 將數(shù)據(jù)寫(xiě)入到 _outputStream 發(fā)送出去洋丐; - sendString
對(duì)數(shù)據(jù)進(jìn)行frame組織并發(fā)送給webSocket服務(wù)端;參考webSocket協(xié)議挥等;
sendString --> _sendFrameWithOpcode --> SRMaskBytesSIMD + _writeData
10. 名詞解釋
PAC:代理自動(dòng)配置友绝,一個(gè)PAC文件包含一個(gè)JS形式的函數(shù) “FindProxyForURL(url, host)” ;PAC文件中的URL可能是手工配置的肝劲,也可能是通過(guò)網(wǎng)頁(yè)的網(wǎng)咯代理自發(fā)現(xiàn)協(xié)議(Web Proxy Autodiscovery Protocol)自動(dòng)配置的迁客;