GCDAsyncSocket聊天實踐

鑒于服務器已經(jīng)有搭建好的socket服務器氧吐,所以我只關(guān)注iOS端如何通過CocoaSyncSocket實現(xiàn)客服聊天

創(chuàng)建聊天工具單例KefuHelper区丑,遵守協(xié)議GCDAsyncSocketDelegate

  • 初始化時,創(chuàng)建socket對象clientSocket【GCDAsyncSocket】
-(instancetype)init{
    if (self = [super init]) {
        self.clientSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];     
    }
    return self;
}
  • 鏈接服務器socket
-(void)connect{
    NSError *error = nil;
    self.isConnected = [self.clientSocket connectToHost:@"47.94.39.111" onPort:8283 error:&error];
    QMPLog(@"鏈接socket服務器----%@",error);
}
  • GCDAsyncSocket代理方法實現(xiàn)
#pragma mark - GCDAsyncSocketDelegate
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port
{
    //    NSLog(@"連接主機對應端口%@", sock);
    [PublicTool showMsg:@"鏈接成功"];
    QMPLog(@"服務器IP: %@-------端口: %d", host,port);
 
    // 連接成功開啟定時器,發(fā)送心跳包壁袄,用于檢測鏈接是否斷開
    [self addTimer];
    // 連接后,可讀取服務端的數(shù)據(jù)
    [self.clientSocket readDataWithTimeout:-1 tag:0];
    self.isConnected = YES;
}

- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
    [PublicTool showMsg:@"斷開連接"];
    QMPLog(@"服務器鏈接失敗: -----%@", err);
    self.clientSocket.delegate = nil;
    self.clientSocket = nil;
    self.isConnected = NO;
    [self.connectTimer invalidate];
}

// 接收到socket服務器發(fā)來的消息丧靡,發(fā)送消息后端寫了相應API, 不通過socket發(fā)送
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    NSString *text = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    [PublicTool showMsg:[NSString stringWithFormat:@"socket接收數(shù)據(jù)--%@",text]];
    // 讀取到服務端數(shù)據(jù)值后,能再次讀取
    [self.clientSocket readDataWithTimeout:-1 tag:0];
}
  • 心跳連接
- (void)addTimer{
    self.connectTimer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(longConnectToSocket) userInfo:nil repeats:YES];
    // 把定時器添加到當前運行循環(huán),并且調(diào)為通用模式
    [[NSRunLoop currentRunLoop] addTimer:self.connectTimer forMode:NSRunLoopCommonModes];
}

// 心跳連接
- (void)longConnectToSocket
{
    // 發(fā)送固定格式的數(shù)據(jù),指令@"longConnect"
    float version = [[UIDevice currentDevice] systemVersion].floatValue;
    NSString *longConnect = [NSString stringWithFormat:@"123%f",version];
    
    NSData  *data = [longConnect dataUsingEncoding:NSUTF8StringEncoding];
    
    [self.clientSocket writeData:data withTimeout:-1 tag:0];
}
GCDAsyncSocket常見問題
  • Error Domain=GCDAsyncSocketErrorDomain Code=4 "Read operation timed out" UserInfo=0xa8db6a0 {NSLocalizedDescription=Read operation timed out}
    scoket讀取數(shù)據(jù)超時饮戳,當網(wǎng)絡不怎么穩(wěn)定通信方給發(fā)送消息的時候時不時的會冒一個這個錯誤呻征,而且Socket也會自動斷開連接。一直跟蹤GCDAsyncSocket.m的代碼5068行<可能代碼有更新的會有點差異>有一個方法
  • (void)setupReadTimerWithTimeout:(NSTimeInterval)timeout
    這個方法是就是專門監(jiān)聽socket讀取數(shù)據(jù)是否有超時的現(xiàn)象的方法,源代碼設置成if(timeout >= 0.0)即檢測到超時就拋異常 這樣很容易導致socket連接異常叼丑。
    處理方式:你可以打印一下這個timeout值关翎,就會大概知道你的socket讀取數(shù)據(jù)超時的范圍,在項目允許的范圍內(nèi)設置這個值的大小鸠信,因為我的項目總是在10以內(nèi)纵寝,所以我設置成if(timeout > 10.0)之后,基本運行的時候就很少拋這個異常了星立。你也可以再接收到這個異常的時候重新連接一次爽茴。
  • Error Domain=GCDAsyncSocketErrorDomain Code=3 "Attempt to connect to host timed out" UserInfo=0x7bd14f40 {NSLocalizedDescription=Attempt to connect to host timed out}
    socket連接的時候超時葬凳,一般發(fā)生在你向服務端發(fā)送一條連接消息的時候,服務端無響應室奏,一般是由于服務端沒有開啟服務火焰,也有可能是設置響應時間的timeout值過小,在GCDAsyncSocket.m的代碼1938行的位置有一個設置timeout的地方 你可以設置一個稍微比較長的響應時間
- (BOOL)connectToHost:(NSString*)host onPort:(uint16_t)port error:(NSError **)errPtr
{
return [self connectToHost:host onPort:port withTimeout:5 error:errPtr];
}
  • Error Domain=GCDAsyncSocketErrorDomain Code=51胧沫,網(wǎng)絡斷開昌简,可以檢查一下網(wǎng)絡連接狀態(tài)

  • Error Domain=NSPOSIXErrorDomain Code=61 "Connection refused" UserInfo=0x7b288750 {NSLocalizedFailureReason=Error in connect() function, NSLocalizedDescription=Connection refused}
    服務器沒啟動,或者端口沒開啟琳袄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末江场,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子窖逗,更是在濱河造成了極大的恐慌,老刑警劉巖餐蔬,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碎紊,死亡現(xiàn)場離奇詭異,居然都是意外死亡樊诺,警方通過查閱死者的電腦和手機仗考,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來词爬,“玉大人秃嗜,你說我怎么就攤上這事《倥颍” “怎么了锅锨?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長恋沃。 經(jīng)常有香客問我必搞,道長,這世上最難降的妖魔是什么囊咏? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任恕洲,我火速辦了婚禮,結(jié)果婚禮上梅割,老公的妹妹穿的比我還像新娘霜第。我一直安慰自己,他們只是感情好户辞,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布泌类。 她就那樣靜靜地躺著,像睡著了一般咆课。 火紅的嫁衣襯著肌膚如雪末誓。 梳的紋絲不亂的頭發(fā)上扯俱,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機與錄音喇澡,去河邊找鬼迅栅。 笑死,一個胖子當著我的面吹牛晴玖,可吹牛的內(nèi)容都是我干的读存。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼呕屎,長吁一口氣:“原來是場噩夢啊……” “哼让簿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起秀睛,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤尔当,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蹂安,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體椭迎,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年田盈,在試婚紗的時候發(fā)現(xiàn)自己被綠了畜号。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡允瞧,死狀恐怖简软,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情述暂,我是刑警寧澤痹升,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站贸典,受9級特大地震影響视卢,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜廊驼,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一据过、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧妒挎,春花似錦绳锅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春原朝,著一層夾襖步出監(jiān)牢的瞬間驯嘱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工喳坠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鞠评,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓壕鹉,卻偏偏與公主長得像剃幌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子晾浴,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 因為項目中用用到socket通信 實現(xiàn)夸平臺的局域網(wǎng)實時通信负乡。下面羅列一些我在使用過程中遇見錯誤和我的處理方式:一...
    東方詩空閱讀 3,248評論 0 2
  • 因為項目中用用到socket通信 實現(xiàn)夸平臺的局域網(wǎng)實時通信。下面羅列一些我在使用過程中遇見錯誤和我的處理方式:一...
    9426Ami閱讀 9,242評論 0 0
  • iPhone的標準推薦是CFNetwork 庫編程脊凰,其封裝好的開源庫是 cocoa AsyncSocket庫抖棘,用它...
    Ethan_Struggle閱讀 2,245評論 2 12
  • 原文鏈接:https://docs.spring.io/spring-boot/docs/1.4.x/refere...
    pseudo_niaonao閱讀 4,702評論 0 9
  • 專一性! 在五年笙各,甚至是十年的時間里钉答,只是專一的做一件事情! 平心靜態(tài)杈抢,不知煩厭的始終做一件事情,用心仑性,用愛去做惶楼,...
    小絲瓜1314520閱讀 206評論 0 0