套接字(通信雙方C/S協商好的約定
),網絡上兩個程序經過一個雙向的通訊鏈接實現數據的交換,這個連接的一端稱爲一個Socket.
應用程序經過套接字向網絡發出請求或者應答網絡請求。
java
網絡請求就是經過Socket創建鏈接而後互相通訊git
通信的規則
)必須創建鏈接,效率會下降
不須要創建鏈接,速度快
使用CocoaAsyncSocket第三方庫程序員
Telnet命令 $telnet host port/telnet 192.168.10.10 5288
監聽服務端某個端口對應的服務有沒有開啓shell
超文本傳輸協議,訪問的是遠程的網絡資源,格式是http://數據庫
http1.1,content-type:multipart/form-data,content-length:188,body:username=zhangsan&password=123456
可擴展的數據傳輸協議,基於XML的即時通信協議,它用於及時通信(IM),目的是爲了保持長鏈接,以實現即時通信功能。
傳輸格式:(標籤對)緩存
<from>zhangsan<from> <to>lisi<to> <body>一塊兒吃晚上</body>
基本形式:單客戶端經過TCP/IP鏈接到單服務器,而後在之上傳輸XML流.
(XMPP相似於HTTP的數據傳輸協議,其過程就如同」解包裝->包裝」的過程),只須要理解其接收的類型和返回的類型,即可以很好的利用XMPP進行數據通信。XMPP官網-http://xmpp.org
即時通信準備工做:
下載Openfire服務器
下載XMPPFramework框架
解析XML框架KissXML
Openfire服務器默認端口5288安全
自動鏈接 : 若是網絡不經過,用戶應該自動鏈接到服務器,以及時接收消息
自動鏈接機制:2的n次方鏈接
服務器
1.環信是一個即時通訊的服務提供商
2.環信使用的是XMPP協議,它是再XMPP的基礎上進行二次開發,對服務器Openfire和客戶端進行功能模型的添加和客戶端SDK的封裝,環信的本質仍是使用XMPP,基本於Socket的網絡通訊
3.環信內部實現了數據緩存,會把聊天記錄添加到數據庫,把附件下載到本地,程序員更多時間是花到界面用戶體驗上
4.環信內部已經實現了視頻,音頻,圖片,其它附件發送功能
5.環信使用公司能夠節約時間成本
不須要公司內部搭建服務器
客戶端的開發,使用環信SDK比使用XMPPFramework更簡潔方便網絡
遙信消息隊列傳輸,輕量級的XMPP,基於TCP的發佈訂閱協議 通常用於物聯網(硬件交互
)框架
客戶端發送一個心跳給服務端,服務端給客戶端一個心跳應答(以保持長鏈接),若是超過一個時間的閾值,客戶端沒有收到服務端的應答或者服務器沒有收到客戶端的心跳,那麼客戶端會斷開鏈接而後從新創建一個鏈接,服務器只須要斷開這個鏈接便可。
實現方式:
實現MQTT協議須要客戶端和服務器端通信完成,在通信過程當中,MQTT協議中有三種身份:發佈者(Publish)、代理(Broker)(服務器)、訂閱者(Subscribe)。其中,消息的發佈者和訂閱者都是客戶端,消息代理是服務器,消息發佈者能夠同時是訂閱者。
基於Scoket
原生:表明框架 CocoaAsyncSocket
。
基於WebScoket
:表明框架 SocketRocket
。
基於MQTT
:表明框架 MQTTKit
。
基於XMPP
:表明框架 XMPPFramework
。
1客戶端每隔一個時間間隔發生一個探測包給服務器
2客戶端發包時啓動一個超時定時器
3服務器端接收到檢測包,應該回應一個包
4若是客戶機收到服務器的應答包,則說明服務器正常,刪除超時定時器
5若是客戶端的超時定時器超時,依然沒有收到應答包,則說明服務器掛了
SR_CLOSING、SR_CLOSED重連
- (void)reConnect { [self SRWebSocketClose]; //超過一分鐘就再也不重連 因此只會重連5次 2^5 = 64 if (self.reConnectTime >= 1024) { //就是這麼調皮 return; } dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.reConnectTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ self.socket = nil; [self SRWebSocketOpenWithURLString:self.urlString]; //NSLog(@"重連"); }); //重連時間2的指數級增加 if (self.reConnectTime == 0) { self.reConnectTime = 2; }else{ self.reConnectTime *= 2; } }