基于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;
    }

}


赞一个 (1)
分享到: +More

评论 沙了个发

换个身份

取消评论