zoukankan      html  css  js  c++  java
  • socket长连接 GCDAsyncSocket

    基础: http://www.2cto.com/kf/201609/546974.html

    转自: http://blog.csdn.net/u013282507/article/details/52621434

    本篇文章的例子主要实现通过socket实时接收数据的一个图文直播的功能模块,代码为socket工具类。利用的工具是GCDAsyncSocket;

    工具类主要有三个功能模块:

    一、建立Socket连接,实现心跳连接,实现通过socket接收数据。

    类名 Socket.h

    二、数据处理模块,处理接收到的数据,避免粘包问题。

    类名DataContro.h

    三、断线重连模块,当socket断开时,重新启动一个新的socket请求,定时请求服务器,当连接成功时通知当前socket重新连接。

    类名ReconnectControl.h

    Socket类的创建方法如下:

    [objc] view plain copy
     
    1. [Socket sharedInstance].socketHost = @"wei.fm.hebrbtv.com";// host设定  
    2. [Socket sharedInstance].socketPort = 9004;// port设定  
    3. // 在连接前先进行手动断开  
    4. [Socket sharedInstance].socket.userData = SocketOfflineByUser;  
    5. [[Socket sharedInstance] cutOffSocket];  
    6. // 确保断开后再连,如果对一个正处于连接状态的socket进行连接,会出现崩溃  
    7. [[Socket sharedInstance] socketConnectHost:^{  
    8. }];  
    9. [Socket sharedInstance].socket.userData = SocketOfflineByServer;  

    使用时需要添加几个通知方法

    [objc] view plain copy
     
    1. //接收新消息通知  
    2. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(insertMessage:) name:SocketNewMessageNotification object:nil];  
    3. //socket断开通知  
    4. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(socketConnectError) name:SocketConnectErrorNotification object:nil];  
    5. //socket连接通知  
    6. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(socketConnectSuccess) name:SocketConnectSuccessNotification object:nil];  


    一、说一下Socket类里面的具体实现方法

    连接方法

    GCDAsyncSocket创建时需要添加一个线程 这里使用主线程,开启成功后即开启了一个通道,也可以理解为一个水管,后台通过这个通道不定时的发送数据过来。

     

     

    [objc] view plain copy
     
    1. // socket连接  
    2. -(void)socketConnectHost:(VoidBlock)block  
    3. {  
    4.     //数据处理类清楚历史数据  
    5.     [[DataControl shareControl] clearData];  
    6.     //回调方法  
    7.     _block = block;  
    8.     //连接socket  
    9.     self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];  
    10.     NSError *error = nil;  
    11.     [self.socket connectToHost:self.socketHost onPort:self.socketPort withTimeout:3 error:&error];  
    12. }  


    连接成功后进行数据读取,开启心跳连接;之后会在GCDAsyncSocket的代理方法中获取后台发送的数据。

     

    [objc] view plain copy
     
    1. /** 
    2.  连接成功 
    3.  */  
    4. -(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port  
    5. {  
    6.     if (_block) {  
    7.         _block();  
    8.     }  
    9.     //读取socket中的数据  
    10.     [self readData];  
    11.     // 每隔30s像服务器发送心跳包  
    12.     _connectTimer = [NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(longConnectToSocket) userInfo:nil repeats:YES];// 在longConnectToSocket方法中进行长连接需要向服务器发送的讯息  
    13.     [_connectTimer fire];  
    14. }  

    心跳连接:

     

    [objc] view plain copy
     
    1. // 心跳连接  
    2. -(void)longConnectToSocket{  
    3.       
    4.     // 根据服务器要求发送固定格式的数据,假设为指令@".",但是一般不会是这么简单的指令  
    5.     NSString *longConnect = @". ";  
    6.     NSData   *dataStream  = [longConnect dataUsingEncoding:NSUTF8StringEncoding];  
    7.     [self writeData:dataStream];  
    8. }  

    读取数据方法如下,这里加入了一个数据处理类,防止粘包现象,具体原理会在下面说明

     

    [objc] view plain copy
     
    1. /** 
    2.  收到服务器的数据,读取数据成功后通过SocketDataControl处理,防止粘包 
    3.  */  
    4. -(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag  
    5. {  
    6.     [self readData];  
    7.     NSLog(@"读取成功");  
    8.     __block NSMutableArray *arr = [NSMutableArray new];  
    9.     [[DataControl shareControl] appendingData:data newData:^(NSMutableArray *models) {  
    10.         [self performSelector:@selector(sendMessage:) withObject:models];  
    11.         arr = models;  
    12.     }];  
    13. }  

    二、收处理模块:

      处理Socket数据粘包问题

    三、断线重连模块

      Socket 断线重连问题

  • 相关阅读:
    (七)linux 学习 -- 键盘高级操作技巧
    (六)linux 学习 -- 从 shell 眼中看世界
    (五)linux 学习 --重定向
    (四)linux 学习 --使用命令
    (三)linux 学习 --操作文件和目录
    JavaScript封装好的方法
    覆盖Html5默认样式
    CSS的布局整理
    Vue学习笔记
    博客园添加和隐藏导航菜单
  • 原文地址:https://www.cnblogs.com/daxueshan/p/7007179.html
Copyright © 2011-2022 走看看