socketTest

2018-02-10  本文已影响34人  倪大头
//调用
- (void)socketTest {
    [singleSocket sharedInstance].socketHost = @"xxx.xxx.x.xxx";//host设定
    [singleSocket sharedInstance].socketPort = 10000;// port设定

    // 在连接前先进行手动断开
    [singleSocket sharedInstance].socket.userData = SocketOfflineByUser;
    [[singleSocket sharedInstance] cutOffSocket];

    // 确保断开后再连,如果对一个正处于连接状态的socket进行连接,会出现崩溃
    [singleSocket sharedInstance].socket.userData = SocketOfflineByServer;
    [[singleSocket sharedInstance] socketConnectHost];
}
//singleSocket.h:
#import <Foundation/Foundation.h>
#import "AsyncSocket.h"

enum {
    SocketOfflineByServer,// 服务器掉线,默认为0
    SocketOfflineByUser,  // 用户主动cut
};

@interface singleSocket : NSObject<AsyncSocketDelegate>

@property (nonatomic, strong) AsyncSocket    *socket;       // socket
@property (nonatomic, copy  ) NSString       *socketHost;   // socket的Host
@property (nonatomic, assign) UInt16         socketPort;    // socket的prot
@property (nonatomic, retain) NSTimer        *connectTimer; // 计时器

+ (singleSocket *)sharedInstance;

- (void)socketConnectHost;//socket连接

- (void)cutOffSocket;//断开socket连接

@end
//singleSocket.m:
#import "singleSocket.h"
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <unistd.h>

@implementation singleSocket

+ (singleSocket *)sharedInstance {
    static singleSocket *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[self alloc]init];
    });
    
    return sharedInstance;
}

//socket连接
- (void)socketConnectHost {
    self.socket = [[AsyncSocket alloc]initWithDelegate:self];
    NSError *error = nil;
    [self.socket connectToHost:self.socketHost onPort:self.socketPort withTimeout:3 error:&error];
}

#pragma mark  - 连接成功回调
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {
    NSLog(@"socket连接成功");
    //每隔s向服务器发送心跳包
    self.connectTimer = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(longConnectToSocket) userInfo:nil repeats:YES];//在longConnectToSocket方法中进行长连接需要向服务器发送的讯息
    [self.connectTimer fire];
}

//心跳连接
- (void)longConnectToSocket {
    //根据服务器要求发送固定格式的数据,假设为指令@"longConnect",但是一般不会是这么简单的指令
    //NSString *longConnect = @"textStr";
    //NSData *dataStream  = [longConnect dataUsingEncoding:NSUTF8StringEncoding];
    
    //[self.socket writeData:dataStream withTimeout:1 tag:1];
    
    NSMutableData *socketData = [NSMutableData data];
    
    //length 4个字节
    uint32_t lengthbytes = 29;
    NSData *lengthData = [NSData dataWithBytes:&lengthbytes length:sizeof(uint32_t)];
    
    [socketData appendData:lengthData];
    
    //type 1个字节
    Byte typebytes[1] = {0x10};
    NSData *typeData = [NSData dataWithBytes:typebytes length:1];
    
    [socketData appendData:typeData];
    
    //uid 4个字节
    uint32_t uidbytes = (uint32_t)[AXUserModel sharedUseInfo].userId;
    NSData *uidData = [NSData dataWithBytes:&uidbytes length:sizeof(uint32_t)];
    
    [socketData appendData:uidData];
    
    //oid(对方id) 4个字节
    uint32_t oidbytes = (uint32_t)[AXUserModel sharedUseInfo].userId;
    NSData *oidData = [NSData dataWithBytes:&oidbytes length:sizeof(uint32_t)];
    
    [socketData appendData:oidData];
    
    //经纬度
    double longitudebytes = [AXManager sharedManager].currentCityMJLng;
    NSData *longitudeData = [NSData dataWithBytes:&longitudebytes length:8];
    double latitudebytes = [AXManager sharedManager].currentCityMJLat;
    NSData *latitudeData = [NSData dataWithBytes:&latitudebytes length:8];
    
    [socketData appendData:longitudeData];
    [socketData appendData:latitudeData];
    
    
    [self.socket writeData:socketData withTimeout:15 tag:1];
}

//数据发送成功
- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag {
    NSLog(@"%s",__func__);
    
    //发送完数据手动读取,-1不设置超时
    [sock readDataWithTimeout:-1 tag:tag];
}

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    // 对得到的data值进行解析与转换即可
    [self.socket readDataWithTimeout:30 tag:0];
}

//切断socket
- (void)cutOffSocket {
    self.socket.userData = SocketOfflineByUser;//声明是由用户主动切断
    [self.connectTimer invalidate];
    [self.socket disconnect];
}

//重连
- (void)onSocketDidDisconnect:(AsyncSocket *)sock {
    NSLog(@"长链接断开 %ld",sock.userData);
    if (sock.userData == SocketOfflineByServer) {
        // 服务器掉线,重连
        [self socketConnectHost];
    }else if (sock.userData == SocketOfflineByUser) {
        // 如果由用户断开,不进行重连
        return;
    }
}

@end
上一篇下一篇

猜你喜欢

热点阅读