tweak 项目 快速搭建CocoaAsyncSocket(建连、断开、重连、心跳、通用请求)

前言

GitHub

  • http请求:

每次更新数据都要向对应的端口发送一次请求,之后返回数据之后关闭连接

  • 长连接

客户端和服务器一直连着,当有数据更新的时候,服务器会直接发给客户端,不需要客户端主动请求。(client 需要监听流的输入)

ps:在这过程中,为了保证服务端和客户端一直是连接状态,客户端会定时不间断的发送心跳数据到服务器,表明还连接着,不然长时间没有数据更新,会断开连接,这样一直有心跳数据的时候,就会保证了连接没有中断,至于心跳数据的内容,就是前端后端共同商量的,和请求的数据是单独的。(通常采用nstimer)

一、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!

具体的请看MokeyDev 的logos tweak工程使用注意事项

二、问题解决

  • 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

三、代码实现

参考

读消息的设置

默认读消息为timeout 可以设置10

- (void)socketWriteData:(NSString *)data {
    // 开始写数据
    NSLog(@"socketWriteData:%@",data);
    
    NSData *requestData = [data dataUsingEncoding:NSUTF8StringEncoding];
    [self.socket writeData:requestData withTimeout:-1 tag:0];
//    [self socketBeginReadData];// 修改为连接建立之后  就立马监听
}

如果想要实时监听服务端的消息推送就可以修改,连接一旦建立 就开始读

- (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 -》socketBeginReadData

区分 服务端主动推送 和服务端响应的方式

可以让服务端新增响应类型 进行区分,或者app 端进行判断响应数据是否包含reqId,这个reqId 是只有app 主动发起的请求响应时才会存在

处理服务端的消息推送


    GACRESPONSE_TYPE respType = [json[@"respType"] integerValue];
    
    if(respType == RESPONSE_TYPE_NOTIFY){//消息通知 服务端的主动通知
        
        //直接发送通知
        //   1、 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{
        //2、执行对应的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扩展

    原文作者:kunnan
    原文地址: https://segmentfault.com/a/1190000011890820
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞