基于asyncSocket的Socket二次封装
创建环境信息
Mac OS X 10.10.3
Xcode 6.4
iOS 8.4
功能:
1、基于asyncSocket,进行了json和NSData的返回数据的封装,封装了心跳包,便于与服务器进行通信
2、asyncSocket为非ARC模式,需要手动切换为arc模式(-fno-objc-arc)
FJSocket 下载 FJSocket in GitHub
一、在SocketConnect.h
#import <Foundation/Foundation.h> #import "AsyncSocket.h" #import "AsyncUdpSocket.h" /** * 1、基于asyncSocket,进行了json和nsdata的返回数据的封装,封装了心跳包,便于与服务器进行通信 * 2、asyncSocket为非ARC模式,需要手动切换为arc模式(-fno-objc-arc) */ /** * 协议方法 */ @protocol SocketConnectDelegate <NSObject> - (void)receiveData:(id)object; @end @interface SocketConnect : NSObject enum ReceiveDataType{ FJJSONRequestSerializer,//返回json数据 FJHTTPRequestSerializer,//返回二进制数据 }; enum{ SocketOfflineByServer,//服务器掉线 SocketOffLineByUser,//用户手动断开 }; @property (assign,nonatomic)id<SocketConnectDelegate>delegate; //socket通信 @property (strong,nonatomic)NSString *hostIpAddress;//ip地址 @property (assign,nonatomic)NSInteger hostPort;//端口号 @property (strong,nonatomic)NSDictionary *userInfoDic;//用户登录的信息 @property (assign,nonatomic)NSInteger heartTimeInterval;//发送心跳包的时间间隔,默认20秒发送一次 @property (assign,nonatomic)NSInteger withTimeout;//设置socket超时时间,默认为10秒 //tcp Socket @property (strong,nonatomic)AsyncSocket *tcpSocket; @property (assign,nonatomic)enum ReceiveDataType receiveDataType;//设置返回接收的数据类型 + (instancetype)sharedInstance; /** * 登录服务器 * * @return 登录成功返回yes */ - (BOOL)loginServer; /** * 断开socket */ - (void)cutOffSocket;
<!-- more -->
二、在SocketConnect.m
#import "SocketConnect.h" @interface SocketConnect () @property (strong,nonatomic)NSTimer *timer;//计时器,用于发送心跳包 @end @implementation SocketConnect #pragma mark - 懒加载 - (AsyncSocket *)tcpSocket{ if (!_tcpSocket) { _tcpSocket = [[AsyncSocket alloc]initWithDelegate:self]; } return _tcpSocket; } - (NSDictionary *)userInfoDic{ if (!_userInfoDic) { _userInfoDic = [NSDictionary dictionary]; } return _userInfoDic; } //懒加载结束 #pragma mark - 初始化单例对象 + (instancetype)sharedInstance{ static SocketConnect *socketConnect = nil; static dispatch_once_t oneToken; dispatch_once(&oneToken, ^{ socketConnect = [[SocketConnect alloc]init]; }); return socketConnect; } #pragma mark - 连接服务器 - (BOOL)loginServer{ NSError *error = nil; static BOOL success; if (!self.tcpSocket.isConnected) { success = [self.tcpSocket connectToHost:self.hostIpAddress onPort:self.hostPort error:&error]; } if (success) { NSData *data = [NSJSONSerialization dataWithJSONObject:self.userInfoDic options:NSJSONWritingPrettyPrinted error:nil]; [self sendInfo:data]; } return success; } #pragma mark - 发送数据到服务器 - (void)sendInfo:(NSData *)data{ [self.tcpSocket writeData:data withTimeout:self.withTimeout == 0 ? 10 : self.withTimeout tag:0]; } #pragma mark - 通过socket协议方法,发送心跳包 - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{ [self.tcpSocket readDataWithTimeout:-1 tag:0]; //设置心跳包默认20秒发送一次 NSInteger heartPackTime = self.heartTimeInterval == 0 ? 20 : self.heartTimeInterval; self.timer = [NSTimer scheduledTimerWithTimeInterval:heartPackTime target:self selector:@selector(longConnectToSocket) userInfo:nil repeats:YES]; } - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{ if (self.receiveDataType == FJJSONRequestSerializer ) { // NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]; // NSDictionary *dic = @{@"data" : str}; NSError *error = nil; NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves|NSJSONReadingAllowFragments error:&error]; [self.delegate receiveData:error ? error.localizedDescription : dic]; }else{ [self.delegate receiveData:data]; } //设置30秒超时 [self.tcpSocket readDataWithTimeout:30 tag:0]; } #pragma mark - 长连接 发送心跳包 - (void)longConnectToSocket{ static int i = 0; NSString *longStr = [NSString stringWithFormat:@"%d\n",i]; i += 20; [self.tcpSocket writeData:[longStr dataUsingEncoding:NSUTF8StringEncoding] withTimeout:2 tag:1]; } - (void)cutOffSocket{ self.tcpSocket.userData = SocketOffLineByUser; [self.timer invalidate];//关闭心跳包的发送 [self.tcpSocket disconnect];//tcpStock失去连接 } #pragma mark - 断线重连接 - (void)onSocketDidDisconnect:(AsyncSocket *)sock{ //如果是服务器断线,重连接 if (sock.userData == SocketOfflineByServer ) { //连服务器 [self loginServer]; }else{ //用户手动断开 return; } }