iOS使用GCDSocketManager實現長連接

貌似進入2016年就沒再更新簡書,把寫作忘了。罪過。

OK,進入正題,開始今天的技術講解。

太概念的知識網上有很多,我只做概括和快速并正確的使用。

Socket,即使用套接字連接,實際上是對TCP/UDP的再次封裝。

在一般項目中,使用Socket的情況很少,一般都會使用http實現客戶端與服務器端的通信。并且是單向的。

但http只能通過客戶端向服務器端主動發送網絡請求,服務器會對該次請求進行響應,回傳給客戶端一些數據。如果客戶端不主動向服務器端發送網絡請求,服務器端是不能主動向客戶端做出請求/響應操作的。

所以,為了實現服務器端可以主動向客戶端發送請求,我們使用Socket來實現這一需求。


上代碼:
1、先到github下載一個非常牛逼的庫,地址:https://github.com/robbiehanson/CocoaAsyncSocket

下載到本地后,有兩個文件夾:GCD / RunLoop

我個人比較喜歡使用GCD文件。看你擅長哪個技術就選擇哪個文件吧。原理都是相同的。

2、將你想使用的文件拖到項目中。

3、一般我們使用第三方庫都不會直接使用第三庫中某個類或方法,而是對第三方庫進行再次封裝。.h文件如圖:


Snip20160424_21.png

GCDSocketManager是我封裝第三方的一個封裝類。
對外操作都靠這個類來完成。所以我使用了單例模式供全局使用。

4、.m文件


Snip20160424_23.png

幾個需要注意的點:
(1)封裝類必須要實現第三方庫的GCDAsynSocketDelegate協議
(2)握手次數:客戶端和服務器端每次連接傳遞消息都會校驗,校驗就會根據握手次數。(socket的原理不多說了)
(3)斷開重連定時器:特別需要謹記的是只有當前項目在前臺運行時才可以保持長連接的狀態,當項目進入后臺就會斷開長連接,別問為什么。如果你想在程序進入后臺扔可以接到服務器主動給你發送的消息,使用推送服務。定時器在這里的作用就是,在當前程序處于前臺,如果socket連接失敗了要讓它自動重連。每隔一段時間讓socket自動連接一次。為了運行效率著想,這個時間可以每次進行累加。
(4)重連次數:我的重連次數就是用于時間的累加,第一次連接不上就1秒后重連,第二次連接不上就2秒后重連,以此累加。

5、.m文件的具體實現

Snip20160424_24.png

繼續下一個

Snip20160424_26.png

繼續下一個

Snip20160424_27.png

繼續下一個

Snip20160424_28.png

有連接成功,肯定也會有連接失敗,以下是對失敗事件的處理:

Snip20160424_29.png

繼續下一個

Snip20160424_31.png

連接成功處理完了,連接失敗也處理完了。
做事有始有終,有連接,自然也要有斷開。

Snip20160424_32.png

好,以下是對代碼的調用時機和代碼的使用細節進行一些講解。

(1)什么時候進行長連?
長連當然是用戶登錄成功之后需要進行長連。
程序從后臺切換到前臺也需要進行長連。
所以可以把進行連接的代碼寫在根控制器中。

(2)什么時候斷開長連?
前面說過,程序進入后臺是要斷開的。所以在Application進入后臺時調用的那個生命周期方法里寫斷開長連的代碼。

(3)關于兩句很重要的代碼

Snip20160424_33.png

timeout,超時時間。根據實際需求去設置,我這里設置為-1。

tag:發送數據和讀取數據的tag值一定不能設置成一樣的。
為什么不能設置成一樣的呢?舉個例子。
在這里tag相當于一個通道,并且在這個通道中只能完成一件事情。
如果這個通道專門用來發送數據的,就給這個通道打個標簽,標簽值就是1吧。
如果這個通道專門用來讀取數據的,就給這個通道打個標簽,標簽紙就是200把。
數值隨便定義,只能你能確保兩者的tag值不一樣。

但還有一個細節需要注意。

Snip20160424_34.png

我在上圖代碼中再次調用了讀取數據的代碼,這里的tag值要始終保持一致。

那么在這里寫這句代碼有啥用呢?
在寫這句代碼前,我們已經在連接成功的代理方法中寫了這句代碼。
在上圖的代理方法中我可以讀取服務器響應的數據。
讀取完這一次服務器響應的數據后,下一次服務器再次發送數據我們該怎么讀取?
就是通過這句代碼,所以在這里再寫一次。
這樣我們就可以保證每次服務器響應的數據,我們客戶端都可以正常讀取了。

6、心跳包
心跳包。。就是一個數據包。
每隔一段時間向服務器傳輸一次你的數據。
當然是使用定時器實現了。代碼就不上了哈。
到這里,又出現了一個新問題。
剛才已經說了,程序在前臺才能保持長連。
程序進入后臺長連就斷了。
那么,當程序在后臺時依然需要每隔一段時間向服務器發送一次心跳包,這個需求,怎么實現?
請聽下回講解。

代碼連接:http://www.lxweimin.com/p/60fd4ae4cd74

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,992評論 19 139
  • 1、TCP狀態linux查看tcp的狀態命令:1)、netstat -nat 查看TCP各個狀態的數量2)、lso...
    北辰青閱讀 9,528評論 0 11
  • iPhone的標準推薦是CFNetwork 庫編程,其封裝好的開源庫是 cocoa AsyncSocket庫,用它...
    Ethan_Struggle閱讀 2,283評論 2 12
  • 第一部分、概念的理解1、什么是Socket?Socket又稱之為“套接字”,是系統提供的用于網絡通信的方法。它的實...
    Hevin_Chen閱讀 2,484評論 0 5
  • 一 、 回憶里,我們的開始 人生中第一次出遠門,是去上大學,然而我卻是一個東南西北分不清的路...
    遠方WZY閱讀 379評論 3 3