SocketRocket - facebook

socketRocket

WebSocket 協(xié)議

百度百科
http://www.tuicool.com/articles/7zyMvy6

HTML5一種新的協(xié)議,實(shí)現(xiàn)了瀏覽器與服務(wù)器全雙工通信,一開始的握手需要借助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é)議;


Paste_Image.png

多出的 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 方法說明
(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ù)完成偶才開始執(zhí)行其他任務(wù)
    addOperation

  • __bridge
    __bridge 關(guān)鍵字來實(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來創(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ì)

Paste_Image.png

4. 模塊

Internal 模塊

SRPinningSecurityPolicy : SRSecurityPolicy

使用 Security 框架

  • evaluateServerTrust
    遍歷serverTrust對(duì)象,檢查是否與pinnedCertificates中的某個(gè)證書一致,當(dāng)驗(yàn)證所有pinned證書都正確時(shí),返回YES,否則NO;
  • updateSecurityOptionsInStream
    設(shè)置NSStream對(duì)象的安全屬性策略,支持TLS,是否支持證書鏈;
SRProxyConnect :NSObject

使用 NSStreamDelegate 代理,使用 CFNetwork 框架;
處理url的代理設(shè)置,有代理連接代理,無代理直接訪問host;
屬性:http與socket代理,SSL支持,輸入數(shù)據(jù)數(shù)組

  • initWithURL:(NSURL *)url
    初始化工作,檢查url是否需要SSL;
    創(chuàng)建寫數(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 打開stream;
  • (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode;
    處理socket的read/write stream的代理事件,包括連接、錯(cuò)誤、數(shù)據(jù)事件的處理;
    如果stream打開成功,檢查是否有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ù)寫入到outStream中,并做錯(cuò)誤與超時(shí)處理;
  • _processInputStream
    讀取inputStream的數(shù)據(jù)放入到input隊(duì)列中;
    CFHTTPMessageAppendBytes 將數(shù)據(jù)放入到代理頭中,
    調(diào)用_proxyProcessHTTPResponseWithData檢查代理是否連上了;
SRDelegateController :NSObject

設(shè)置DSP或者Operation來處理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 自定義線程類

通過自定義main 中 runloop來控制循環(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ò)上最常見的用于傳輸8Bit字節(jié)代碼的編碼方式之一,返回一個(gè)字符串;

SRHTTPConnectMessage

根據(jù)request,secureKey,協(xié)議版本,cookie及協(xié)議,來生成一個(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í)行部件先訪問內(nèi)存,取得第一個(gè)操作數(shù);之后再一次訪問內(nèi)存,取得第二個(gè)操作數(shù);隨后才能進(jìn)行求和運(yùn)算。而在SIMD型的CPU中,指令譯碼后幾個(gè)執(zhí)行部件同時(shí)訪問內(nèi)存,一次性獲得所有操作數(shù)進(jìn)行運(yùn)算。這個(gè)特點(diǎn)使SIMD特別適合于多媒體應(yīng)用等數(shù)據(jù)密集型運(yùn)算;

Socket Rocket 模塊

Paste_Image.png
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證書,來創(chuàng)建請(qǐng)求;
    SRSecurityPolicy用來處理設(shè)置stream的安全策略;
    這個(gè)函數(shù)用于處初始化各個(gè)參數(shù);
  • open
    超時(shí)處理、SRProxyConnect進(jìn)行連接;
    在block中取得連接的 input/outputStream
    如果需要驗(yàn)證SSL,在接收到stream數(shù)據(jù)后對(duì)證書進(jìn)行驗(yàn)證;
  • didConnect
    生成隨機(jī)key,生成并發(fā)送webSocket的http連接請(qǐng)求消息;
    _pumpWriting 將數(shù)據(jù)寫入到 _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可能是手工配置的,也可能是通過網(wǎng)頁的網(wǎng)咯代理自發(fā)現(xiàn)協(xié)議(Web Proxy Autodiscovery Protocol)自動(dòng)配置的;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • *面試心聲:其實(shí)這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,581評(píng)論 30 472
  • 史上最全的iOS面試題及答案 iOS面試小貼士———————————————回答好下面的足夠了----------...
    Style_偉閱讀 2,557評(píng)論 0 35
  • 多線程、特別是NSOperation 和 GCD 的內(nèi)部原理。運(yùn)行時(shí)機(jī)制的原理和運(yùn)用場(chǎng)景。SDWebImage的原...
    LZM輪回閱讀 2,108評(píng)論 0 12
  • ———————————————回答好下面的足夠了---------------------------------...
    恒愛DE問候閱讀 1,835評(píng)論 0 4

友情鏈接更多精彩內(nèi)容