美文网首页
iOS GCDAsyncSocket简单使用

iOS GCDAsyncSocket简单使用

作者: Y_3c23 | 来源:发表于2019-11-15 18:06 被阅读0次

    GCDAsyncSocket使用

    1:通过pod导入 pod 'CocoaAsyncSocket'

    2:导入头文件 #import <GCDAsyncSocket.h>

    3:.h文件 :声明变量,遵循代理,单利

    #import "SynthesizeSingleton.h"//单利

    #import GCDAsyncSocket.h

    @interface BYSocketManager : NSObject<GCDAsyncSocketDelegate>

    SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(BYSocketManager);

    @property (nonatomicstrong) GCDAsyncSocket *socket;

    @property (nonatomicretain) NSTimer *connectTimer; // 计时器

    /**

     重新连接socket

     */

    - (void)socketReconnect;

    /**

      socket连接

     */

    -(void)socketConnectHost;

    /**

      socket发送消息

     */

    -(void)socketSendMessage:(NSString*)messageText;

    /**

     断开socket连接

     */

    -(void)socketCutOff;

    /**

     是否是主动断开连接

     */

    @property(nonatomic,assign)BOOL isActiveDisconnection;

    @end

    .m文件  实现方法

    #import "BYSocketManager.h"

    @implementation BYSocketManager

    SYNTHESIZE_SINGLETON_FOR_CLASS(BYSocketManager);

    /**

     重新连接socket

     */

    - (void)socketReconnect{

        if(self.socket==nil){// 创建socket

            self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];

        }

        if (!self.socket.isConnected){// 连接socket

            NSError*error;

            [self.socket connectToHost:IP或域名 onPort:端口 withTimeout:-1error:&error];

            if(error) {

                BYLog(@"重连socket错误:::%@",error);

            }

        }

    }

    /**

      socket连接

     */

    -(void)socketConnectHost{

        if(self.socket==nil){// 创建socket

            // 并发队列,这个队列将影响delegate回调,但里面是同步函数!保证数据不混乱,一条一条来

            // 这里最好是写自己并发队列

            self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];

        }

        if (!self.socket.isConnected){ // 连接socket

            NSError*error;

            [self.socket connectToHost:IP或域名 onPort:端口 withTimeout:-1error:&error];

            if(error) {

                BYLog(@"连接socket错误:::%@",error);

            }

        }

    }

    /**

      socket发送消息

     */

    -(void)socketSendMessage:(NSString*)messageText{

        if(BYNullString(messageText)) {//检验是否为空

            return;

        }

        BYLog(@"发送的消息:::%@",messageText);

        NSData *data = [messageText dataUsingEncoding:NSUTF8StringEncoding];

        [self.socket writeData:data withTimeout:-1 tag:10086];

    }

    /**

     断开socket连接

     */

    -(void)socketCutOff{

        if (self.connectTimer) {

            [self.connectTimerinvalidate];//定时器销毁

        }

        self.isActiveDisconnection = YES;

        [self.socket disconnect];

    }

    #pragma mark socketDelegate

    //已经连接到服务器

    - (void)socket:(GCDAsyncSocket*)sockdidConnectToHost:(nonnullNSString*)hostport:(uint16_t)port{

        self.isActiveDisconnection = NO;//已连接说明连接不再断开

        BYLog(@"连接成功 : %@---%d",host,port);

        //连接成功或者收到消息,必须开始read,否则将无法收到消息==继续监听服务器的消息

        //不read的话,缓存区将会被关闭。 -1:表示无限时长 ,永久不失效。tag是标记

        [self.socket readDataWithTimeout:-1 tag:10086];

        //建立连接后立即发送登陆的json数据

        NSString * sockDict1 = [NSString stringWithFormat:@"{\"%@\":\"%@\",\"%@\":\"%@\"}",@"msg_type",@"3",@"app_type",@"ios"];

         [self.socket writeData:[sockDict1 dataUsingEncoding:NSUTF8StringEncoding] withTimeout:-1 tag:34];//向连接的socket发送登录json数据消息

         //设置定时检测

         _connectTimer = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(connectTimerRun) userInfo:nil repeats:YES];

    }

    // 连接断开

    - (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{

        BYLog(@"断开 socket连接 原因:%@",err);

        //BRYLog(@"断开连接::sorry the connect is failure %ld",sock.userData);

        if (self.isActiveDisconnection == YES) {// 如果由用户断开,不进行重连

            return;

        }else{

            [self socketReconnect];// 服务器掉线,重连

        }

    }

    //已经接收服务器返回来的数据

    - (void)socket:(GCDAsyncSocket*)sockdidReadData:(NSData*)datawithTag:(long)tag{

        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];

        BYLog(@"接收到tag = %ld : %ld 长度的数据,收到服务器消息==%@",tag,data.length,dict);

        if([dict[@"msg_type"]intValue] ==1) {

        }else if ([dict[@"msg_type"] intValue] == 9) {//BRYLog(@"收到了服务器的消息要返回给服务器数据");==心跳连接

           [self socketSendMessage:[NSString stringWithFormat:@"{\"%@\":\"%@\",\"%@\":\"%@\"}\n",@"msg_type",@"9",@"client_ok",@"1"]];

        }

        //连接成功或者收到消息,必须开始read,否则将无法收到消息==继续监听服务器的消息

        //不read的话,缓存区将会被关闭。 -1:表示无限时长 ,永久不失效。tag是标记  继续准备接受消息

        [self.socket readDataWithTimeout:-1 tag:10086];

    }

    //消息发送成功 代理函数 向服务器 发送消息

    - (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag{

        BYLog(@"%ld 发送数据成功",tag);

    }

    //定时向服务器发送消息==心跳连接

    - (void)connectTimerRun{

        [self socketSendMessage:[NSString stringWithFormat:@"{\"%@\":\"%@\"}\n",@"msg_type",@"9"]];

    }

    @end

    单利文件:SynthesizeSingleton(直接网上搜索也行,拖进你的项目中)

    引用方法:在你创建的单利文件中:

    .h文件:SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(你创建的类名);

    .m文件:SYNTHESIZE_SINGLETON_FOR_CLASS(你创建的类名);

    //

    //  SynthesizeSingleton.h

    //  ISO-Tools

    //

    //  Created by yinglong zhang on 12-12-2.

    //

    //

    #if __has_feature(objc_arc)

    #define SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(classname) \

    \

    + (classname *)shared##classname;

    #define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \

    \

    static classname *shared##classname = nil; \

    \

    + (classname *)shared##classname \

    { \

        static dispatch_once_t pred; \

        dispatch_once(&pred, ^{ shared##classname = [[classname alloc] init]; }); \

        return shared##classname; \

    }

    #else

    #define SYNTHESIZE_SINGLETON_FOR_CLASS_HEADER(classname) \

    \

    + (classname *)shared##classname;

    #define SYNTHESIZE_SINGLETON_FOR_CLASS(classname) \

    \

    static classname *shared##classname = nil; \

    \

    + (classname *)shared##classname \

    { \

        static dispatch_once_t pred; \

        dispatch_once(&pred, ^{ shared##classname = [[classname alloc] init]; }); \

        return shared##classname; \

    } \

    \

    - (id)copyWithZone:(NSZone *)zone \

    { \

        return self; \

    } \

    \

    - (id)retain \

    { \

        return self; \

    } \

    \

    - (NSUInteger)retainCount \

    { \

        return NSUIntegerMax; \

    } \

    \

    - (oneway void)release \

    { \

    } \

    \

    - (id)autorelease \

    { \

        return self; \

    }

    #endif

    相关文章

      网友评论

          本文标题:iOS GCDAsyncSocket简单使用

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