SocketRocket 介紹:
SocketRock 是 Facebook 開源的框架,基於 WebSocket 客戶端類庫,適用於 iOS、Mac OS、tv OS。GitHub 傳送門:https://github.com/facebook/SocketRocket
安裝:pod 'SocketRocket'
也可以拖入文件 SocketRocket:
引入框架:
- libicucore.dylib
- CFNetwork.framework
- Security.framework
- Foundation.framework
SocketRocket 初始化:
- (void)initSocket { if (webSocket) { return; } webSocket = [[SRWebSocket alloc] initWithURL:[NSURL URLWithString:ServerURL]]; webSocket.delegate = self; // 設置代理線程queue NSOperationQueue * queue=[[NSOperationQueue alloc]init]; queue.maxConcurrentOperationCount=1; [webSocket setDelegateOperationQueue:queue]; // 連接 [webSocket open]; }
// 初始化心跳 - (void)initHeartBeat { dispatch_main_async_safe(^{ [self destroyHeartBeat]; __weak typeof (self) weakSelf = self; //心跳設置為3分鍾,NAT超時一般為5分鍾 heartBeat = [NSTimer scheduledTimerWithTimeInterval:3*60 repeats:YES block:^(NSTimer * _Nonnull timer) { NSLog(@"heart"); //和服務端約定好發送什么作為心跳標識,盡可能的減小心跳包大小 [weakSelf sendMsg:@"heart"]; }]; [[NSRunLoop currentRunLoop] addTimer:heartBeat forMode:NSRunLoopCommonModes]; }) } // 取消心跳 - (void)destroyHeartBeat { dispatch_main_async_safe(^{ if (heartBeat) { [heartBeat invalidate]; heartBeat=nil; } }) } // 重連機制 - (void)reConnect { [self disConnect]; // 超過一分鍾就不再重連 之后重連5次 2^5=64 if (reConnectTime>64) { return; } dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(reConnectTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ webSocket=nil; [self initSocket]; }); // 重連時間2的指數級增長 if (reConnectTime == 0) { reConnectTime =2; } else { reConnectTime *=2; } }
代理方法:
#pragma mark - SRWebScokerDelegate - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message { NSLog(@"服務器返回的信息:%@",message); } - (void)webSocketDidOpen:(SRWebSocket *)webSocket { NSLog(@"連接成功"); // 連接成功 開始發送心跳 [self initHeartBeat]; } // open失敗時調用 - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error { NSLog(@"連接失敗。。。。。%@",error); // 失敗了去重連 [self reConnect]; } // 網絡連接中斷被調用 - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean { NSLog(@"被關閉連接,code:%ld,reason:%@,wasClean:%d",code,reason,wasClean); //如果是被用戶自己中斷的那么直接斷開連接,否則開始重連 if (code == DisConnectTypeByUser) { [self disConnect]; } else { [self reConnect]; } //斷開連接時銷毀心跳 [self destroyHeartBeat]; } //sendPing的時候,如果網絡通的話,則會收到回調,但是必須保證ScoketOpen,否則會crash - (void)webSocket:(SRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload { NSLog(@"收到pong回調"); }