tweak 項目 快速搭建CocoaAsyncSocket(建連、斷開、重連、心跳、通用請求)

前言

GitHubphp

  • http請求:

每次更新數據都要向對應的端口發送一次請求,以後返回數據以後關閉鏈接html

  • 長鏈接

客戶端和服務器一直連着,當有數據更新的時候,服務器會直接發給客戶端,不須要客戶端主動請求。(client 須要監聽流的輸入)前端

ps:在這過程當中,爲了保證服務端和客戶端一直是鏈接狀態,客戶端會定時不間斷的發送心跳數據到服務器,代表還鏈接着,否則長時間沒有數據更新,會斷開鏈接,這樣一直有心跳數據的時候,就會保證了鏈接沒有中斷,至於心跳數據的內容,就是前端後端共同商量的,和請求的數據是單獨的。(一般採用nstimer)node

1、tweak 項目集成CocoaAsyncSocket 可採用MonkeyDev 的logos Tweak模版(支持使用CocoaPods)

  • pod
platform :ios, '8.0'
inhibit_all_warnings!

#use_frameworks!
target 'wlentrust' do
   pod 'CocoaAsyncSocket'
   pod 'JSONModel', '1.1.0'
   pod 'AFNetworking', '3.0.4'
   pod 'XMLDictionary'
end

因爲tweak自己就是動態庫,所以暫時只支持靜態庫#use_frameworks!ios

具體的請看MokeyDev 的logos tweak工程使用注意事項git

2、問題解決

  • Cannot synthesize weak property in file using manual reference
    counting
/Users/devzkn/code/tweak/wlentrust/wlentrust/src/socket/GCDAsyncSocketManager/Manager/GCDAsyncSocketCommunicationManager.m:41:1: Cannot synthesize weak property in file using manual reference counting
  • 解決方案:修改項目配置爲ARC編譯環境
修改app LLVMXX -language-Object-C 支持ARC
Y-Y-Y-NO

3、代碼實現

參考github

讀消息的設置

默認讀消息爲timeout 能夠設置10chrome

- (void)socketWriteData:(NSString *)data {
    // 開始寫數據
    NSLog(@"socketWriteData:%@",data);
    
    NSData *requestData = [data dataUsingEncoding:NSUTF8StringEncoding];
    [self.socket writeData:requestData withTimeout:-1 tag:0];
//    [self socketBeginReadData];// 修改成鏈接創建以後  就立馬監聽
}

若是想要實時監聽服務端的消息推送就能夠修改,鏈接一旦創建 就開始讀macos

- (void)socket:(GCDAsyncSocket *)socket didConnectToHost:(NSString *)host port:(UInt16)port {

        [self.socketManager socketBeginReadData];// 修改成鏈接創建以後  就立馬監聽

}
/**
 開始讀數據
 */
#pragma mark - ******** 設置讀數據的timeout   鏈接創建以後就開始監聽讀取數據

- (void)socketBeginReadData {
    NSLog(@"socketBeginReadData");
    [self.socket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 maxLength:0 tag:0];//考慮使用-1
}

業務邏輯的處理

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {

// 根據服務端返回的消息類型,解析參數,處理任務
}

實現實時監聽服務端的流的方法

一旦接受到數據 就開啓下一次的監聽輸入流
receive data -》socketBeginReadDatajson

區分 服務端主動推送 和服務端響應的方式

可讓服務端新增響應類型 進行區分,或者app 端進行判斷響應數據是否包含reqId,這個reqId 是隻有app 主動發起的請求響應時纔會存在

處理服務端的消息推送

GACRESPONSE_TYPE respType = [json[@"respType"] integerValue];
    
    if(respType == RESPONSE_TYPE_NOTIFY){//消息通知 服務端的主動通知
        
        //直接發送通知
        //   一、 RESPONSE_TYPE_NOTIFY 處理服務端主動推送的任務
        
        NSMutableDictionary * userInfo = [NSMutableDictionary dictionaryWithObject:json forKey:kRESPONSE_TYPENotificationjsonKey];//respType 傳送json
        [[NSNotificationCenter defaultCenter] postNotificationName:kRESPONSE_TYPERESPONSE_TYPE_NOTIFYNotification object:self userInfo:userInfo];
        
        
    }else{
        //二、執行對應的block
        
        
        
        SocketDidReadBlock didReadBlock = self.requestsMap[requestID];
        
        //    if (errorCode != 0) {
        //
        //        jsonError = [[NSError alloc]initWithDomain:NSURLErrorDomain code:errorCode userInfo:nil];
        //    }
        
        if (didReadBlock) {
            didReadBlock(jsonError, json);
        }
        
        
    }
    [self.socketManager socketBeginReadData];// 修改成鏈接創建以後  就立馬監聽

異常斷開鏈接處理

#pragma mark - ******** 失敗從新鏈接
- (void)socketDidDisconnect:(GCDAsyncSocket *)socket withError:(NSError *)err {
- (void)socketWriteDataWithRequestType:(GACRequestType)type
                           requestBody:(nonnull NSDictionary *)body
                            completion:(nullable SocketDidReadBlock)callback {
    NSLog(@"socketWriteData:%@",body);
    if (self.socketManager.connectStatus == -1) {
        NSLog(@"socket 未連通");
- (void)socket:(GCDAsyncSocket *)socket didConnectToHost:(NSString *)host port:(UInt16)port {
    
    self.socketManager.connectStatus = 1;//此處的狀態設置,提早到創建鏈接的地方
   //此時將重連的時鐘刪除
    [self.socketManager invalidatereconnectTimer];

服務端的搭建能夠採用Node.js

API大全
PHP API

待續

工程師必備技能 - 90分鐘本身開發一個chrome擴展

相關文章
相關標籤/搜索