仿微信的IM聊天时间显示格式(含iOS/Android/Web实现)[图文+源码]

本文为原创分享,转载请注明出处。

1、引言

即时通讯IM应用中的聊天消息时间显示是个再常见不过的需求,现在都讲究用户体验,所以时间显示再也不能像传统软件一样简单粗地暴显示成“年/月/日 时:分:秒”这样。所以,市面上几乎所有的IM都会对聊天消息的时间显示格化做人性化处理,从而提升用户体验(使用感受会明显友好)。

这两天正在继续开发RainbowChat-Web产品,所以正需要这样的代码。但经过在即时通讯网的论坛和技术交流群里询问,以及网上的所谓仿微信例子,都不符合要求。这些例子要么简陋粗暴(有逻辑bug硬伤)、要么并不完整(可能只是随手写的练手代码,并不适合放到产品中),所以本着做技术精益求精的态度,没有现成的轮子可用,那就只能造轮子了。

那么,按怎样的显示逻辑来实现呢?作为移动端IM的王者,微信无疑处处是标杆,所以本次的消息时间显示格式,直接参照微信的实现逻辑准没错(随大流虽然没个性,但不至于非主流)。

* 提示:本文中的代码实现,是从 RainbowChat 和 RainbowChat-Web 两个IM产品中扒出来简化后的结果,是基于完全相同的算法逻辑分别用OC、Java和JavaScript实现的。如您觉得有用,可以改改直接用于您的产品,如您有更好的建议请直接回复和评论。代码仅供参考,不足之外,还请见谅!

学习交流:

- 即时通讯/推送技术开发交流4群:101279154 [推荐]

- 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》

(本文同步发布于:http://www.52im.net/thread-2371-1-1.html)

2、相关文章

《用于IM中图片压缩的Android工具类源码,效果可媲美微信 [附件下载]》

《高仿Android版手机QQ可拖拽未读数小气泡源码 [附件下载]》

《Android聊天界面源码:实现了聊天气泡、表情图标(可翻页) [附件下载]》

《高仿Android版手机QQ首页侧滑菜单源码 [附件下载]》

《分享java AMR音频文件合并源码,全网最全》

《Android版高仿微信聊天界面源码 [附件下载]》

《高仿手机QQ的Android版锁屏聊天消息提醒功能 [附件下载]》

《高仿iOS版手机QQ录音及振幅动画完整实现 [源码下载]》

《Android端社交应用中的评论和回复功能实战分享[图文+源码]》

《Android端IM应用中的@人功能实现:仿微博、QQ、微信,零入侵、高可扩展[图文+源码]》

3、看看微信中聊天消息的时间显示规则

先来看看微信中聊天消息的时间显示成什么样:

 
微信主页“消息”界面
 
聊天界面(注意聊天界面中默认带了“时:分”的显示)

来自微信官方对聊天消息时间显示的规则说明:

 

▲ 该规则的定义,主要是2、3条(本图引用自微信官方FAQ文档)

4、总结一下微信中聊天消息的时间显示逻辑

参见第3节中的截图和微信官方的说明,我们可以总结出微信对于聊天消息时间显示的规则。

① 微信对于聊天消息时间显示的规则总结如下(首页“消息”界面):

1)当聊天消息时间为一周之内时:当天的消息显示为“小时:分钟”形式,然后是“昨天”、“前天”,然后就是“星期几”这个样子;

2)当聊天消息的时间大于一周时:直接显示“年/月/日”的时间格式。

② 微信对于聊天消息时间显示的规则总结如下(聊天内容界面):

1)当聊天消息时间为一周之内时:当天的消息显示为“小时:分钟”形式,然后是“昨天 时:分”、“前天 时:分”,然后就是“星期几  时:分”这个样子;

2)当聊天消息的时间大于一周时:直接显示“年/月/日 时:分”的完整时间格式。

注意:聊天内容界面里的时间格式,实际上是首页“消息”界面里的时间格式加上“时:分”后的结果,所以代码实现上这两套代码是可以重用的,无需两份代码。

好了,规则已经摸清,下面将直接上代码。

5、Android平台上的代码实现(标准Java)

5.1 完整源码

/**

 * 返回指定pattern样的日期时间字符串。

 *

 * @param dt

 * @param pattern

 * @return 如果时间转换成功则返回结果,否则返回空字符串""

 * @author 即时通讯网([url=http://www.52im.net]http://www.52im.net[/url])

 */

publicstaticString getTimeString(Date dt, String pattern)

{

        try

        {

                SimpleDateFormat sdf = newSimpleDateFormat(pattern);//"yyyy-MM-dd HH:mm:ss"

                sdf.setTimeZone(TimeZone.getDefault());

                returnsdf.format(dt);

        }

        catch(Exception e)

        {

                return"";

        }

}

 

/**

* 仿照微信中的消息时间显示逻辑,将时间戳(单位:毫秒)转换为友好的显示格式.

* <p>

* 1)7天之内的日期显示逻辑是:今天、昨天(-1d)、前天(-2d)、星期?(只显示总计7天之内的星期数,即<=-4d);<br>

* 2)7天之外(即>7天)的逻辑:直接显示完整日期时间。

*

* @param srcDate 要处理的源日期时间对象

* @param mustIncludeTime true表示输出的格式里一定会包含“时间:分钟”,否则不包含(参考微信,不包含时分的情况,用于首页“消息”中显示时)

* @return 输出格式形如:“10:30”、“昨天 12:04”、“前天 20:51”、“星期二”、“2019/2/21 12:09”等形式

* @author 即时通讯网([url=http://www.52im.net]http://www.52im.net[/url])

* @since 4.5

*/

publicstaticString getTimeStringAutoShort2(Date srcDate, booleanmustIncludeTime)

{

        String ret = "";

 

        try

        {

                GregorianCalendar gcCurrent = newGregorianCalendar();

                gcCurrent.setTime(newDate());

                intcurrentYear = gcCurrent.get(GregorianCalendar.YEAR);

                intcurrentMonth = gcCurrent.get(GregorianCalendar.MONTH)+1;

                intcurrentDay = gcCurrent.get(GregorianCalendar.DAY_OF_MONTH);

 

                GregorianCalendar gcSrc = newGregorianCalendar();

                gcSrc.setTime(srcDate);

                intsrcYear = gcSrc.get(GregorianCalendar.YEAR);

                intsrcMonth = gcSrc.get(GregorianCalendar.MONTH)+1;

                intsrcDay = gcSrc.get(GregorianCalendar.DAY_OF_MONTH);

 

                // 要额外显示的时间分钟

                String timeExtraStr = (mustIncludeTime?" "+getTimeString(srcDate, "HH:mm"):"");

 

                // 当年

                if(currentYear == srcYear)

                {

                        longcurrentTimestamp = gcCurrent.getTimeInMillis();

                        longsrcTimestamp = gcSrc.getTimeInMillis();

 

                        // 相差时间(单位:毫秒)

                        longdelta = (currentTimestamp - srcTimestamp);

 

                        // 当天(月份和日期一致才是)

                        if(currentMonth == srcMonth && currentDay == srcDay)

                        {

                                // 时间相差60秒以内

                                if(delta < 60* 1000)

                                           ret = "刚刚";

                                // 否则当天其它时间段的,直接显示“时:分”的形式

                                else

                                            ret = getTimeString(srcDate, "HH:mm");

                        }

                        // 当年 && 当天之外的时间(即昨天及以前的时间)

                        else

                        {

                                // 昨天(以“现在”的时候为基准-1天)

                                GregorianCalendar yesterdayDate = newGregorianCalendar();

                                yesterdayDate.add(GregorianCalendar.DAY_OF_MONTH, -1);

 

                                // 前天(以“现在”的时候为基准-2天)

                                GregorianCalendar beforeYesterdayDate = newGregorianCalendar();

                                beforeYesterdayDate.add(GregorianCalendar.DAY_OF_MONTH, -2);

 

                                // 用目标日期的“月”和“天”跟上方计算出来的“昨天”进行比较,是最为准确的(如果用时间戳差值

                                // 的形式,是不准确的,比如:现在时刻是2019年02月22日1:00、而srcDate是2019年02月21日23:00,

                                // 这两者间只相差2小时,直接用“delta/(3600 * 1000)” > 24小时来判断是否昨天,就完全是扯蛋的逻辑了)

                                if(srcMonth == (yesterdayDate.get(GregorianCalendar.MONTH)+1)

                                        && srcDay == yesterdayDate.get(GregorianCalendar.DAY_OF_MONTH))

                                {

                                            ret = "昨天"+timeExtraStr;// -1d

                                }

                                // “前天”判断逻辑同上

                                elseif(srcMonth == (beforeYesterdayDate.get(GregorianCalendar.MONTH)+1)

                                        && srcDay == beforeYesterdayDate.get(GregorianCalendar.DAY_OF_MONTH))

                                {

                                            ret = "前天"+timeExtraStr;// -2d

                                }

                                else

                                {

                                            // 跟当前时间相差的小时数

                                            longdeltaHour = (delta/(3600* 1000));

 

                                            // 如果小于 7*24小时就显示星期几

                                            if(deltaHour < 7*24)

                                            {

                                                String[] weekday = {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};

 

                                                // 取出当前是星期几

                                                String weedayDesc = weekday[gcSrc.get(GregorianCalendar.DAY_OF_WEEK)-1];

                                                ret = weedayDesc+timeExtraStr;

                                            }

                                            // 否则直接显示完整日期时间

                                            else

                                                ret = getTimeString(srcDate, "yyyy/M/d")+timeExtraStr;

                                }

                        }

            }

            else

                ret = getTimeString(srcDate, "yyyy/M/d")+timeExtraStr;

        }

        catch(Exception e)

        {

                System.err.println("【DEBUG-getTimeStringAutoShort】计算出错:"+e.getMessage()+" 【NO】");

        }

 

        returnret;

}

5.2 调用示例

// 用于首页“消息”界面时

getTimeStringAutoShort2(newDate(), false);

// 用于聊天内容界面时

getTimeStringAutoShort2(newDate(), true);

5.3 运行效果
 
▲ 上述代码在RainbowChat Android版上的运行效果(首页)
 
▲ 上述代码在RainbowChat Android版上的运行效果(聊天界面)

6、iOS平台上的代码实现(Objective-C)

6.1 完整源码

源文件TimeTool.h:

#import <Foundation/Foundation.h>

@interfaceTimeTool : NSObject

/**

 * 仿照微信中的消息时间显示逻辑,将时间戳(单位:毫秒)转换为友好的显示格式.

 * 1)7天之内的日期显示逻辑是:今天、昨天(-1d)、前天(-2d)、星期?(只显示总计7天之内的星期数,即<=-4d);

 * 2)7天之外(即>7天)的逻辑:直接显示完整日期时间。

 * @param dt 日期时间对象(本次被判断对象)

 * @param includeTime YES表示输出的格式里一定会包含“时间:分钟”,否则不包含(参考微信,不包含时分的情况,用于首页“消息”中显示时)

 * @return 输出格式形如:“刚刚”、“10:30”、“昨天 12:04”、“前天 20:51”、“星期二”、“2019/2/21 12:09”等形式

 * @since 1.3

 */

+ (NSString*)getTimeStringAutoShort2:(NSDate*)dt mustIncludeTime:(BOOL)includeTime;

+ (NSString*)getTimeString:(NSDate*)dt format:(NSString*)fmt;

/**

 * 获得指定NSDate对象iOS时间戳(格式遵从ios的习惯,以秒为单位)。

 */

+ (NSTimeInterval) getIOSTimeStamp:(NSDate*)dat;

 

/**

 * 获得指定NSDate对象iOS时间戳的long形式(格式遵从ios的习惯,以秒为单位,形如:1485159493)。

 */

+ (long) getIOSTimeStamp_l:(NSDate*)dat;

 

/**
* 获得iOS当前系统时间的NSDate对象。
*/
+ (NSDate*)getIOSDefaultDate;

@end

源文件TimeTool.m:

#import "TimeTool.h"

@implementationTimeTool

// 仿照微信的逻辑,显示一个人性化的时间字串

+ (NSString*)getTimeStringAutoShort2:(NSDate*)dt mustIncludeTime:(BOOL)includeTime{

    NSString*ret = nil;

    NSCalendar*calendar = [NSCalendarcurrentCalendar];

    // 当前时间

    NSDate*currentDate = [NSDatedate];

    NSDateComponents*curComponents = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekdayfromDate:currentDate];

    NSIntegercurrentYear=[curComponents year];

    NSIntegercurrentMonth=[curComponents month];

    NSIntegercurrentDay=[curComponents day];

    // 目标判断时间

    NSDateComponents*srcComponents = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekdayfromDate:dt];

    NSIntegersrcYear=[srcComponents year];

    NSIntegersrcMonth=[srcComponents month];

    NSIntegersrcDay=[srcComponents day];

    // 要额外显示的时间分钟

    NSString*timeExtraStr = (includeTime?[TimeTool getTimeString:dt format:@" HH:mm"]:@"");

    // 当年

    if(currentYear == srcYear) {

        longcurrentTimestamp = [TimeTool getIOSTimeStamp_l:currentDate];

        longsrcTimestamp = [TimeTool getIOSTimeStamp_l:dt];

        // 相差时间(单位:秒)

        longdelta = currentTimestamp - srcTimestamp;

        // 当天(月份和日期一致才是)

        if(currentMonth == srcMonth && currentDay == srcDay) {

            // 时间相差60秒以内

            if(delta < 60)

                ret = @"刚刚";

            // 否则当天其它时间段的,直接显示“时:分”的形式

            else

                ret = [TimeTool getTimeString:dt format:@"HH:mm"];

        }

        // 当年 && 当天之外的时间(即昨天及以前的时间)

        else{

            // 昨天(以“现在”的时候为基准-1天)

            NSDate*yesterdayDate = [NSDatedate];

            yesterdayDate = [NSDatedateWithTimeInterval:-24*60*60 sinceDate:yesterdayDate];

            NSDateComponents*yesterdayComponents = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDayfromDate:yesterdayDate];

            NSIntegeryesterdayMonth=[yesterdayComponents month];

            NSIntegeryesterdayDay=[yesterdayComponents day];

            // 前天(以“现在”的时候为基准-2天)

            NSDate*beforeYesterdayDate = [NSDatedate];

            beforeYesterdayDate = [NSDatedateWithTimeInterval:-48*60*60 sinceDate:beforeYesterdayDate];

            NSDateComponents*beforeYesterdayComponents = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDayfromDate:beforeYesterdayDate];

            NSIntegerbeforeYesterdayMonth=[beforeYesterdayComponents month];

            NSIntegerbeforeYesterdayDay=[beforeYesterdayComponents day];

            // 用目标日期的“月”和“天”跟上方计算出来的“昨天”进行比较,是最为准确的(如果用时间戳差值

            // 的形式,是不准确的,比如:现在时刻是2019年02月22日1:00、而srcDate是2019年02月21日23:00,

            // 这两者间只相差2小时,直接用“delta/3600” > 24小时来判断是否昨天,就完全是扯蛋的逻辑了)

            if(srcMonth == yesterdayMonth && srcDay == yesterdayDay)

                ret = [NSStringstringWithFormat:@"昨天%@", timeExtraStr];// -1d

            // “前天”判断逻辑同上

            elseif(srcMonth == beforeYesterdayMonth && srcDay == beforeYesterdayDay)

                ret = [NSStringstringWithFormat:@"前天%@", timeExtraStr];// -2d

            else{

                // 跟当前时间相差的小时数

                longdeltaHour = (delta/3600);

 

                // 如果小于或等 7*24小时就显示星期几

                if(deltaHour <= 7*24){

                    NSArray<NSString*> *weekdayAry = [NSArrayarrayWithObjects:@"星期日", @"星期一", @"星期二", @"星期三", @"星期四", @"星期五", @"星期六", nil];

                    // 取出的星期数:1表示星期天,2表示星期一,3表示星期二。。。。 6表示星期五,7表示星期六

                    NSIntegersrcWeekday=[srcComponents weekday];

                    // 取出当前是星期几

                    NSString*weedayDesc = [weekdayAry objectAtIndex:(srcWeekday-1)];

                    ret = [NSStringstringWithFormat:@"%@%@", weedayDesc, timeExtraStr];

                }

                // 否则直接显示完整日期时间

                else

                    ret = [NSStringstringWithFormat:@"%@%@", [TimeTool getTimeString:dt format:@"yyyy/M/d"], timeExtraStr];

            }

        }

    }

    // 往年

    else{

        ret = [NSStringstringWithFormat:@"%@%@", [TimeTool getTimeString:dt format:@"yyyy/M/d"], timeExtraStr];

    }

    returnret;

}

+ (NSString*)getTimeString:(NSDate*)dt format:(NSString*)fmt{

    NSDateFormatter* format = [[NSDateFormatteralloc] init];

    [format setDateFormat:fmt];

    return[format stringFromDate:(dt==nil?[TimeTool getIOSDefaultDate]:dt)];

}

+ (NSTimeInterval) getIOSTimeStamp:(NSDate*)dat{

    NSTimeIntervala = [dat timeIntervalSince1970];

    returna;

}

+ (long) getIOSTimeStamp_l:(NSDate*)dat{

    return[[NSNumbernumberWithDouble:[TimeTool getIOSTimeStamp:dat]] longValue];

}

+ (NSDate*)getIOSDefaultDate
{
return [NSDate date];
}

@end

6.2 调用示例

// 用于首页“消息”界面时

[TimeTool getTimeStringAutoShort2:[NSDatedate] mustIncludeTime:NO];

6.3 运行效果
 
▲ 上述代码在RainbowChat iOS版上的运行效果(首页)

7、Web网页端的代码实现(JavaScript)

7.1 完整源码

抱歉:因文章字数限制,JavaScript版源码无非法贴上来,请从链接:http://www.52im.net/thread-2371-1-1.html,查看JavaScript版完整源码!

7.2 调用示例

// 用于首页“消息”界面时

_getTimeStringAutoShort2(1550789954260, false);

// 用于聊天内容界面时

_getTimeStringAutoShort2(1550789954260, true);

7.3 运行效果
 
▲ 上述代码在RainbowChat-Web产品上的运行效果

附录:更多精品资源下载

[1] 精品源码下载:

《Java NIO基础视频教程、MINA视频教程、Netty快速入门视频 [有源码]》

《轻量级即时通讯框架MobileIMSDK的iOS源码(开源版)[附件下载]》

《开源IM工程“蘑菇街TeamTalk”2015年5月前未删减版完整代码 [附件下载]》

《微信本地数据库破解版(含iOS、Android),仅供学习研究 [附件下载]》

《NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战 [附件下载]》

《NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战 [附件下载]》

《NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示 [附件下载]》

《NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示 [附件下载]》

《用于IM中图片压缩的Android工具类源码,效果可媲美微信 [附件下载]》

《高仿Android版手机QQ可拖拽未读数小气泡源码 [附件下载]》

《一个WebSocket实时聊天室Demo:基于node.js+socket.io [附件下载]》

《Android聊天界面源码:实现了聊天气泡、表情图标(可翻页) [附件下载]》

《高仿Android版手机QQ首页侧滑菜单源码 [附件下载]》

《开源libco库:单机千万连接、支撑微信8亿用户的后台框架基石 [源码下载]》

《分享java AMR音频文件合并源码,全网最全》

《微信团队原创Android资源混淆工具:AndResGuard [有源码]》

《一个基于MQTT通信协议的完整Android推送Demo [附件下载]》

《Android版高仿微信聊天界面源码 [附件下载]》

《高仿手机QQ的Android版锁屏聊天消息提醒功能 [附件下载]》

《高仿iOS版手机QQ录音及振幅动画完整实现 [源码下载]》

《Android端社交应用中的评论和回复功能实战分享[图文+源码]》

《Android端IM应用中的@人功能实现:仿微博、QQ、微信,零入侵、高可扩展[图文+源码]》

《仿微信的IM聊天时间显示格式(含iOS/Android/Web实现源码)[图文+源码]》

[2] 精品文档和工具下载:

《计算机网络通讯协议关系图(中文珍藏版)[附件下载]》

《史上最全即时通讯软件简史(精编大图版)[附件下载]》

《重磅发布:《阿里巴巴Android开发手册(规约)》[附件下载]》

《阿里技术结晶:《阿里巴巴Java开发手册(规约)-终极版》[附件下载]》

《基于RTMP协议的流媒体技术的原理与应用(技术论文)[附件下载]》

《独家发布《TCP/IP详解 卷1:协议》CHM版 [附件下载]》

《良心分享:WebRTC 零基础开发者教程(中文)[附件下载]》

《MQTT协议手册(中文翻译版)[附件下载]》

《经典书籍《UNIX网络编程》最全下载(卷1+卷2、中文版+英文版)[附件下载]》

《音视频开发理论入门书籍之《视频技术手册(第5版)》[附件下载]》

《国际电联H.264视频编码标准官方技术手册(中文版)[附件下载]》

《Apache MINA2.0 开发指南(中文版)[附件下载]》

《网络通讯数据抓包和分析工具 Wireshark 使用教程(中文) [附件下载]》

《最新收集NAT穿越(p2p打洞)免费STUN服务器列表 [附件下载]》

《高性能网络编程经典:《The C10K problem(英文)》[附件下载]》

《即时通讯系统的原理、技术和应用(技术论文)[附件下载]》

《技术论文:微信对网络影响的技术试验及分析[附件下载]》

《华为内部3G网络资料: WCDMA系统原理培训手册[附件下载]》

《网络测试:Android版多路ping命令工具EnterprisePing[附件下载]》

《Android反编译利器APKDB:没有美工的日子里继续坚强的撸》

《一款用于P2P开发的NAT类型检测工具 [附件下载]》

《两款增强型Ping工具:持续统计、图形化展式网络状况 [附件下载]》

[3] 精选视频、演讲PPT下载:

《美图海量用户的IM架构零基础演进之路(PPT)[附件下载]》

《开源实时音视频工程WebRTC的架构详解与实践总结(PPT+视频)[附件下载]》

《QQ空间百亿级流量的社交广告系统架构实践(视频+PPT)[附件下载]》

《海量实时消息的视频直播系统架构演进之路(视频+PPT)[附件下载]》

《YY直播在移动弱网环境下的深度优化实践分享(视频+PPT)[附件下载]》

《QQ空间移动端10亿级视频播放技术优化揭秘(视频+PPT)[附件下载]》

《RTC实时互联网2017年度大会精选演讲PPT [附件下载]》

《微信分享开源IM网络层组件库Mars的技术实现(视频+PPT)[附件下载]》

《微服务理念在微信海量用户后台架构中的实践(视频+PPT)[附件下载]》

《移动端IM开发和构建中的技术难点实践分享(视频+PPT)[附件下载]》

《网易云信的高品质即时通讯技术实践之路(视频+PPT)[附件下载]》

《腾讯音视频实验室:直面音视频质量评估之痛(视频+PPT)[附件下载]》

《腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT[附件下载]》

《微信朋友圈海量技术之道PPT[附件下载]》

《手机淘宝消息推送系统的架构与实践(音频+PPT)[附件下载]》

《如何进行实时音视频的质量评估与监控(视频+PPT)[附件下载]》

《Go语言构建高并发消息推送系统实践PPT(来自360公司)[附件下载]》

《网易IM云千万级并发消息处理能力的架构设计与实践PPT [附件下载]》

《手机QQ的海量用户移动化实践分享(视频+PPT)[附件下载]》

《钉钉——基于IM技术的新一代企业OA平台的技术挑战(视频+PPT)[附件下载]》

《微信技术总监谈架构:微信之道——大道至简(PPT讲稿)[附件下载]》

《Netty的架构剖析及应用案例介绍(视频+PPT)[附件下载]》

《声网架构师谈实时音视频云的实现难点(视频采访)》

《滴滴打车架构演变及应用实践(PPT讲稿)[附件下载]》

《微信海量用户背后的后台系统存储架构(视频+PPT)[附件下载]》

《在线音视频直播室服务端架构最佳实践(视频+PPT)[附件下载]》 

《从0到1:万人在线的实时音视频直播技术实践分享(视频+PPT)[附件下载]》

《微信移动端应对弱网络情况的探索和实践PPT[附件下载]》

《Android版微信从300KB到30MB的技术演进(PPT讲稿)[附件下载]》

《从零开始搭建瓜子二手车IM系统(PPT)[附件下载]》

《极光分享:高并发海量消息推送系统架构演进(视频+PPT)[附件下载]》

(本文同步发布于:http://www.52im.net/thread-2371-1-1.html)

相关推荐

鸿蒙原生即时通讯/IM系统RainbowTalk v2.8版发布,基于MobileIMSDK框架、ArkTS编写

💧 此版本解决了若干bug,以及ui和功能细节优化,同时支持最新鸿蒙7.0系统。

hellojackjiang2011的博客 166

深度剖析IM消息乱序的根本原因及优化方法

本文深度剖析即时通讯IM消息乱序的问题,梳理IM客户端时间戳不可信、多端并发、群消息扇出重试三大核心陷阱,拆解微信、钉钉、企业微信的时序设计方案,并从锚点设计、多端去交错、幂等兜底、可观测性等维度,给出IM项目消息时序性保证的落地优化策略。

hellojackjiang2011的博客 293

IM聊天不掉线?生产级WebSocket断线重连、心跳保活实战

本文将给出一套生产级Web端即时通信方案,包括心跳检测保活 + 指数退避重连,代码直接能跑。

hellojackjiang2011的博客 327

IM全文检索技术(五):vivo敏感词匹配系统的技术实践

本文将从算法选型入手,结合两个实际场景来介绍谛听系统的敏感词匹配算法。包括底层算法选型思路和两种实际场景下提升敏感词精准度、降低漏杀率的方案。

hellojackjiang2011的博客 190

Nginx生产级WebSocket实时长连接负载均衡,一文搞定

本文从基础配置、生产配置、Docker / K8s、安全、排障、性能调优,系统性讲清 WebSocket 在 Nginx 中的正确打开方式。

hellojackjiang2011的博客 309

即时通讯IM离线消息该怎么存?全面盘点主流存储方案

离线消息是IM系统的核心能力,当用户不在线时,消息必须可靠存储,待用户上线后完整推送。本文将对比主流的离线消息存储方案,帮你找到最适合业务场景的架构。

hellojackjiang2011的博客 310

移动端实时音视频聊天框架 RainbowAV v2.2.7发布

1)

hellojackjiang2011的博客 247

都HTML5了,Web端即时通讯技术到底该用什么?一文即懂!

本文分享的是 Web 端最常用即时通讯技术(包括 WebSocket、SSE、WebRTC、轮询等)的原理、优缺点与适用场景等,以及生产环境下的高并发场景下的进阶实践。

hellojackjiang2011的博客 341

基于开源MobileIMSDK框架,即时通讯IM产品RainbowChat v12.1发布

此版本新增了短信验证码的注册和登录功能,解决了Android 16手机上发送文件失败等问题。

hellojackjiang2011的博客 209

IM千人群聊该不该用消息写扩散?详细算算成本账!

本文将为你详解 IM 群聊消息的写扩散技术原理以及写扩散过程中的服务端详细性能成本,同时对比了市面上IM大厂的技术方案,给出分规模架构选型与以及性能优化策略等。

hellojackjiang2011的博客 402

直播系统聊天技术(十):基于实时消息总线的活动系统架构设计

本文分享的是网易云音乐技术团队基于实时消息总线技术,解决了直播活动系统的模块灵活组合、消息治理与异步履约等问题,希望能给你带来启发。

hellojackjiang2011的博客 369

轻量级Web端IM即时通讯框架MobileIMSDK-Web,基于Socket.io库

MobileIMSDK-Web是一套Web端即时通讯框架,超轻量级、极少依赖,高度提炼、简单易用。

hellojackjiang2011的博客 286

socket长连接在手游场景下的技术实践

本文介绍了37手游基于B站goim框架自研长连接系统的实践。系统采用分层设计,支持多协议和发布/订阅机制,用于直播弹幕、实时推送等场景,实现了高性能与业务适配。

hellojackjiang2011的博客 404

基于开源MobileIMSDK框架,即时通讯IM产品RainbowChat v12.0发布

RainbowChat 是一套基于 MobileIMSDK 开源通信框架的产品级移动端IM系统。可能是市面上开放源码的,唯一一款同时支持TCP、UDP、WebSocket三种网络通信协议的IM产品。

hellojackjiang2011的博客 518

社交场景下的统一即时通讯im消息流交互层模块化技术实践

这些IM场景,在消息流的展示形式上是极为相似的,同时每个业务又有着自己特殊的交互需求。基于此,我们对IM消息流能力做了标准化的构建,来减少IM功能的业务接入成本;同时也是为了统一各个业务的技术方案,减少跨业务开发的理解和维护成本。

hellojackjiang2011的博客 572

现代IM系统中聊天消息的同步和存储方案探讨

本文内容主要涉及IM系统中的消息系统架构,探讨一种适用于大用户量的消息同步以及存储系统的架构实现,能够支持消息系统中的高级特性“多端同步”以及“消息漫游”。在性能和规模上,能够做到全量消息云端存储,百万TPS以及毫秒级延迟的消息同步能力。

hellojackjiang2011的博客 75

即时通讯安全篇(十六):对称加密 vs 非对称加密?一文搞懂

本文将以通俗案例讲解加密本质,介绍对称加密(含 AES、迪菲–赫尔曼密钥交换)与非对称加密(RSA)原理、特点及应用,并阐释其数学基础。

hellojackjiang2011的博客 397

网络编程入门如此简单(五):UDP跟TCP相比,到底差了什么?

本文将通俗易懂地为你类比解释UDP与TCP的核心差异,包括如何基于UDP实现TCP的可靠传输:通过模拟三次握手、添加序列号与确认机制解决顺序和丢包问题,利用滑动窗口控制流量,并引入拥塞控制算法来动态调整发送速率等。

hellojackjiang2011的博客 448

基于WebSocket的IM即时通信方案在H5游戏场景下的技术实践

本文将从H5游戏场景下的实时信息更新需求切入,探讨下在类似这种高并发、低延迟的业务需求中,如何使用 IM 方案来解决频繁的数据更新问题,也顺便介绍下 WebSocket 的基本运作流程等。

hellojackjiang2011的博客 1069

鸿蒙Next原生IM即时通讯RainbowTalk,纯ArkTS编写,基于开源MobileIMSDK框架

RainbowTalk 是一套基于 MobileIMSDK 开源通信框架的产品级纯血鸿蒙NEXT端IM系统。RainbowTalk 由纯ArkTS编写、全新开发,没有套壳、也没走捷径,原生“纯血”。

hellojackjiang2011的博客 1232

如何保障分布式IM聊天系统的消息可靠性(即消息不丢)

本文主要聚焦分布式IM聊天系统消息可靠性问题,即如何保证消息不丢失。

hellojackjiang2011的博客 732

如何保障分布式IM聊天系统的消息有序性(即消息不乱)

本篇主要总结和分享分布式IM聊天系统架构中关于消息有序性的设计和实践。

hellojackjiang2011的博客 835

B站即时通讯IM消息系统的新架构升级实践

本文要分享的是B站IM消息系统的新架构升级实践总结,内容包括原架构的问题分析,新架构的整体设计以及具体的升级实现等。

hellojackjiang2011的博客 714

AI大模型爆火的SSE技术到底是什么?万字长文,一篇读懂SSE!

本文从SSE(Server-Sent Events)技术的原理到示例代码,为你通俗易懂的讲解SSE技术的方方面面。

hellojackjiang2011的博客 787

腾讯新闻APP的消息推送Push架构技术重构实践

本文主要分享的是腾讯技术团队近年来对腾讯新闻消息推送PUSH系统做的架构优化和技术实践。

hellojackjiang2011的博客 843

移动端弱网优化专题(十五):字节跳动移动端网络HttpDNS优化实践

本文要分享的是字节跳动团队针对火山HTTPDNS Cache2.0通过自研网段库与动态划分算法,将缓存粒度从“城市-运营商”细化为“网段”,解决了传统方案的城市级调度污染问题。配合缓存分级、预取等优化,在提升调度精准度的同时保证了高命中率,最终实现了服务端调度准确性提升和客户端性能优化。

hellojackjiang2011的博客 720

转转客服IM聊天系统背后的技术挑战和实践分享

在当今互联网时代,高效的用户服务是提升用户体验的关键。转转自研的客服IM聊天系统作为用户与客服沟通的桥梁,承担着传递信息、解决问题的关键角色。然而,消息数据的流转并非一帆风顺,本文将深入探讨IM系统在消息传递过程中遇到的问题和挑战,以及相应的技术解决方案。

hellojackjiang2011的博客 1096

ChatGPT如何实现聊天一样的实时交互?快速读懂SSE实时“推”技术

本文将带你快速认识SSE实时通信协议,包括它的技术原理、常见使用场景、与同类技术的对比以及简单的示例代码等。

hellojackjiang2011的博客 124

全面适配iOS 26液态玻璃,基于开源IM即时通讯框架MobileIMSDK:RainbowChat-iOS端v10.2发布

RainbowChat是一套基于开源IM即时通讯聊天框架 MobileIMSDK 的产品级移动端IM系统。

hellojackjiang2011的博客 1157

可靠传输的TCP协议send成功就意味着数据一定发出去了?

本篇文章我们以TCP协议的网络编程逻辑,从Socket缓冲区的角度去拆解,为什么号称可靠传输的TCP协议,在代码中调用send并成功发出数据,并不意味着这个数据就一定通过物理网络发出去了。

hellojackjiang2011的博客 125
上一篇: 仿微信的IM聊天时间显示格式(含iOS/Android/Web实现)[图文+源码]
下一篇: 鹅厂7年终有离开之日,记离职鹅厂最后30天的真实心路历程
jackjiang2025
jackjiang2025 网际时代技术分享账号 网际时代技术分享账号
博客等级 码龄8年 700粉丝 318原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值