OC 在线直播五百人同时聊天时造成视频卡顿解决办法

Header_8.jpg

问题描述

观看直播情况下,直播间五百人同时发送消息,聊天界面展示会很耗性能,影响直播视频正常播放

分析和解决方案

1.聊天接收时,收到的代理方法会传递一个字典,这个字典包含这条聊天的所有信息,但是接收到这个消息后,我这边没有任何处理,直接把这个东西交给我的DataSourceManager去处理,然后将解析过的lastObject给chatView去添加cell。


屏幕快照 2019-03-08 上午10.54.50.png

这个时候就造成一个问题,如果一秒钟我这边接收到了100条消息,我这个流程就要走100次,然后在TableView中reload100次。

为了避免这个问题,可以在接收到这个消息后,进行一些处理,如果每秒钟发送多条消息,就将这些消息打包,然后交给chatView直接添加这个数组就可以了

屏幕快照 2019-03-08 上午11.07.04.png

下面是处理每秒钟加载过多消息进行的限制

//解析公聊消息
    WS(ws)
    [self.manager addPublicChat:dic userDic:self.userDic viewerId:self.viewerId groupId:self.groupId danMuBlock:^(NSString * _Nonnull msg) {
        //弹幕
        [ws.playerView insertDanmuString:msg];
    }];
    //判断时间
    NSString *publistTime = dic[@"time"];
    NSInteger publish = [NSString timeSwitchTimestamp:publistTime andFormatter:@"HH:mm:ss"];
    if (_lastTime == publish) {
        //添加数组
        [self.chatArr addObject:[self.manager.publicChatArray lastObject]];
//        NSLog(@"同一秒,添加至数组");
        [_updateTimer invalidate];
        WS(weakSelf)
        _updateTimer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:NO block:^(NSTimer * _Nonnull timer) {
            if (weakSelf.chatArr.count != 0) {
                [weakSelf.chatView addPublicChatArray:weakSelf.chatArr];
                [weakSelf.chatArr removeAllObjects];
//                NSLog(@"延迟数据校对");
            }
        }];
    }else{
        if (self.chatArr.count != 0) {
            [self.chatView addPublicChatArray:self.chatArr];
            [self.chatArr removeAllObjects];
//            NSLog(@"将数组中的元素添加至消息中");
        }
        [self.chatView addPublicChat:[self.manager.publicChatArray lastObject]];
        _lastTime = publish;
//        NSLog(@"+++++++++++++++++");
    }

到这里解决了一个问题,当每秒钟消息过多,让他只走了一遍reloadData
2.优化到这里后,iphone7及以上机型播放直播视频加五百人聊天已经不卡顿了,但是在iphone6 iphone6plus 还是有轻微卡顿,而且卡顿还是1S一卡顿,和我这个延迟机制刚好相对应
ChatView中处理添加数组方法

/**
 添加一个聊天数组(直播公聊如果每秒钟发送消息过多,会调用这个方法)

 @param array 聊天数组
 */
-(void)addPublicChatArray:(NSMutableArray *)array{
    if([array count] == 0) return;
    
    NSInteger preIndex = [self.publicChatArray count];
    [self.publicChatArray addObjectsFromArray:[array mutableCopy]];
    NSInteger bacIndex = [self.publicChatArray count];
    
    NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
    for(NSInteger row = preIndex + 1;row <= bacIndex;row++) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(row-1) inSection:0];
        [indexPaths addObject: indexPath];
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        [self.publicTableView reloadData];
        //防止越界
        NSIndexPath *lastIndexPath = [indexPaths lastObject];
        if ((long)lastIndexPath.row > self.publicChatArray.count) {
            return;
        }
//        [self.publicTableView beginUpdates];
//        [self.publicTableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
//        [self.publicTableView endUpdates];
        if (indexPaths != nil && [indexPaths count] != 0 ) {
            [self.publicTableView scrollToRowAtIndexPath:[indexPaths lastObject] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        }
    });
}

考虑到这个问题,也有可能是配置比较低的机型每秒钟加载数组过长,所以这里加了一个舍弃机制,这个数据过长的话就只加载最近的几条

//让每秒钟发送消息超过10条时,取最新的十条
    if (array.count > 10 && self.input == YES ) {
//        NSInteger count = array.count;
        NSRange range = NSMakeRange(0, array.count - 10);
        [array removeObjectsInRange:range];
//        NSLog(@"每秒钟数据%d个,加载最新10条, 目前消息数%lu", count, self.publicChatArray.count);
    }

3.优化了前面两个之后,有一个问题,我remove掉的那些数据是丢失了吗?如果我滑到顶部下拉刷新能不能查看之前的消息
下拉刷新机制

/**
 下拉刷新新数据
 */
-(void)loadNewData{
/* 
ChatViewDataSourceManager是一个数据处理中心单例,所有的消息要经过这个类去处理model,
并且这个数据中的聊天数组包含所有经过处理的聊天信息
*/
    if ([ChatViewDataSourceManager sharedManager].publicChatArray.count > self.publicChatArray.count) {
        NSMutableArray *arr = [ChatViewDataSourceManager sharedManager].publicChatArray;
        NSInteger selfCount = self.publicChatArray.count;
        NSInteger insertCount = arr.count - selfCount;
        insertCount = insertCount > 10 ? 10 : insertCount;//判断未展示的消息数据是否大于10条
        //加载10条数据
        for (NSInteger i = arr.count - selfCount; i > arr.count - selfCount - insertCount; i--) {
            [self.publicChatArray insertObject:arr[i] atIndex:0];
        }
//        NSLog(@"刷新了%d条数据,总条数%d, 目前条数%d", insertCount, arr.count, self.publicChatArray.count);
        [self.publicTableView reloadData];
        [self.publicTableView.mj_header endRefreshing];
    }else{
//        NSLog(@"没有更多数据了");
        [self.publicTableView.mj_header endRefreshing];
    }
}

避免tableView显示过多cell机制

 //当前cell数量大于60时,加载最新20条,下拉刷新从单例数组中取
    if (self.publicChatArray.count > 60) {
        NSRange range =NSMakeRange(0, self.publicChatArray.count - 20);
        [self.publicChatArray removeObjectsInRange:range];
//        NSLog(@"count大于60,返回最新20条,目前消息条数%lu", self.publicChatArray.count);
    }

总结

1.数据量过大时,延迟1S展示,通过数组打包交给ChatView渲染
2.舍弃机制,避免加载过多的cell,毕竟一个屏幕直播占一块,聊天占一块,没必要一次性加载100条,够两个屏幕的宽度就可以,然后通过下拉刷新去取数据就可以

tableView的其他坑

1.数据预处理

2.cell视图渲染

3.行高处理

4.异步获取聊天图片刷新

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353