iOS--SocketRocket框架的使用及測試服務(wù)器的搭建

什么是socket?

Socket 其實(shí)并不是一個協(xié)議。它工作在 OSI 模型會話層(第5層),是為了方便大家直接使用更底層協(xié)議(一般是TCP 或 UDP )而存在的一個抽象層。Socket是對TCP/IP協(xié)議的封裝,Socket本身并不是協(xié)議,而是一個調(diào)用接口(API)。


20160526230432824.png

Socket通常也稱作”套接字”,用于描述IP地址和端口,是一個通信鏈的句柄。網(wǎng)絡(luò)上的兩個程序通過一個雙向的通訊連接實(shí)現(xiàn)數(shù)據(jù)的交換,這個雙向鏈路的一端稱為一個Socket,一個Socket由一個IP地址和一個端口號唯一確定。應(yīng)用程序通常通過”套接字”向網(wǎng)絡(luò)發(fā)出請求或者應(yīng)答網(wǎng)絡(luò)請求。
Socket在通訊過程中,服務(wù)端監(jiān)聽某個端口是否有連接請求,客戶端向服務(wù)端發(fā)送連接請求,服務(wù)端收到連接請求向客戶端發(fā)出接收消息,這樣一個連接就建立起來了。客戶端和服務(wù)端也都可以相互發(fā)送消息與對方進(jìn)行通訊,直到雙方連接斷開。

什么是WebSocket?

Websocket是應(yīng)用層第七層上的一個應(yīng)用層協(xié)議,它必須依賴 HTTP 協(xié)議進(jìn)行一次握手 ,握手成功后,數(shù)據(jù)就直接從 TCP 通道傳輸,與 HTTP 無關(guān)了。
Websocket的數(shù)據(jù)傳輸是frame形式傳輸?shù)?,比如會將一條消息分為幾個frame,按照先后順序傳輸出去。這樣做會有幾個好處:
1 大數(shù)據(jù)的傳輸可以分片傳輸,不用考慮到數(shù)據(jù)大小導(dǎo)致的長度標(biāo)志位不足夠的情況。
2 和http的chunk一樣,可以邊生成數(shù)據(jù)邊傳遞消息,即提高傳輸效率。

SocketRocket框架

使用cocoapods導(dǎo)入SocketRocket框架

platform :ios,"7.0"

target "WebScoketTest" do
pod 'SocketRocket'

end

框架并不開源,我們只能看到對外封裝的一些方法。
一部分為SRWebSocket的初始化,以及連接,關(guān)閉連接,發(fā)送消息等方法。另一部分為SRWebSocketDelegate,其中包括一些回調(diào):收到消息的回調(diào),連接失敗的回調(diào),關(guān)閉連接的回調(diào),收到pong的回調(diào),是否需要把data消息轉(zhuǎn)換成string的代理方法。

使用框架

點(diǎn)擊下載例子
其中包括了一個簡單的心跳,重連機(jī)制和websocket封裝好的pingpong機(jī)制
部分代碼:

D5EEF738-B9B9-411C-A065-3CCAF17F3B54.png
BBC96522-2A6E-4CC5-BD67-6150E6ABFF10.png
(1)什么是心跳?

簡單的來說,心跳就是用來檢測TCP連接的雙方是否可用。那又會有人要問了,TCP不是本身就自帶一個KeepAlive機(jī)制嗎?
?這里我們需要說明的是TCP的KeepAlive機(jī)制只能保證連接的存在,但是并不能保證客戶端以及服務(wù)端的可用性.
?我們客戶端發(fā)起心跳Ping(一般都是客戶端),假如設(shè)置在10秒后如果沒有收到回調(diào),那么說明服務(wù)器或者客戶端某一方出現(xiàn)問題,這時候我們需要主動斷開連接。
?服務(wù)端也是一樣,會維護(hù)一個socket的心跳間隔,當(dāng)約定時間內(nèi),沒有收到客戶端發(fā)來的心跳,我們會知道該連接已經(jīng)失效,然后主動斷開連接。
?國內(nèi)移動無線網(wǎng)絡(luò)運(yùn)營商在鏈路上一段時間內(nèi)沒有數(shù)據(jù)通訊后, 會淘汰NAT表中的對應(yīng)項(xiàng), 造成鏈路中斷。而國內(nèi)的運(yùn)營商一般NAT超時的時間為5分鐘,所以通常我們心跳設(shè)置的時間間隔為3-5分鐘。

(2)什么是pingpong機(jī)制?
2702646-6e51be4cf4ba7b11.jpg

? 當(dāng)服務(wù)端發(fā)出一個Ping,客戶端沒有在約定的時間內(nèi)返回響應(yīng)的ack,則認(rèn)為客戶端已經(jīng)不在線,這時我們Server端會主動斷開Scoket連接,并且改由APNS推送的方式發(fā)送消息。
? 同樣的是,當(dāng)客戶端去發(fā)送一個消息,因?yàn)槲覀冞t遲無法收到服務(wù)端的響應(yīng)ack包,則表明客戶端或者服務(wù)端已不在線,我們也會顯示消息發(fā)送失敗,并且斷開Scoket連接。
? 還記得我們之前CocoaSyncSockt的例子所講的獲取消息超時就斷開嗎?其實(shí)它就是一個PingPong機(jī)制的客戶端實(shí)現(xiàn)。我們每次可以在發(fā)送消息成功后,調(diào)用這個超時讀取的方法,如果一段時間沒收到服務(wù)器的響應(yīng),那么說明連接不可用,則斷開Scoket連接

(3)什么是重連機(jī)制?

理論上,我們自己主動去斷開的Scoket連接(例如退出賬號,APP退出到后臺等等),不需要重連。其他的連接斷開,我們都需要進(jìn)行斷線重連。
?一般解決方案是嘗試重連幾次,如果仍舊無法重連成功,那么不再進(jìn)行重連。

webSocket服務(wù)端的實(shí)現(xiàn)

(1)安裝Homebrew

終端運(yùn)行:

// 鏈接1
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
(2)成功后,安裝node

$ brew install node

(3)安裝ws模塊

$ npm install ws
此時如果出現(xiàn)錯誤

npm WARN enoent ENOENT: no such file or directory

可以使用$ npm init -f命令生成一下

(4)cd到下載的js文件路徑下

執(zhí)行$ node 文件名.js
此時運(yùn)行下載的demo,試試看吧!

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

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

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