美文网首页
socketTest

socketTest

作者: 倪大头 | 来源:发表于2018-02-10 09:52 被阅读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
    

    相关文章

      网友评论

          本文标题:socketTest

          本文链接:https://www.haomeiwen.com/subject/trhbaxtx.html