iOS使用GCDSocketManager實現長連線
阿新 • • 發佈:2018-12-29
.h檔案
#import <Foundation/Foundation.h>
#import "GCDAsyncSocket.h"
@interface GCDSocketManager : NSObject
@property(nonatomic,strong) GCDAsyncSocket *socket;
//單例
+ (instancetype)sharedSocketManager;
//連線
- (void)connectToServer;
//斷開
- (void)cutOffSocket;
@end
.m檔案
#import "GCDSocketManager.h" #define SocketHost @"地址" #define SocketPort 埠 @interface GCDSocketManager()<GCDAsyncSocketDelegate> //握手次數 @property(nonatomic,assign) NSInteger pushCount; //斷開重連定時器 @property(nonatomic,strong) NSTimer *timer; //重連次數 @property(nonatomic,assign) NSInteger reconnectCount; @end @implementation GCDSocketManager //全域性訪問點 + (instancetype)sharedSocketManager { static GCDSocketManager *_instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance; } //可以在這裡做一些初始化操作 - (instancetype)init { self = [super init]; if (self) { } return self; } #pragma mark 請求連線 //連線 - (void)connectToServer { self.pushCount = 0; self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()]; NSError *error = nil; [self.socket connectToHost:SocketHost onPort:SocketPort error:&error]; if (error) { DLog(@"SocketConnectError:%@",error); } } #pragma mark 連線成功 //連線成功的回撥 - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port { DLog(@"socket連線成功"); [self sendDataToServer]; } //連線成功後向伺服器傳送資料 - (void)sendDataToServer { //傳送資料程式碼省略... //傳送 [self.socket writeData:jsonData withTimeout:-1 tag:1]; //讀取資料 [self.socket readDataWithTimeout:-1 tag:200]; } //連線成功向伺服器傳送資料後,伺服器會有響應 - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { [self.socket readDataWithTimeout:-1 tag:200]; //伺服器推送次數 self.pushCount++; //在這裡進行校驗操作,情況分為成功和失敗兩種,成功的操作一般都是拉取資料 } #pragma mark 連線失敗 //連線失敗的回撥 - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err { DLog(@"Socket連線失敗"); self.pushCount = 0; NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSString *currentStatu = [userDefaults valueForKey:@"Statu"]; //程式在前臺才進行重連 if ([currentStatu isEqualToString:@"foreground"]) { //重連次數 self.reconnectCount++; //如果連線失敗 累加1秒重新連線 減少伺服器壓力 NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 * self.reconnectCount target:self selector:@selector(reconnectServer) userInfo:nil repeats:NO]; self.timer = timer; } } //如果連線失敗,5秒後重新連線 - (void)reconnectServer { self.pushCount = 0; self.reconnectCount = 0; //連線失敗重新連線 NSError *error = nil; [self.socket connectToHost:SocketHost onPort:SocketPort error:&error]; if (error) { DLog(@"SocektConnectError:%@",error); } } #pragma mark 斷開連線 //切斷連線 - (void)cutOffSocket { DLog(@"socket斷開連線"); self.pushCount = 0; self.reconnectCount = 0; [self.timer invalidate]; self.timer = nil; [self.socket disconnect]; } @end