iOS AsyncSocket使用教程

  • 使用AsyncSocket的時候可以做一層封裝,根據(jù)需求提供幾個接口出來。比如:連接、斷開連接、發(fā)送消息等等。還有接受消息,接受到的消息可以通過通知、代理、block等傳出去。
  • 對AsyncSocket使用.一般來說,一個用戶只需要建立一個socket長連接,所以可以用單例類方便使用。
使用AsyncSocket

1.創(chuàng)建socket的單例類

//在LGSocketServe.h 
#import <Foundation/Foundation.h>
#import "AsyncSocket.h"
#import "GCDAsyncSocket.h"
@interface LGSocketServe : NSObject
//創(chuàng)建屬性 用于連接
@property (nonatomic, strong, readonly) GCDAsyncSocket          *socket;
@property (nonatomic, copy,   readonly) NSString                *socketHost;
@property (nonatomic, assign, readonly) uint16_t                socketPort;

//創(chuàng)建單列類
+(instancetype)shareSocket;
@end



//在LGSocketServe.m
#import "LGSocketServe.h"
#import <UIKit/UIKit.h>

@interface LGSocketServe ()

@property (nonatomic, strong, readwrite) GCDAsyncSocket         *socket;
@property (nonatomic, copy,   readwrite) NSString               *socketHost;
@property (nonatomic, assign, readwrite) uint16_t               socketPort;

@end

@implementation LGSocketServe 

+(instancetype)shareSocket
{
    static dispatch_once_t onceToken;
    static LGSocketServe *socket;
    dispatch_once(&onceToken, ^{
        socket = [[LGSocketServe alloc]init];
    });
    return socket;
}
- (instancetype)init
{
    self = [super init];
    if (self) {
        self.socket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_global_queue(0, 0)];
    }
    return self;
}
//創(chuàng)建連接
- (void)connected:(NSString *)host onPort:(uint16_t)port error:(NSError *)error{
    self.socketHost = host;
    self.socketPort = port;
    //必須確認(rèn)在斷開連接的情況下,進(jìn)行連接
    if (self.socket.isDisconnected) {
        [self.socket connectToHost:self.socketHost onPort:self.socketPort error:nil];
    }else{
        [self.socket disconnect];
        [self.socket connectToHost:self.socketHost onPort:self.socketPort error:nil];
    }
    [self.socket connectToHost:host onPort:port error:nil];
}
//心跳連接
-(void)longConnectToSocket{
    // 根據(jù)服務(wù)器要求發(fā)送固定格式的數(shù)據(jù),假設(shè)為指令@"longConnect",但是一般不會是這么簡單的指令
    NSString *longConnect = @"longConnect\r\n";
    NSData   *dataStream  = [longConnect dataUsingEncoding:NSUTF8StringEncoding];
    [self.socket writeData:dataStream withTimeout:-1 tag:0];
}
//連接成功
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
    //每隔特定時間向服務(wù)器發(fā)送心跳包
    //在longConnectToSocket方法中進(jìn)行長連接需要向服務(wù)器發(fā)送特定信息
    self.longConnectTimer
    = [NSTimer timerWithTimeInterval:kSocketConnectTimerTimeInterval
                              target:self
                            selector:@selector(longConnectToSocket)
                            userInfo:nil
                             repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.longConnectTimer
                                 forMode:NSRunLoopCommonModes];
}
//斷開連接
- (void)disConnected{

    [self.socket disconnect];
}
//斷開之后重新連接
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
    //這里可以列舉枚舉值
    //因用戶自動斷開 不自動連接
    if (self.offlineError == SZYSocketOfflineByServer) {
        [self.longConnectTimer invalidate];
        self.longConnectTimer = nil;
        [self.socket setDelegate:nil];
        [self.socket disconnect];
    //因服務(wù)器原因斷開 自動連接
    }else if (self.offlineError == SZYSocketOfflineByServer){
    
        [self.longConnectTimer invalidate];
        self.longConnectTimer = nil;
        [self.socket setDelegate:nil];
        [self.socket disconnect];
        [self.socket setDelegate:self];
        [self.socket connectToHost:self.socketHost
                            onPort:self.socketPort
                             error:nil];
    //因Wifi原因斷開 不自動連接
    }else{
        [self.longConnectTimer invalidate];
        self.longConnectTimer = nil;
        [self.socket setDelegate:nil];
        [self.socket disconnect];
    }
    
}
//寫入數(shù)據(jù)
- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag{

    [self.socket writeData:data withTimeout:-1 tag:100];
}
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"讀取到的消息:%@", dataString);
}
//讀取數(shù)據(jù)
- (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag{
    [self.socket readDataToData:data withTimeout:-1 tag:100];
    
}
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
    NSLog(@"didWriteDataWithTag");
}

有錯誤歡迎留言指正

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • iPhone的標(biāo)準(zhǔn)推薦是CFNetwork 庫編程,其封裝好的開源庫是 cocoa AsyncSocket庫,用它...
    Ethan_Struggle閱讀 2,357評論 2 12
  • 轉(zhuǎn)載:http://www.cocoachina.com/ios/20170615/19529.html 參考:h...
    F麥子閱讀 4,136評論 3 2
  • iPhone的標(biāo)準(zhǔn)推薦是CFNetwork 庫編程,其封裝好的開源庫是 cocoa AsyncSocket庫,用它...
    夜殤丶夜逝閱讀 4,141評論 1 23
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,604評論 30 472
  • 多線程、特別是NSOperation 和 GCD 的內(nèi)部原理。運行時機(jī)制的原理和運用場景。SDWebImage的原...
    LZM輪回閱讀 2,116評論 0 12

友情鏈接更多精彩內(nèi)容