微信Mars跨平台组件iOS端消息调用流程

2017-06-03  本文已影响2335人  CoderQH

摘要

Mars 是微信官方的终端基础组件,是一个使用 C++ 编写的业务性无关,平台性无关的基础组件。目前已接入微信 Android、iOS、Mac、Windows、WP 等客户端。下面主要分析iOS端样例消息调用流程。

Mars 结构

官方样图官方样图

其中STN(信令传输网络)为核心模块。

下面主要分析STN模块消息通讯流程:

消息核心流程:一个消息任务以startTask开始,onTaskEnd结束。中间通过StnCallBack::Req2Buf与StnCallBack::Buf2Resp分别处理客户端的请求和响应的相关操作,比如数据处理,服务端响应和状态检测等等。

客户端发送/接受

发送

数据传输格式为:google 的 protocol buffer。protocol buffer是google的一个开源项目,它是用于结构化数据串行化的灵活、高效、自动的方法,例如XML,不过它比xml更小、更快、也更简单。你可以定义自己的数据结构,然后使用代码生成器生成的代码来读写这个数据结构。你甚至可以在无需重新部署程序的情况下更新数据结构。

iOS端发送调用方法: requestSendData

-(NSData*)requestSendData {
    SendMessageRequest *sendMsgRequest = [SendMessageRequest new];
    sendMsgRequest.from = [self username];
    sendMsgRequest.to = @"all";
    sendMsgRequest.text = _textField.text;
    sendMsgRequest.accessToken = @"123456";
    sendMsgRequest.topic = _conversation.topic;
    LOG_INFO(kModuleViewController, @"send msg to topic:%@", _conversation.notice);
    NSData* data = [sendMsgRequest data];
    dispatch_async(dispatch_get_main_queue(), ^{
        _textField.text = @"";
    });
    return data;
}

数据处理:StnCallBack::Req2Buf

bool StnCallBack::Req2Buf(int32_t _taskid, void* const _user_context, AutoBuffer& _outbuffer, int& _error_code, const int _channel_select) {
    NSData* requestData =  [[NetworkService sharedInstance] Request2BufferWithTaskID:_taskid userContext:_user_context];
    
    if (requestData == nil) {
        requestData = [[NSData alloc] init];
    }

    _outbuffer.AllocWrite(requestData.length);
    _outbuffer.Write(requestData.bytes,requestData.length);
    return requestData.length > 0;
}

接收
-(int)onPostDecode:(NSData*)responseData {
    SendMessageResponse *sendMsgResponse = [SendMessageResponse parseFromData:responseData error:nil];
    dispatch_async(dispatch_get_main_queue(), ^{
        NSString *recvtext = [NSString stringWithFormat:@"%@ : %@", sendMsgResponse.from, sendMsgResponse.text];
        [self.messages addObject:recvtext];
        [self.tableView reloadData];
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.messages.count-1 inSection:0];
        [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    });
    return sendMsgResponse.errCode == 0 ? 0 : -1;
}

数据处理:StnCallBack::Buf2Resp

int StnCallBack::Buf2Resp(int32_t _taskid, void* const _user_context, const AutoBuffer& _inbuffer, int& _error_code, const int _channel_select) {
    
    int handle_type = mars::stn::kTaskFailHandleNormal;
    NSData* responseData = [NSData dataWithBytes:(const void *) _inbuffer.Ptr() length:_inbuffer.Length()];
    
    NSInteger errorCode = [[NetworkService sharedInstance] Buffer2ResponseWithTaskID:_taskid ResponseData:responseData userContext:_user_context];
    
    if (errorCode != 0) {
        handle_type = mars::stn::kTaskFailHandleDefault;
    }
    
    return handle_type;
}
消息存储

消息存储是用字典存储,taskID为key,数据包为value。

- (void)addObserver:(id<UINotifyDelegate>)observer forKey:(NSString *)key {
    [controllers setObject:observer forKey:key];
}

- (void)addCGITasks:(CGITask*)cgiTask forKey:(NSString *)key {
    [tasks setObject:cgiTask forKey:key];
}

服务端推送

当TaskID 为0时候,默认为推送。

调用方法:notifyPushMessage


- (void)notifyPushMessage:(NSData*)pushData withCmdId:(int)cmdId {
    MessagePush* messagePush = [MessagePush parseFromData:pushData error:nil];
    if (messagePush != nil) {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSString *recvtext = [NSString stringWithFormat:@"%@ : %@", messagePush.from, messagePush.content];
            [self.messages addObject:recvtext];
            [self.tableView reloadData];
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.messages.count-1 inSection:0];
            [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        });
    }
}

数据处理:StnCallBack::OnPush

void StnCallBack::OnPush(int32_t _cmdid, const AutoBuffer& _msgpayload) {
    if (_msgpayload.Length() > 0) {
        NSData* recvData = [NSData dataWithBytes:(const void *) _msgpayload.Ptr() length:_msgpayload.Length()];
        [[NetworkService sharedInstance] OnPushWithCmd:_cmdid data:recvData];
    }
    
}

数据存储:cmdID

- (void)addPushObserver:(id<PushNotifyDelegate>)observer withCmdId:(int)cmdId {
    LOG_INFO(kNetwork, @"add pushObserver for cmdId:%d", cmdId);
    [pushrecvers setObject:observer forKey:[NSString stringWithFormat:@"%d", cmdId]];
}

完成一个任务

调用方法:

- (int)onTaskEnd:(uint32_t)tid errType:(uint32_t)errtype errCode:(uint32_t)errcode {
    
    NSLog(@"%ld  %ld  %ld ",tid, errtype, errcode);
    
    return 0;
}

处理方法:StnCallBack::OnTaskEnd

int  StnCallBack::OnTaskEnd(int32_t _taskid, void* const _user_context, int _error_type, int _error_code) {
    
    return (int)[[NetworkService sharedInstance] OnTaskEndWithTaskID:_taskid userContext:_user_context errType:_error_type errCode:_error_code];

}

待续。

上一篇下一篇

猜你喜欢

热点阅读