【有奖调研】GeekOnline社区建设意见征集 置顶

活动江南孤鹜 回复了问题 • 6 人关注 • 5 个回复 • 87 次浏览 • 2 天前 • 来自相关话题

【征稿活动】Geek Online 社区第一期投稿激励计划已启动! 置顶

活动梅川酷子 发表了文章 • 3 个评论 • 527 次浏览 • 2020-08-27 19:40 • 来自相关话题

为了回馈社区用户长期以来的支持,营造良好的社区技术氛围,鼓励更多开发者交流技术心得、分享技术实操方法及经验,创作更多优秀内容。特面向所有社区注册用户,举办第一期 Geek Online 社区投稿激励计划活动。活动时间征稿时间:8 月 27 日 – 10&nbs... ...查看全部

为了回馈社区用户长期以来的支持,营造良好的社区技术氛围,鼓励更多开发者交流技术心得、分享技术实操方法及经验,创作更多优秀内容。特面向所有社区注册用户,举办第一期 Geek Online 社区投稿激励计划活动。

活动时间

征稿时间:8 月 27 日 – 10 月 31 

评审时间:9、10 月每月最后一周进行

面向对象

Geek Online 社区所有注册用户

内容要求

对技术的介绍、产品的分析等技术类内容均可,也可以是个人实际操作的方法或经验总结,可供参考方向:

1、融云产品相关,选题包括:集成 IM 或 RTC 的使用体验、操作攻略、案例分享等。

2、结合市面上热度较高的事件/现象,从技术视角挖掘开发逻辑、产品解读等。

参赛规则

1、投稿需符合上述内容要求,图文并茂,排版美观,无错别字,代码规范。

2、在 Geek Online 社区发布文章参与,标题格式为【GeekOnline 投稿 | XXXXXXXXXX

3、稿件字数在 500 字以上

5、投稿数量不限,但所有稿件内容必须为 2020 年 8 月 27 日后作者本人新发内容

6、投稿人社区账号头像、昵称、个人介绍需资料完善

7、稿件投递后 个工作日内完成初审,并通过社区消息、邮箱通知。

评分细则

1、每月底将对当月参赛稿件进行评比,满分 10 。其中,

影响力 3 分,由社区内热度(阅读数)、互动量(点赞、评论数)加权计算;

专业性 7 分,由 Geek Online 技术专家及编辑组成的评审团,从文章实用性、创新性及代码规范度等方面综合评定给分。

2、我们鼓励投稿内容与融云产品相结合,对于此类稿件将给予社区置顶等曝光机会,增加文章影响力。

奖励

1、所有稿件通过初评,即可获得 Geek Online 加油包 1 份(内容发布 7 个工作日内发出)

2月度评选后,根据得分,给予优秀稿件 200-1000 元京东购物卡奖励,并在社区公示

3、优秀稿件,经编辑审核后,将安排在不限于公众号、社群及网媒中推广。

4、获奖作者,有机会加入社区特邀专栏作者计划,获得更高现金激励,并受邀参与融云各类开发者活动(线下/线上)

声明

1、在法律允许范围内,活动最终解释权归 Geek Online 社区所有。

2、参加活动的文章作者拥有著作权,Geek Online 社区、融云全媒体平台拥有使用权。

3、对于作者发布非原创内容或有争议内容所引起的一切后果,均由作者承担。欢迎社区用户举报,一经查实,作废处理。

【社区精华|持续更新】收录本社区精华内容,手把手教学IM/RTC开发! 置顶

技术交流admin 发表了文章 • 8 个评论 • 327 次浏览 • 2020-12-07 14:41 • 来自相关话题

本文收录了GeekOnline社区精华内容,希望帮助社区开发者学习IM+RTC知识,解答疑惑。赠人玫瑰,手有余香,如您有不错的内容需要收录,欢迎在在评论区投稿回复。Android篇融云即时通讯SDK集成 — 通知检查融云 IM SDK 集成 —- 刷新会话界面... ...查看全部

本文收录了GeekOnline社区精华内容,希望帮助社区开发者学习IM+RTC知识,解答疑惑。赠人玫瑰,手有余香,如您有不错的内容需要收录,欢迎在在评论区投稿回复。

微信截图_20201207144054.png

Android篇

融云即时通讯SDK集成 — 通知检查

融云 IM SDK 集成 —- 刷新会话界面和会话列表界面

Android 端如何添加自定义表情

解决融云 SDK 4.0 版本配置 https 导航报 SSLHandshakeException

融云清空历史消息 Android 端

唠一唠融云的消息扩展功能

融云 IMkit 拦截或监听所有发送消息

融云如何把图片消息的图片上传到自己的文件服务器

唠一唠融云 VIVO push 无法跳转的解决方案

融云即时通讯SDK集成 — 定制UI(一) ——会话界面小改动

融云即时通讯SDK集成 — 定制UI(二) ——添加自定义表情库

融云即时通讯SDK集成 — 定制UI(三) ——兼容Android Q

融云如何把图片消息的图片上传到自己的文件服务器

融云即时通讯SDK集成 — 华为推送的点击跳转处理

带你实现女朋友欲罢不能的 App

Flutter 集成融云 sdk

配置融云SDK的自签证书

自定义消息 包含 list 数组

关于融云聊天室KV 值的正确使用

融云 IM SDK 转 AndroidX

融云即时通讯SDK集成 — 国内厂商推送集成踩坑篇(Android平台)

在融云 IMkit 会话界面基础上添加消息已读未读

融云聊天室属性 kv

融云 ConversationListFragment 会话列表添加头部布局

融云即时通讯SDK集成 — FCM推送集成指南(Android平台)

融云集成之避坑指南-Android推送篇

融云IMKit 动态删除或添加plugin 的实现


iOS篇

iOS 基于实时音视频 SDK 实现屏幕共享功能——1

iOS 基于实时音视频 SDK 实现屏幕共享功能——2

iOS 基于实时音视频 SDK 实现屏幕共享功能——3

iOS 基于实时音视频 SDK 实现屏幕共享功能——4

如何隐藏融云输入框语音按钮

给融云的输入框上方加个功能按钮,怎么整?

融云 IM SDK 如何插入消息

集成融云 IMLib 时,如何实现一套类似于 IMKit 的用户信息管理机制

为融云聊天页面的输入框添加 Placeholder

30 分钟集成融云 IM 即时通讯

简单介绍融云 imkit 包含功能

融云的聊天页面在 iOS14 出现崩溃的解决办法

融云聊天页面长按消息后“翻译”功能的实现方法

使用融云 IM 点击最近聊天记录时跳转到 @ 自己的消息

如何设置融云用户信息

自定义融云会话列表 cell 选中背景

融云 IMKit 音频录制参数

融云会话页面刷新不及时问题

融云 Flutter IM SDK 解析

关于融云 SDK 在使用 p8 证书的坎坷~

融云 SDK 如何实现群组操作

如何利用融云 IMLib 来实现一个阅后即焚功能

干货分享——使用融云通讯能力库 IMLib 实现单群聊的阅读回执


Web篇

作为小白接融云 IM SDK 新路体验~

微信小程序集成融云 SDK (即时通讯) 集成必备条件

Web 端使用融云 SDK 集成实现滑动加载历史消息

融云IM SDK web 端集成 — 表情采坑篇

融云 Web SDK 如何实现表情的收发 ?

集成融云小程序 SDK 遇到的问题

使用融云 Web SDK 撤回消息

融云 RTC SDK 集成实现直播,趟坑之旅~~~

融云 Web SDK 删除历史消息

集成融云小程序 SDK 遇到的问题

Web 端集成融云 SDK 如何发送正确图片消息给移动端展示?

使用融云 IM SDK 实现 H5 直播聊天

WebRTC 实现实时音视频技术研究

融云发送语音消息

融云 CallLib 集成遇到的问题

结合融云 WebSDK 了解 WebSocket 基本原理

集成融云 Web 音视频通话踩坑之旅

SDK 兼容 JSON

融云 IM SDK 发送语音消息

集成融云 IM 问题总结

融云 Web SDK 如何实现只有一个设备登入

融云 Web 播放声音 — Flash 篇 (播放 AMR、WAV)

融云 IM 那些事儿

融云 AMR(Aduio) 播放 AMR 格式 Base64 码音频


社区福利

【领取见面礼】限量 100份 GeekOnline加油包!等你来拿

【有奖调研】Geek Online 2020 编程挑战赛参赛调研

【征稿活动】Geek Online 社区第一期投稿激励计划已启动!


GeekOnline编程挑战赛

Geek Online 2020 编程挑战赛官网

重磅!Geek Online 2020 编程挑战赛来了!

Geek Online 2020 编程挑战赛 GitHub 仓库

2 个月激烈角逐,15 支队伍突围决赛路演!Geek Online 2020 编程挑战赛完美收官!

一张图回顾 Geek Online 2020 编程挑战赛精彩瞬间!

“这些项目不是什么赚大钱的项目,但是它们足够有趣。”丨关于 Geek Online 2020 编程挑战赛,选手们如是说

融云 CTO 杨攀: Geek Online 2020 编程挑战赛 让开发者站上 C 位

【参赛攻略】你想了解的Geek Online 2020 编程挑战赛常见问题这里都有!

【融云集成常见问题整理】Geek Online 2020 编程挑战赛选手提问整理


求职招聘

【招聘】寻一枚熟悉融云IM的开发工程师,坐标合肥,待遇从优

和50万优质程序员一起成长——程序员客栈招聘

持续更新....

【融云集成常见问题整理】Geek Online 2020 编程挑战赛选手提问整理 置顶

融云集成梅川酷子 发表了文章 • 0 个评论 • 263 次浏览 • 2020-12-02 18:40 • 来自相关话题

内容整理自Geek Online 2020 编程挑战赛群答疑内容,关于大赛请点击Geek Online 2020 编程挑战赛了解详情。如果您有IM/RTC开发,融云开发文档建议等技术问题欢迎留言讨论。问题 1: 下载SDK如何选择?各大版本有什么区别?问题 1... ...查看全部

内容整理自Geek Online 2020 编程挑战赛群答疑内容,关于大赛请点击Geek Online 2020 编程挑战赛了解详情。如果您有IM/RTC开发,融云开发文档建议等技术问题欢迎留言讨论。

问题 1: 下载SDK如何选择?各大版本有什么区别?

问题 1 答案:使用最新版本 4.0 SDK ,新版 SDK 包含很多新功能并且会将历史版本遗留 Bug 进行修复,所以极力推荐使用新版 SDK 4.0+ 集成开发,下载地址:https://www.rongcloud.cn/downloads

问题 2 :开发环境和生产环境有什么区别?

问题 2 答案:  开发环境功能免费使用,但用户数有 100 个限制,生产环境无用户数限制,但需要付费,咱们的参赛同学使用开发环境集成就好

问题 3 :参赛过程中开发产生的费用怎么办?(注:本条仅限于参赛期间选手的参赛作品)

问题 3 答案:开发环境功能均可免费体验,遇到特殊情况可在战队群里向融云同学处理

问题 4 :小程序开发有什么注意事项?

问题 4 答案:

 (1)需要在开发者后台小程序中开通,开通 30 分钟后生效

 (2)小程序发布上线需要优先设置合法域名:https://docs.rongcloud.cn/v4/views/rtc/call/noui/quick/mini.html

 (3)小程序特殊分类需要证书,例如社交小程序需要 ICP 证书,所以大家选择小程序分类时要提前注意是否需要证书

问题 5: 融云支持哪些平台?

问题 5 答案:支持 iOS、Android、Web、Flutter、uniapp、Electron,如果有 IoT 需求可以私信融云同学

问题 6:  如果遇到集成文档问题,怎么办?(也可以在本篇文章留言回复)

问题 6 答案:可直接在战队群里反馈至融云同学,欢迎大家对文档的改进提出宝贵建议,感谢

问题7:ios没上线 push怎么做?

问题7答案:在融云开发者后台 -> 应用 -> 开发环境可以设置

微信图片_20201202183130.png


问题8:融云的RTC集成必须要集成IM?

问题8答案:RTC SDK 依赖于 IM SDK,一定要连接 IM 后再进行 RTC 相关的集成

问题9:融云新版SDK4.0版本和2.0版本对比有哪些升级?具体有哪些优化和提升?

问题9答案:4.0 SDK 是融云基于近几年的经验积累和沉淀进行的重构版,包含对架构、连接、重连、弱网等使用场景做了特殊优化,除核心能力优化外 4.0 SDK 还在持续发布新功能,例如:聊天室 KV 存储、会话置顶免打扰等

问题10:我想问一下,rongrtc的storage改动如何监听似乎rongclient设置接受到消息的onreceived回调不会触发。而改动storage 时是有设置第三个消息参数的,Sdk的debug会打印storage_set的,可以拦截不?

问题10答案:如果设置了第三个参数,会触发接收方的 RongRTC 实例的 Message received 监听

问题11:融云有没有小程序版的IM集成SDK?

问题11答案:有的,开发者后台开通小程序后可以直接下载小程序 IM SDK,开通位置:https://developer.rongcloud.cn/miniprogram/index/

问题12:弱弱的问一句,融云可否实现微信群机器人?现在微商盛行,想用融云做个自动问答的机器人客服 」

问题12答案:可以的,融云支持将消息路由的能力,消息路由到自己服务器后可以对接三方图文识别厂商

问题13:融云有内嵌到app的H5版本客服机器人吗?

问题14:不单独提供客服的,但 IM SDK 支持 H5 的

感谢各位选手的参与,Geek Online 2020 编程挑战赛 完美收官,关于大赛:

 Geek Online 2020 编程挑战赛官网

2 个月激烈角逐,15 支队伍突围决赛路演!Geek Online 2020 编程挑战赛完美收官!

“这些项目不是什么赚大钱的项目,但是它们足够有趣。”丨关于 Geek Online 2020 编程挑战赛,选手们如是说

一张回顾 Geek Online 2020 编程挑战赛精彩瞬间!


关于IM/RTC开发,融云开发文档建议等技术问题欢迎留言讨论

2 个月激烈角逐,15 支队伍突围决赛路演!Geek Online 2020 编程挑战赛完美收官! 置顶

技术交流梅川酷子 发表了文章 • 0 个评论 • 292 次浏览 • 2020-10-27 09:59 • 来自相关话题

2020 春季的一场疫情,让远程办公和在线教育在全球范围内成为一种常态。疫情终将过去,但疫情为人们带来的新的工作及生活方式却将持续地影响着我们。后疫情时代,远程实时互动技术的重要性被提到了新的高度,下一代互联网通信云将如何作用于人们的工作和生活?融云作为全球领... ...查看全部

2020 春季的一场疫情,让远程办公和在线教育在全球范围内成为一种常态。

疫情终将过去,但疫情为人们带来的新的工作及生活方式却将持续地影响着我们。后疫情时代,远程实时互动技术的重要性被提到了新的高度,下一代互联网通信云将如何作用于人们的工作和生活?

融云作为全球领先的互联网通信云厂商,一直致力于 RTC 技术的创新和发展,并于近期举办了 Geek Online 2020 编程挑战赛,希望借此机会与全球开发者一道,共同寻找 RTC 技术的更多落地场景,开辟更多使用途径。

10 月 17 日,为期两个月的编程挑战赛迎来了最为紧张的决赛阶段, 15 支队伍进行了线上的路演答辩。

决赛路演,大屏直播互动

本届 Geek Online 2020 编程挑战赛以《后疫情时代,通信云技术的创新及实践》为主题,鼓励开发者挖掘关于实时音视频和即时通讯技术的更多创意。通过近 2 个月的激烈角逐,在近百份参赛作品中,15 支队伍突出重围,闯入总决赛,他们通过线上展示的方式和大家分享,角逐最后的冠军。

本次决赛的评委共有四位,分别是融云联合创始人兼 CTO 杨攀、思否联合创始人兼 CTO 祁宁、泰岳梧桐资本合伙人杨扬以及通过线上直播参与路演的评委云启资本董事总经理陈昱。

1.png
       
     

 

路演答辩借助了融云 RTC 技术搭建了一个实时互动直播平台,选手轮流进入融云实时音视频 - SealRTC 平台进行画面共享,四位导师也可以在平台内实时与选手视频交流互动。

 


       2.png
     

 

路演直播画面

部分参赛选手作品展示 & 评委点评


       3.jpg
     

 

冠军团队 - 缘拼

该团队成员擅长 uniapp 以及微信小程序开发,作品基于融云 RTC 技术。这是一款基于兴趣、基于地理位置的同城社交类小程序,可以语音、视频构建同城兴趣小组,并将线上兴趣转换为线下社交行为。相当于将豆瓣兴趣小组音视频化。




        4.jpg       

 

亚军团队 - 红鲤鱼与绿鲤鱼与驴

该作品由两位选手共同完成,分别是熟悉前端、WebRTC 方向的“红鲤鱼”和熟悉后端、大数据方向的“绿鲤鱼”。这是一款帮忙新手程序员迅速熟悉融云 SDK 的小游戏,通过识别二维码拼图的游戏,让了解融云的过程有趣味性。该作品层次丰富,第一层需要用户集成融云 SDK、掌握融云的基本概念,第二层需要用户做一定程度的视频后处理,第三层需要用户做一些图像识别。




     5.jpg       

 

季军团队 - youweyoung

获得第三名的团队包含了一位拥有前后端多年开发经验的选手。作品基于 Android 操作系统使用 RTC 混合开发,最终做出了音视频通话应用 —— IYI网络剧场,将角色扮演类的剧本杀游戏以视频形式展现,每个场景有不同的主题人物并且可以替换,人物则是以皮影、动画等形式展现,适用于远程视频讲故事或玩剧本杀,有一定新颖性。




       6.jpg       

 

科技创新奖团队 - 萍水相逢的生活

这支队伍只有一位选手,他是一个心怀想法的程序员,做的产品是一个基于事务的陌生人聊天系统,事务场景可以是租房加中介的联系方式、街头偶遇添加好友、发布大字报等,这款产品的设计思路旨在为大家生活提供便利的软件。




       7.jpg       

 

 

商业价值奖团队 - MAXFLOAT

MAXFLOAT 是一支有实力,有梦想,有创意,敢拼搏,即想即做的队伍。他们认为当前城市化生活环境下人与人的交流越来越少,宠物逐渐替代朋友成为更好的伙伴,养宠物的越来越多,但随之而来的是更多的问题,比如宠物的遗失、被抛弃造成了流浪宠物越来越多,而宠物的健康,有时也不能及时得到重视。因此他们做了一款以宠物招领、寄养、寻回、宠物医生等为主,以宠物信息普及、宠物疾病普及为辅的 APP 帮助广大宠物爱好者。






包含获奖团队在内的 15 组团队,作品各具特色,即为评委以及线上观众们展示了自身的产品创意,也展示了 RTC 技术在实际应用中的能力与延展性,很多选手的作品获得了评委们的高度评价。我们对获奖团队进行了单独的采访,内容会于后续发出,敬请期待。

在选手们精彩的分享以及答辩之后,四位评委嘉宾分别给出了对于参加本次比赛的感受。






“融云始于 IM,又不止于 IM。通过融云提供的技术以及服务能力,开发者们可以更加关注线上的优化与迭代,期待更多开发者利用融云SDK,开发更创新、强大的产品。” —— 陈昱






“本次的决赛中我有很多印象深刻的作品,有的非常符合开发者的口味,有的对于使用场景有着很深入的思考。因为疫情,通信云技术的需求正在变得越来越大、越来越丰富,有很多场景需要我们去开拓,很值得开发者们关注并付出行动。” —— 祁宁






“选手们有很多创意创新点都很好,将很多现实中生活化的场景融入到比赛中,也有一些具有极客特质的项目,这些都是融云自身生态开发能力非常好的体现。对于融云来说,开发者是宝贵的资源,而通信云的生态也需要非常广泛的群体参与,共同完善。” —— 杨扬






“很高兴的看到,决赛中有很多作品提到了人们的心理问题,除开产品技术本身,还致力于解决人文层面的诉求。基于 IM 的核心能力,选手们提供了很多在线的沟通场景,比如剧本杀、狼人杀等等,基于这些实时互动的模式,通信能力已经变成了现代应用的一种基础设施,能为产业、产品和应用场景提供帮助,这让我们既感到压力,也感受到了更强大的动力。” —— 杨攀

结语

通过选手们的展示,我们可以了解到通信云技术的发展和提升不仅仅可以作用于工作和学习,关于实时音视频和即时通讯技术的应用,还有更多创新的场景等待我们用全新的思维来发掘。

Geek Online 2020 编程挑战赛虽然是第一次举办,但已经收获了参赛选手以及观看决赛路演直播观众们的一致好评,部分选手在路演结束后已经联系主办方咨询第二届比赛的安排,想要提前报名。

融云作为专注于通信的 PaaS 云服务平台,想要通过底层的基础模块支持,帮助企业与开发者构建「云通信」的能力。举办此次编程挑战赛的目的,也是希望让开发者们碰撞出技术的思维火花,加速潮流技术的应用创新,也为开发者们搭建了一个沟通、交流、合作的平台,希望能够掀起一股通信技术应用的探索与实践热潮。

点击进入大赛官网,查看更多比赛信息


       4aQyJP5TdHkx0NXM__thumbnail.png       


安卓使用官方的demo好友问题

技术交流admin 回复了问题 • 2 人关注 • 1 个回复 • 18 次浏览 • 2 天前 • 来自相关话题

技术实践丨IM 消息同步机制全面解析

技术交流柠檬^ 发表了文章 • 0 个评论 • 18 次浏览 • 3 天前 • 来自相关话题

综述即时通讯系统最基础、最重要的是消息的及时性与准确性,及时体现在延迟,准确则具体表现为不丢、不重、不乱序。综合考虑业务场景、系统复杂度、网络流量、终端能耗等,融云精心设计了消息收发机制,并不断打磨优化,形成了现在的消息同步机制。整体思路:1.客户端、服务端共... ...查看全部
综述


即时通讯系统最基础、最重要的是消息的及时性与准确性,及时体现在延迟,准确则具体表现为不丢、不重、不乱序。

综合考虑业务场景、系统复杂度、网络流量、终端能耗等,融云精心设计了消息收发机制,并不断打磨优化,形成了现在的消息同步机制。

整体思路:
1.客户端、服务端共同配合,互相补充。
2.采用多重机制,从不同层面保障。
3.拆分上下行,分别处理。

协议层

首先,从协议层保证,协议栈需要提供可靠、有序的双向字节流传输,融云自研通信协议 RMTP(RongCloud Message Transfer Protocol)。

1.jpg

协议交互示意图


协议层通过 qos、 ack 等机制,保证数据传输的可靠性。

业务层

在关键业务,采用 ack 确认机制,配合状态机,服务感知当前业务传输状态,保障业务按照预期执行。

2.jpg

业务层确认机制示意图


消息 ID

采用全局唯一的消息 ID 生成策略。保证消息可通过 ID 进行识别,排重。

3.jpg

如何实现分布式场景下唯一 ID 生成,请点击融云过往技术文章了解。


客户端服务端交互

客户端与服务端之间使用长连接,基于 RMTP 协议传输数据。
经过总结,主要用三种行为:

1.客户端主动拉取消息,主动拉取有两个触发方式:
①与 IM 服务新建立连接成功,用于获取不在线的这段时间未收到的消息。(此处叫做获取离线消息)
②定时器触发。在客户端最后收到消息后启动定时器,比如 3-5 分钟执行一次, 主要有两个目的,一个是用于防止因网络,中间设备等不确定因素引起的通知送达失败,服务端客户端状态不一致,一个是可通过本次请求,对业务层做状态机保活。

2.服务端主动-发送消息(直发消息) 在线消息发送机制之一,简单理解为服务端将消息内容直接发送给客户端,适用于消息频率较低,并且持续交互,比如二人或者群内的正常交流讨论。

3、服务端主动-发送通知(通知拉取) 在线消息发送机制之一,简单理解为服务端给客户端发送一个通知,通知包含时间戳等可作为排序索引的内容,客户端收到通知后,依据自身数据,对比通知内时间戳,发起拉取消息的流程。适用于较多消息传递。比如某人有很多大规模的群,每个群内都有很多成员正在激烈讨论。通过通知拉取机制,可以有效的减少客户端服务端网络交互次数,并且对多条消息进行打包,提升有效数据载荷。既能保证时效,又能保证性能。

4.jpg

客户端服务端交互示意图


业务拆分

在有了多层机制保证后,将业务进行拆分,首先将业务拆分出上下行,在上行过程保证发送消息顺序,为了保证消息有序, 最好的方式是按照 userId 区分,然后使用时间戳排序。那么分布式部署情况下,将用户归属到固定的业务服务器上,会使得上行排序变得更容易。同时归属到同一个服务器,在多端维护时也更容易。

客户端连接过程
1.客户端通过 APP server ,获取到连接使用的 token。
2.客户端使用 token 通过导航服务,获取具体连接的 IM 接入服务器(CMP),导航服务通过 userId 计算接入服务器,然后下发,使得某一客户端可以连接在同一台接入服务器(CMP)。

5.jpg

示意图


上行

客户端发出消息后,通过接入服务,按照 userId 投递到指定消息服务器,生成消息 Id, 依据最后一条消息时间,确认更新当前消息的时间戳(如果存在相同时间戳则后延),然后将时间戳,以及消息 Id,通过 Ack 返回给客户端 ; 然后对上行消息使用 userId + 时间戳进行缓存以及持久化存储,后续业务操作均使用此时间戳。(此业务流程我们成为上行流程,上行过程存储的消息为发件箱消息)

下行

消息节点在处理完上行流程后,消息按照目标用户投递到所在消息节点,进入下行流程。下行过程,按照目标 userId 以及本消息在上行过程中生成的时间戳,计算是否需要更新时间戳(正向)。如果需要更新则对时间戳进行加法操作,直到当前用户时间戳不重复。如此处理后,目标用户的存储以及客户端接收到消息后的排重可以做到一致,并且可以做到同一个会话内的时间戳是有序的。从而保证同一个接收用户的消息不会出现乱序。

至此,我们已经完成了发送过程,接收过程的消息顺序保障,那么消息流程还剩下直发与通知拉取的处理流程,以及服务端如何选择是直发还是通知拉取。

直发消息

1、客户端 SDK 依据本地存储的最新消息时间戳判断,用来做排序等逻辑。
2、对同一个用户直发消息1条,其他转通知。通知拉取时候客户端选择本地最新一条消息时间戳作为开始拉取时间。
3、在消息发送过程中,如果上一条消息发送流程未结束,下一条消息则不用直发(s_msg),而是用(s_ntf)

6.jpg

直发逻辑示意图


通知拉取

1.服务端在通知体中携带当前消息时间戳。投递给客户端。
2.客户端收到通知后,比对本地消息时间戳,选择是否发拉取消息信令。
3.服务端收到拉取消息信令后,以信令携带的时间戳为开始,查询出消息列表(200 条或者 5M),并给客户端应答。
4.客户端收到后,给服务端 ack,服务端维护状态。
5.客户端拉取消息时使用的时间戳,是客户端本地最新一条消息的时间戳。

7.jpg

上图中,3-7 步可能需要循环多次,有以下考虑: 1.客户端一次收到的消息过多,应答体积过于庞大,传输过程对网络质量要求更高, 因此按照数量以及消息体积分批次进行。2. 一次拉取到的消息过多,客户端处理会占用大量资源,可能会有卡顿等,体验较差。


服务端直发消息与通知拉取切换逻辑

主要涉及到的是状态机的更新。下面示意图集成直发消息与通知拉取过程针对状态机的更新:

8.jpg

至此,消息收发核心流程介绍完毕,只剩下多端在线的处理。


多端在线同步

多端按照上下行,同样区分为发送方多端同步以及接收方多端同步。

发送方多端同步

在前面客户端连接 IM 服务过程中,我们已经将同一个用户的客户端汇聚在了同一台服务,那么维护一个 userId 的多端就会变得很简单。

1.用户多个终端链接成功后,发送一条消息,这个消息到达 CMP(IM 接入服务) 后,CMP 做基础检查,然后获此用户的其他终端连接。

2.服务把客户端上行的消息,封装为服务端下行消息,直接投递给用户的其他客户端。这样完成了发送方的多端抄送,然后将这条消息投递到 IM 服务。进入正常发送投递流程。发送方的多端同步没有经过 IM Server,这么做的好处是:1.比较快速;2.经过越少的服务节点,出问题的几率越小。

接收方多端同步

1.IM 服务收到消息后,先判断接收方的投递范围,这个范围指的是接收方用户的哪些的终端要接收消息。

2.IM 服务将范围以及当前消息,发送到 CMP,CMP 依据范围,匹配接收方的终端,然后投递消息。

区分接收方多端范围应用场景: 消息一般是所有终端。

有一些特殊业务,比如我在 A 客户端上,控制另外某个端的状态,可能需要一些命令消息, 这时候需要这个作用范围,针对性的投递消息。

9.jpg到此,我们分析完了有关 IM 消息核心处理流程,通过层层拆解逻辑,提供可靠的消息投递机制。

万人群聊的消息分发控速方案

技术交流徐凤年 发表了文章 • 0 个评论 • 18 次浏览 • 3 天前 • 来自相关话题

当前阶段,群聊已经成为主流IM软件的基本功能,不管是亲属群,朋友群亦或是工作群,都是非常常见的场景。随着移动互联网的发展,即时通讯服务被广泛应用到各个行业,客户业务快速发展,传统百人甚至千人上限的群聊已经无法满足很多业务发展需求,所以超大群的业务应运而生。&n... ...查看全部

当前阶段,群聊已经成为主流IM软件的基本功能,不管是亲属群,朋友群亦或是工作群,都是非常常见的场景。随着移动互联网的发展,即时通讯服务被广泛应用到各个行业,客户业务快速发展,传统百人甚至千人上限的群聊已经无法满足很多业务发展需求,所以超大群的业务应运而生。

 

1超大群面临的挑战

我们以一个万人群的模型进行举例:

1、如果群中有人发了消息,那么这条消息需要按照1:9999的比例进行分发投递,如果我们按照常规消息的处理流程,那么消息处理服务压力巨大。

2、消息量大的情况下,服务端向客户端直推消息的处理速度将会成为系统瓶颈,而一旦用户的消息下发队列造成了挤压,会影响到正常的消息分发,也会导致服务缓存使用量激增。

3、在微服务架构中,服务以及存储(DB,缓存)之间的QPS和网络流量也会急剧增高。

4、以群为单位的消息缓存,内存和存储开销较大(消息体的存储被放大了万倍)。

基于这些挑战,我们的服务势必要做一定的优化来应对。

 

2群消息分发模型

整体的群聊服务架构如下图所示:

1.png

   用户在群里发了一条群消息后,消息先到群组服务,然后通过群组服务缓存的群关系,锁定这条消息最终需要分发的目标用户,然后根据一定的策略分发到消息服务上,消息服务再根据用户的在线状态和消息状态来判断这条消息是直推、通知拉取还是转Push,最终投递给目标用户。

 

3超大群消息分发解决方案

3.1分发控速:

第一,首先我们会根据服务器的核数来建立多个群消息分发队列,这些队列我们设置了不同的休眠时间以及不同的消费线程数,这里可以理解为快、中、慢等队列。如下图所示:

2.png

第二,我们根据群成员数量的大小来将所有群映射到相应的队列中,规则是小群映射到快队列中,大群映射到相应的慢队列中。

第三,小群由于人数少,对服务的影响很小,所以服务利用快队列快速的将群消息分发出去,而大群群消息则利用慢队列的相对高延时来起到控速的作用。

3.2 合并分发:

一条群消息发送到IM服务器后,需要从群组服务投递给消息服务,如果每一个群成员都投递一次,并且投递的群消息内容是一致的话,那肯定会造成相应的资源浪费和服务压力。

服务落点计算中我们使用的是一致性哈希,群成员落点相对固定,所以落点一致的群成员我们可以合并成一次请求进行投递,这样就大幅提高了投递效率同时减少了服务的压力。

3.3 超大规模群的处理方案

在实际群聊业务中,还有一种业务场景是超大规模群,这种群的群人数达到了数十万甚至上百万,这种群如果按照上述的分发方案,势必也会造成消息节点的巨大压力。比如我们有一个十万人的群,消息节点五台,消息服务处理消息的上限是一秒钟4000条,那每台消息节点大约会分到2万条群消息,这超出了消息节点的处理能力。

所以为了避免上述问题,我们的超大群(群成员上线超过3000,可以根据服务器数量和服务器配置相应做调整)会用特殊的队列来处理群消息的分发,这个特殊的队列一秒钟往后端消息服务投递的消息数是消息服务处理上限的一半(留相应的能力处理其他消息),如果单台消息服务处理的QPS上限是4000,那群组服务一秒往单台消息服务最多投递2000条。

 

结束语

我们后续也会针对群消息进行引用分发,对于大群里发的消息体比较大的消息,我们给群成员只分发和缓存消息的索引,比如MessageID,等群成员真正拉取群消息时再从将消息组装好给客户端分发下去。这样做会节省分发的流量以及存储的空间。

随着互联网的发展,群组业务的模型和压力也在不停地扩展,后续可能还会遇到更多的挑战,届时我们服务器也会通过更优的处理方式来应对。

 

感兴趣的开发者可以扫码下载融云的 IM 即时通讯 Demo 产品:SealTalk,体验融云的群聊、聊天室等通信能力。

3.png

【融云分析】WebRTC如何通过STUN、ICE协议实现P2P连接

技术交流赵炳东 发表了文章 • 0 个评论 • 18 次浏览 • 3 天前 • 来自相关话题

WebRTC中两个或多个主机进行P2P连接是通过STUN、TURN、ICE等技术实现的。主机往往都是在NAT之后,且不同的NAT导致外部主机向内网主机发送数据的可见性不同。 内网主机通过STUN协议可以获得NAT分配的外部地址。ICE是主机之间发现P2P传输路... ...查看全部

WebRTC中两个或多个主机进行P2P连接是通过STUN、TURN、ICE等技术实现的。主机往往都是在NAT之后,且不同的NAT导致外部主机向内网主机发送数据的可见性不同。 内网主机通过STUN协议可以获得NAT分配的外部地址。ICE是主机之间发现P2P传输路径机制,ICE中使用了STUN协议进行连通检测、传输路径的指定和保活。 本文将对STUN和ICE协议进行分析和解读,希望能为开发者们带来一些启发和帮助

1. NAT类型

网络地址转换, 简称NAT,节省了IPv4地址空间的使用并且隔离了内网和外网。NAT对待UDP的实现方式有4种,分别如下:

1.1完全圆锥型

一个内网地址(iAddr:iPort)被映射到一个外网地址 (eAddr:ePort)。这个内网(iAddr:iPort)地址发送的数据包都会通过这个外网地址(eAddr:ePort)。外部主机可以通过这个外网地址(eAddr:ePort)向这个内网地址(iAddr:iPort)发送数据包

1.png

1.2地址受限锥型

一个内网地址(iAddr:iPort)被映射到一个外网地址 (eAddr:ePort)。这个内网(iAddr:iPort)地址发送的数据包都会通过这个外网地址(eAddr:ePort)。外部主机 (hAddr:any) 只有接收过从内网(iAddr:iPort)发送来的数据包后,才能通过外部地址 (eAddr:ePort)发送数据包给内网地址(iAddr:iPort)。其中外部主机的端口可以是任意的。

2.png

1.3端口受限锥型

一个内网地址(iAddr:iPort)被映射到一个外网地址 (eAddr:ePort)。这个内网(iAddr:iPort)地址发送的数据包都会通过这个外网地址(eAddr:ePort)。外部主机 (hAddr:hPort) 只有接收过从内网(iAddr:iPort)发送来的数据包后,才能通过外部地址 (eAddr:ePort)发送数据包给内网地址(iAddr:iPort)。其中外部主机的端口hPort是受限的。

3.png

1.4对称型

一个内网地址(iAddr:iPort)向外网地址 (sAddr1:sPort1)发送的多次请求时,NAT会分配同一个外网地址(eAddr1:ePort1)。若向不同的外网地址如(sAddr2:sPort2)发送数据包时,NAT分配另外一个外网地址(eAddr2:ePort2)。外网地址 (sAddr1:sPort1)只有接收过从内网(iAddr:iPort)发送来的数据后,才能通过已经在NAT上开辟的(eAddr1:ePort1)发送数据包给内网.

4.png

2. STUN简介

STUN是Session Traversal Utilities for NAT简写,RFC5389规定了具体内容。STUN协议是用来获取内网地址对应在NAT上的外网地址,NAT穿越。 STUN是C/S模式的协议,由客户端发送STUN请求;STUN服务响应,告知由NAT分配给主机的IP地址和端口号。

2.1 STUN消息结构

STUN消息头为20字节,后面紧跟0或多个属性。STUN头部包含一STUN消息类型、magic cookie、事务ID和消息长度。 

5.png

(图)STUN消息结构

每个STUN消息的最高位前2位必须为0。当多个协议复用同一个端口的时候,这个可以用于与其他协议区分STUN数据包。 消息类型确定消息的类别(如请求、成功回应、失败回应、指示indication)。虽然这里有四种消息类型,但可以分为2类事务:请求/响应事务、指示事务。

magic cookie为固定值0x2112A442。

Transaction ID标识同一个事务的请求和响应。当客户端发送多个STUN请求,通过Transaction ID识别对应的STUN响应。

2.2 STUN消息类型

6.png

(图)STUN消息类型

C0和C1位置的bit指明了消息的分类。其余的12位置标示不同的请求类型,比如绑定请求。

2.3 STUN属性

STUN头之后是0或多个属性。每个属性都采用TLV编码,type为16位的类型、lenght为16位的长度、value为属性值。每个STUN属性必须是4字节对齐。

7.png

(图)STUN属性

STUN属性格式

STUN服务器请求和响应都包含消息属性。一些属性不是强制性的,其中一些只能出现在绑定请求中,而其他一些只能出现在绑定响应中。  属性空间被划分为2个范围。强制理解属性STUN代理必须处理,否则STUN代理将无法正常处理该属性的消息;STUN代理不能理解可选理解属性的话,这些属性可以被忽略。

强制理解属性 (0x0000-0x7FFF):

8.png

 可选理解属性 (0x8000-0xFFFF)

9.png

具体说明如下: MAPPED-ADDRESS属性标识了NAT映射后的地址。

XOR-MAPPED-ADDRESS属性与MAPPED-ADDRESS属性一致,映射后的地址要做异或处理。

USERNAME属性用于消息完整性。用户名和密码包含在消息完整性中。

MESSAGE-INTEGRITY属性是STUN消息的HMAC-SHA1值,长度20字节。MESSAGE-INTEGRITY属性可以出现在任何类型的STUN消息中。用作HMAC输入的文本是STUN消息,包括头部,直到且包括MESSAGE-INTEGRITY属性前面的属性。FINGERPRINT属性出现MESSAGE-INTEGRITY后。所以FINGERPRINT属性外,STUN代理忽略其他出现在MESSAGE-INTEGRITY属性后的任何属性。

FINGERPRINT属性可以出现在所有的STUN消息中,该属性用于区分STUN数据包与其他协议的包。属性的值为采用CRC32方式计算STUN消息直到但不包括FINGERPRINT属性的的结果,并与32位的值0x5354554e异或。

ERROR-CODE属性被用于错误响应消息中。它包含一个在300至699范围内的错误响应号。

REALM属性出现在请求中,表示认证时要用长期资格。出现在响应中,表示服务器希望客户端使用长期资格进行认证。

NONCE属性是出现在请求和响应消息中的一段字符串。

UNKNOWN-ATTRIBUTES属性出现在错误代码为420的的错误响应,表示服务器端无法理解的属性。

SOFTWARE属性用于代理发送消息时所使用的软件的描述。

ALTERNATE-SERVER属性表示STUN客户可以尝试的不同的STUN服务器地址。属性格式与MAPPED-ADDRESS相同。

2.4 STUN示例

下面是Wireshark抓取的一对STUN绑定请求和响应。STUN绑定请求,源地址192.168.2.36:47798,目标地址180.76.137.157:30001。

10.png

STUN绑定响应,源地址180.76.137.157:30001,目标地址192.168.2.36:47798

11.png

其中ICE-CONTROLLING、PRIORITY属性是下面提到的ICE中扩充的属性。

3. ICE简介

ICE两端并不知道所处的网络的位置和NAT类型,通过ICE能够动态的发现最优的传输路径。如下图L和R是ICE代理,下面简称L和R。L和R有各自的传输地址,包括主机的网卡地址、NAT上的外网地址、 TURN服务地址。ICE就是要从这些地址中,找到L和R的候选地址对,实现两端高效连通。

12.png

(图)ICE部署图举例

ICE两端可以通过信令服务器交换SDP信息。ICE使用STUN,TURN等协议来建立会话。

3.1收集候选地址

ICE端收集本地地址。通过STUN服务收集NAT外网地址;通过TURN收集中继地址。

所以有四种候选地址:

13.png

如下图: 主机候选X:x 服务器反射候选X1':x1' 中继候选Y:y 这里称主机候选地址是服务器候选地址的BASE。

14.png

(图)ICE端口

3.2连通检测

L收集了所有的候选地址后,按优先级从高到低排序,通过信令服务器发送SDP offer给R。R收到offer后,收集获选地址,并将自己候选地址放入SDP answer发送给L。此时两端都有了对端的和本端的候选地址。然后配对,生成candidate pair。为了确保candidate pair的有效性,两端都要做连通检测。根据candidate pair,从本地candidate发送STUN请求到远端candidate;接收端返回STUN响应给发送端。如下图。

15.png

(图)ICE基本连通检测

两端都按照各自checklist分别进行检查。

当R收到L的检测时,R发送向L的检测被称为Triggered检测。

3.3 Candidates pair排序

将连通性检查成功的candidate pair按优先级排序加入check list。两端定期遍历这个check list, 发送STUN请求给对端称为Ordinary检测。优先级的计算根据以下原则: 每端给自己的candidate一个优先级数值。本端优先级和远端优先级结合,得到candidate pair的优先级优先级。

公式 priority = (2^24)*(type preference) + (2^8)*(local preference) + (2^0)*(256 - component ID)

16.png

再根据candidate的优先级计算candidate pair的优先级。

priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0)

G:controlling candidate 优先级 D:controlled candidate 优先级

3.4提名Candidates

ICE中有两种角色, controlling角色可以选取最终的candidate pair;controlled角色会等待controlling角色选取的candidate pair。 ICE指定一个ICE代理为controlling角色,其他ICE代理为controlled角色。ICE优先检测优先级高的candidate pair。

Controlling角色有两中提名方案:REGULAR提名:当得到至少一对有效的pair的时候,Controlling角色就会选择其中的一个pair作为候选,此次连通检测发送一个带flag的请求,告诉对端这个就是被选中的pair。

17.png

(图)REGULAR提名

AGGRESSIVE提名:Controlling角色会在每个STUN请求之中添加flag标志,最先成功的那个被选为媒体传输通道。

18.png

(图)AGGRESSIVE提名

3.5 ICE示例

下面是例子中,L和R都是full模式ICE代理,采用aggressive提名,传输媒体为RTP。full模式为双方都要进行连通性检查,都要的走一遍流程;lite模式为,full模式ICE一方进行连通性检查,lite一方只需回应response消息。

19.png

(图)ICE举例

便于理解,采用"主机类型-网络类型-序号"的格式表示传输的地址。地址有两个分量,分别是IP和PORT。L,R,STUN,NAT代表不同的主机类型;PUB代表外网,PRV代表内网; L处在内网中,内网地址是10.0.1.1,R处在外网,外网地址是192.0.2.1。L和R都配置了STUN服务,地址是192.0.2.2,端口是3478。L在NAT后面,NAT外网地址是192.0.2.3。序号表示不同的媒体类型,这里只有RTP所以序号为1。 "S="表示STUN消息的发送地址、"D=" 表示STUN消息的接收地址。 "MA=" 表示STUN绑定响应的中mapped address。"USE-CAND" 表示带有"USE-CANDIDATE" STUN消息。

L收集本地候选地址,并发起STUN绑定请求给STUN服务器,L得到 NAT-PUB-1作为服务器反射候选地址。 L计算候选的优先级,主机候选地址type preference为126;服务器反射候选地址type preference为100。local preference为65535。component ID为1 套用公式priority = (2^24)*(type preference) + (2^8)*(local preference) + (2^0)*(256 - component ID) 得主机候选地址的优先级为2130706431,服务器反射候选地址的优先级为1694498815。 L设置主机候选地址的foundation为1,服务器反射候选地址foundation为2。  L将服务器反射候选地址作为default候选地址。对应的offer sdp为

20.png

替换地址后

21.png

因为L和R都采用的是full-mode,这种情况下ICE协议规定发送offer为controlling端,L为controlling端。 L和R生成candidate pair,两端都有2个candidate pair。L会裁减掉包含服务映射候选地址,保留candidate pair为本端$L_PRIV_1、远端$R_PUB_1

22.png

消息9表示R做连通检测,因为R是controlled角色,所以无需设置USE-CANDIDATE。L处于NAT后面,且没有向R发送过请求,所以此次连通检测会失败。

当L收到answer sdp后,开始连通检测(消息10-13)。L采用的是aggressive提名,所以每个请求都会有USE-CANDIDATE。L使用candidate pair为$L_PRIV_1/$R_PUB_1发起的连通检测成功后,L创建一个新的candidate pair,本端为NAT-PUB-1(消息13中得到) 、远端为R-PUB-1(消息10中得到),加入valid list中。这个连通检测中设置了USE-CANDIDA属性,该candidate pair为选中的候选。L的RTP流在valid list中有选中的candidate pair,所以L进入完成状态。

R收到L的STUN绑定请求(消息11)后,R发起消息11对应的Triggered检测,其candidate pair的本端为R-PUB-1、远端为NAT-PUB-1。检测成功后,R创建本端为R-PUB-1、远端为NAT-PUB-1的candidate pair,加入valid list。因为消息11中包含了USE-CANDIDATE,所以这个candidate pair就被选中为这个RTP流的传输通道。R进入完成状态。

4. 总结

本文介绍了NAT、STUN、ICE等基本概念。STUN部分介绍了STUN的消息结构、消息类型和消息属性ICE协议中STUN消息要遵循STUN协议。 ICE部分介绍了ICE代理之间是如何根据各自的网络地址建立连接的步骤有收集候选地址、连通检测、Candidates pair生成与排序、提名Candidates。 详细内容还需查看ICE协议rfc5245以及webrtc的p2p部分的具体实现。


感谢融云的新春礼包 -- 暖暖冬日,雪中送炭

其他江南孤鹜 发表了文章 • 1 个评论 • 21 次浏览 • 3 天前 • 来自相关话题

昨天收到一个高大上的礼盒,以为里面装着一件古董打开一看,惊呆了。。。正好美国最近大动乱,啥都不缺,就缺这件防弹背心,顺便还可以防寒保暖。以后深夜撸代码,就可以穿着这件背心了。哇咔咔。。。谢谢融云的惊喜

昨天收到一个高大上的礼盒,以为里面装着一件古董

打开一看,惊呆了。。。


2.jpg


正好美国最近大动乱,啥都不缺,就缺这件防弹背心,顺便还可以防寒保暖。

3.jpg

以后深夜撸代码,就可以穿着这件背心了。哇咔咔。。。谢谢融云的惊喜

友情链接