接觸WebSocket
考慮到普通的HTTP 通信方式只能由客戶端主動拉取,服務器不能主動推給客戶端 。然后就想出的2種解決方案。
1.和后台溝通了一下 他們那里使用的是WebSocket ,所以就使用WebSocket讓我們app端和服務器建立長連接。這樣就可以事實接受他發過來的消息
2.使用推送,也可以實現接收后台發過來的一些消息
最后還是選擇了WebSocket,找到了facebook的 SocketRocket 框架。下面是接入過程中的一些記錄
WebSocket
WebSocket 是 HTML5 一種新的協議。它實現了瀏覽器與服務器全雙工通信,能更好的節省服務器資源和帶寬並達到實時通訊,它建立在 TCP 之上,同 HTTP 一樣通過 TCP 來傳輸數據,但是它和 HTTP 最大不同是:
WebSocket 是一種雙向通信協議,在建立連接后,WebSocket 服務器和 Browser/Client Agent 都能主動的向對方發送或接收數據,就像 Socket 一樣;
WebSocket 需要類似 TCP 的客戶端和服務器端通過握手連接,連接成功后才能相互通信。
具體在這兒 WebSocket 是什么原理?為什么可以實現持久連接?
用法
我使用的是pod管理庫 所以在podfile中加入pod 'SocketRocket'
在使用命令行工具cd到當前工程 安裝pod install
如果是copy的工程中的 SocketRocket庫的github地址:SocketRocket
導入庫到工程中以后首先封裝一個SocketRocketUtility單例
SocketRocketUtility.m文件中的寫法如下:
#import "SocketRocketUtility.h" #import <SocketRocket.h> NSString * const kNeedPayOrderNote = @"kNeedPayOrderNote";//發送的通知名稱 @interface SocketRocketUtility()<SRWebSocketDelegate> { int _index; NSTimer * heartBeat; NSTimeInterval reConnectTime; } @property (nonatomic,strong) SRWebSocket *socket; @end @implementation SocketRocketUtility + (SocketRocketUtility *)instance { static SocketRocketUtility *Instance = nil; static dispatch_once_t predicate; dispatch_once(&predicate, ^{ Instance = [[SocketRocketUtility alloc] init]; }); return Instance; } //開啟連接 -(void)SRWebSocketOpenWithURLString:(NSString *)urlString { if (self.socket) { return; } if (!urlString) { return; } //SRWebSocketUrlString 就是websocket的地址 寫入自己后台的地址 self.socket = [[SRWebSocket alloc] initWithURLRequest: [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]]; self.socket.delegate = self; //SRWebSocketDelegate 協議 [self.socket open]; //開始連接 } //關閉連接 - (void)SRWebSocketClose { if (self.socket){ [self.socket close]; self.socket = nil; //斷開連接時銷毀心跳 [self destoryHeartBeat]; } } #pragma mark - socket delegate - (void)webSocketDidOpen:(SRWebSocket *)webSocket { NSLog(@"連接成功,可以與服務器交流了,同時需要開啟心跳"); //每次正常連接的時候清零重連時間 reConnectTime = 0; //開啟心跳 心跳是發送pong的消息 我這里根據后台的要求發送data給后台 [self initHeartBeat]; [[NSNotificationCenter defaultCenter] postNotificationName:kWebSocketDidOpenNote object:nil]; } - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error { NSLog(@"連接失敗,這里可以實現掉線自動重連,要注意以下幾點"); NSLog(@"1.判斷當前網絡環境,如果斷網了就不要連了,等待網絡到來,在發起重連"); NSLog(@"2.判斷調用層是否需要連接,例如用戶都沒在聊天界面,連接上去浪費流量"); NSLog(@"3.連接次數限制,如果連接失敗了,重試10次左右就可以了,不然就死循環了。)"; _socket = nil; //連接失敗就重連 [self reConnect]; } - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean { NSLog(@"被關閉連接,code:%ld,reason:%@,wasClean:%d",code,reason,wasClean);