Geek Online 2020 编程挑战赛

Geek Online 2020 编程挑战赛

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

GeekOnline编程挑战赛梅川酷子 发表了文章 • 0 个评论 • 430 次浏览 • 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 编程挑战赛完美收官!

GeekOnline编程挑战赛梅川酷子 发表了文章 • 1 个评论 • 451 次浏览 • 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       


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

GeekOnline编程挑战赛梅川酷子 发表了文章 • 0 个评论 • 456 次浏览 • 2020-10-28 17:40 • 来自相关话题

Geek Online 2020 编程挑战赛圆满落幕,一张图回顾 Geek Online 2020 编程挑战赛精彩瞬间!

Geek Online 2020 编程挑战赛圆满落幕,

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

微信图片_20201202164614.png微信图片_20201028173842.png

微信图片_20201202164655.png

微信图片_20201202164718.png

微信图片_20201202164744.png

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

GeekOnline编程挑战赛梅川酷子 发表了文章 • 0 个评论 • 469 次浏览 • 2020-10-27 10:12 • 来自相关话题

Geek Online 2020 编程挑战赛是融云 面向全球 IM 和 RTC 开发者、编程爱好者与极客举办的一场在线黑客马拉松。融云作为全球领先的互联网通信云厂商,一直致力于 IM 和 RTC 技术的创新和发展,希望与全球开发者一道,共同... ...查看全部

Geek Online 2020 编程挑战赛是融云 面向全球 IM 和 RTC 开发者、编程爱好者与极客举办的一场在线黑客马拉松。融云作为全球领先的互联网通信云厂商,一直致力于 IM 和 RTC 技术的创新和发展,希望与全球开发者一道,共同寻找 IM 和 RTC 技术的更多落地场景,开辟更多使用途径。

本届 Geek Online 2020 编程挑战赛以《后疫情时代,通信云技术的创新及实践》为主题,也是希望借此机会鼓励开发者挖掘关于实时音视频和即时通讯技术的更多创意。通过近 2 个月的激烈角逐,在近百份参赛作品中,15 支队伍突出重围,闯入总决赛。

其中,缘拼、红鲤鱼与绿鲤鱼与驴、youwe young、萍水相逢的生活、MAXFLOAT 五组参赛团队分获了最终的奖项。

在比赛中,他们不仅夺得奖杯、获得声誉,也赢得了丰厚的奖金;而在比赛后,我们也采访了其中的三组选手,和他们聊了聊参赛前和赛后的一些“独家记忆”。



      lPc6q1vIgtC3pM40__thumbnail.png

“作为大学在读生,我能深刻体会到目前很多大学生的社交问题 —— 不愿甚至排斥参与社交,难以与陌生人沟通。正是为了改善乃至解决这个问题,我们设计出了缘拼。”

冠军团队:缘拼

选手:康帅 杨桢 张晨博

1、请介绍一下自己/团队

我们是来自内蒙古师范大学计算机科学技术学院蚂蚁工坊的大三在校生,团队中有两名前端开发工程师和一名后端开发工程师,擅长 uniapp 以及微信小程序开发,有多个企业合作项目开发经验。我们都热爱编程,热爱生活,有创意并愿意将其付诸于实际。

2、能谈一谈你在比赛中的项目设计思路,以及比赛中的一些趣事么?

作为大学在读生,我能深刻体会到目前很多大学生的社交问题 —— 不愿甚至排斥参与社交,难以与陌生人沟通。正是为了改善乃至解决这个问题,我们设计出了缘拼。而在比赛的设计过程中,我们一开始决定的项目名称是约拼,但是经过几回队内讨论后,认为陌生人社交,更多靠的是缘分,而不是按部就班,所以改名为缘拼。

3、如果有更充分的时间与资源,你还想要借助 RTC 技术来实现哪些场景应用?

受当前疫情影响,人们的活动范围很是受限,但受限并不意味着无趣 —— 基于 RTC 技术,我们有了一个设想:用户可以发帖自由提问,而帖子增加的同时会创建一个直播连麦群聊,用户可以在其中畅所欲言,足不出户却一见如故,共同探讨问题的解决方法。

4、对于你们来讲,参加编程挑战赛的经历给你带来了什么?参赛的意义是什么?

对于我们来说,这次参加编程挑战赛意义重大,参加编程挑战赛不仅给我带来了莫大的鼓舞,也让我自己对编程更加热爱,同时也意识到自身有许多可以进步的空间。而且这次获得冠军也是对我自身两年编程学习的一次肯定与激励,让我有更大的动力去向编程水平的顶峰发起冲刺。

5、对没有参加过类似比赛、一直持观望态度的朋友,你有什么建议吗?

勇敢参加,迈出第一步才知道路顺不顺,有了竞争才能有进步。

6、提供一张照片或者能代表你们团队的图片吧

 

       LKAlADNHRPLUiivP__thumbnail.png      

 

三个男人,三台电脑,三个月,一个奇迹(缘拼)。




GLSHGa6TWXQxGklG__thumbnail.jpg       

“我想各架一个摄像头在东京、威尼斯和九寨沟,然后在我的房间投影成门窗,这样我就拥有了一座「伪·哈尔的移动城堡」。”

亚军 & 突出贡献奖团队:红鲤鱼与绿鲤鱼与驴

选手:顾俊 陆禹淳

1、先介绍一下你的团队与本次大赛的作品吧

「红鲤鱼与绿鲤鱼与驴」是一个固定的团队,由三个人构成:熟悉前端、WebRTC方向的红鲤鱼(也就是我本人),熟悉后端、大数据方向的绿鲤鱼,以及熟悉视觉、法务方面的驴(希望不会用到法务方面)。这次比赛是由红鲤鱼与绿鲤鱼两名成员参与的,但仍沿用了团队名。

本次大赛的参赛作品「点解」,是一个面向程序员的解谜游戏。该谜题层次丰富如洋葱,第一层需要用户集成融云SDK、掌握融云的基本概念。第二层需要用户做一定程度的视频后处理。第三层需要用户做一些图像识别。整个过程需要像打游戏一样走出新手村、打怪练级、挑战大BOSS,最终拿到宝藏。

2、能谈一谈你在比赛中的项目设计思路,以及比赛中的一些趣事么

「点解」的核心是一个不断翻转的二维码。它的灵感来源于一个物联网界的著名协议。这个协议在一个加密的 WIFI 信道中,通过发送的包的长度来向并不拥有密码的客户端传递消息。这让我对于信道有了颠覆性的认知 —— 信道可以如此不走寻常路!于是我就构思了这个利用 RTC 信道降级传输元信息的通信方式。它不够精巧,但足够特别。

3、如果有更充分的时间与资源,你还想要借助 RTC 技术来实现哪些场景应用?

我想各架一个摄像头在东京、威尼斯和九寨沟,然后在我的房间投影成门窗,这样我就拥有了一座「伪·哈尔的移动城堡」。

4、对于你个人来讲,参加编程挑战赛的经历给你带来了什么?参赛的意义是什么?

因为工作的原因,我平时会接触各种各样的、不同场景的实时音视频应用。看多了之后就有点审美疲劳。对我而言,很多音视频项目的「创新」,多多少少能够见到已有应用的影子。从另一方面来说,我作为一个 WebRTC 工程师,如果仍然拘泥于我见过的场景,或者说创新力度不够大的话,那么参加挑战赛又跟上班有什么分别呢?

所以其实像 GeekOnline 这样的比赛给了这样的项目一些机会,这些项目也许不是什么赚大钱的项目,但是它们足够有趣。而唯有在这样的场景下,这样的项目才有机会被买单,这样的项目才有机会被人看见。

那么为什么不做这样的项目呢?想赚钱去上班就好了啊。

5、对没有参加过类似比赛、一直持观望态度的朋友,你有什么建议吗?

参加啊,大不了搞砸,怕什么。搞砸一次,浑身轻松。

6、提供一张照片或者能代表你们团队的图片吧

 

       vJLVQjzLzAOw5znq__thumbnail.png      

你看这个小人,其实是一半安卓,代表了程序员,它的“帽子”其实是一条吞了大象的蛇,取自《小王子》。



 jQnAbrcslfHJGuJm__thumbnail.jpeg.jpg

“就如队名一样,我们的爱心无限大,我们的潜力无限大,我们的梦想无限大,我们的能力也无限大。”

商业价值奖团队:MAXFLOAT

选手:张先红 华辰 杨小重 焉红霞

1. 请结合几个关键词介绍一下自己/团队

MAXFLOAT是一支有实力,有梦想,有创意,敢拼搏,即想即做的队伍。团队成员经验丰富,思维灵敏,活泼可爱,富有爱心。就如队名一样,我们的爱心无限大,我们的潜力无限大,我们的梦想无限大,我们的能力也无限大。

2. 能谈一谈你在比赛中的项目设计思路,以及比赛中的一些趣事么?

“宠宝儿”是一款为宠物服务的软件,面向的都是比较有爱心的群体,因此在整体风格上,定义为暖色调。而内容素材上,偏卡通化,使其具有治愈系能力。在功能架构上,我们尽量做到简约,不让用户在杂余的地方浪费时间。

分享个比较有趣的事。在开发过程遇到了一个问题,融云的同事帮忙找了两天,最后发现是两个方法太像了,作用差不多,调错了,那时心中顿时是万马奔腾啊,但是也比较感谢他们,他们的认真和负责,深深的打动了我。我觉得其它的比赛很难做到这点。

3. 如果有更充分的时间与资源,你还想要借助 RTC 技术来实现哪些场景应用?

1)屏幕共享

对于直播,单纯的视频直播,只能看到摄像头前的东西,而考虑到医生在进行直播的时候,有时普及一些东西,需展示一些素材。如果接入商城,用户可能在直播推荐自己的一些产品,这个时候需要做产品展示,因此屏幕共享是必须的。但这个屏幕共享不是单纯的手机屏幕共享,而应该将多个硬件的屏幕结合,用户自己选择展示。

2)内部会议

后期如果接入宠物医院,这样就相当于面向企业了,因此会考虑为他们提供一些服务。

4. 对于你们来讲,参加编程挑战赛的经历给你带来了什么?参赛的意义是什么?

当我看到咱们融云举办的活动时候,报名时间已经过去差不多半个月,当时担心时间不够用,但是到最后,我还提前一个多星期提交了作品。所以我觉得,想做什么,那就动手去做吧,不要管其它的,做了再说,决定了之后,我们开始确立参赛的项目,是构思已经的宠物项目,而这一次,它有机会展现给更多的人。然后我们对功能的删减,确定要做哪些,大概需要多长时间,通过合理的规划,自己的努力和坚持,我们提前一个多星期完成了作品。而且之前,我们没有想过做直播方面的功能,而这次融云给了我们一个很好的思路。

5. 对没有参加过类似比赛、一直持观望态度的朋友,你有什么建议吗?

之前我们没有参加过任何比赛,这次也是偶尔看到的,正好大家都比较感兴趣,就报名参加了。

对于那些观望的,其实也没什么好的建议,如果平时比较忙的话,那确实是没有精力在放到其它事情上了,但如果有兴趣,有精力,那么我建议,还是要多做多想,这样能更好的提升自己,如果瞻前顾后,那将一事无成。

6. 提供一张照片或者能代表你们团队的图片吧

 VtotPQXvY38Pzp7w__thumbnail.jpeg.jpg

星空代表着梦想,而我们有自己的梦想,我们想做那颗最亮的星。


这次比赛中取得的成绩,对于这些参赛选手来说都只是个开始,但正如他们所说,Geek Online 2020 编程挑战赛的这一经历,一定会是他们人生中的一次宝贵经验。

Geek Online 2020 编程挑战赛虽然是第一次举办,但已经收获了参赛选手以及观看决赛路演直播观众们的一致好评,融云作为专注于通信的 PaaS 云服务平台,想要通过底层的基础模块支持,帮助企业与开发者构建「云通信」的能力。

举办此次编程挑战赛的目的,也是希望让开发者们碰撞出技术的思维火花,加速潮流技术的应用创新,也为开发者们搭建了一个沟通、交流、合作的平台,希望能够掀起一股通信技术应用的探索与实践热潮。

也希望全球 IM 和 RTC 开发者、编程爱好者与极客

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

IM即时通讯放肆小青年 回复了问题 • 28 人关注 • 27 个回复 • 919 次浏览 • 2020-10-26 09:33 • 来自相关话题

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

GeekOnline编程挑战赛梅川酷子 发表了文章 • 0 个评论 • 515 次浏览 • 2020-09-21 14:27 • 来自相关话题

近日,首届 Geek Online 2020 编程挑战赛正式启动,作为挑战赛主办方的融云,希望借此机会与开发者一起,共同挖掘 RTC 和 IM 技术的创新应用场景,发现更多通信云领域的落地实践。据了解,此次编程挑战赛采用线上形式,开发者通过使用融云 ... ...查看全部

近日,首届 Geek Online 2020 编程挑战赛正式启动,作为挑战赛主办方的融云,希望借此机会与开发者一起,共同挖掘 RTC 和 IM 技术的创新应用场景,发现更多通信云领域的落地实践。据了解,此次编程挑战赛采用线上形式,开发者通过使用融云 IM+RTC SDK 进行创新应用开发,参赛作品通过 GitHub 提交,秉承开源、公平、公正的原则,从作品完整度、创新性以及商业价值三方面进行评选,致敬开发者精神。

c1b9f25c8aea944c7856a7110dfc54a.jpg

01 疫情推动音视频技术的应用场景发展

过去,音视频技术应用最广的两个场景集中在娱乐视频直播以及视频会议。在今年疫情的推动下,催生出更多的音视频应用场景,尤其以在线教育以及远程办公两大领域的使用最为广泛。

借助音视频技术,用户体验的方式从线下转移到线上,省去了路程奔波的时间,减少线下的空间成本,同时利用相关技术可以在线上获取到更好的互动体验,带来了远程体验的普及,让线上交流由被动变为主动。

后疫情时代,远程在线的沟通方式逐渐受到大家的认可,除了在线教育和远程办公外,其它线下场景也逐步线上化,例如用户可以远程开通银行卡,法庭可以在线上进行审判等等,通过各种远程无接触的服务,大家享受着音视频技术带来的便捷性。

因此,疫情不仅推动音视频技术的应用场景发展,相对应,音视频技术也逐渐成为了各行业、各产品作为支撑业务形态所必备的基础能力。

02 Geek Online 编程挑战赛上线开拓更多业务场景

为了挖掘更多更优秀的产品应用场景,融云发起了 Geek Online 2020 编程挑战赛,以“后疫情时代,通信云技术的创新及实践”为主题,鼓励开发者挖掘更多即时通讯和音视频技术的应用场景。挑战赛已于 8 月 24 日开始报名,赛程近 2 个月,10 月 17 日进行线上决赛,并计划于 10 月 31 日在 WICC 2020 互联网通信云大会现场颁奖

在谈到举办编程挑战赛的初衷时,融云 CTO 杨攀告诉笔者,融云服务的对象就是开发者群体,融云的使命是与开发者共成长。过去,融云与开发者建立了多种沟通渠道,包括线上的工单、电话、技术群、文档,以及线下的技术沙龙和 WICC 峰会。而编程挑战赛是想让开发者之间进行更好地交流互动,让开发者站在舞台中央,表达他们创新的想法和点子,也是融云与开发者互动模式的迭代。

微信图片_20200921142307.png

据了解,此次挑战赛的参赛作品须集成融云官网最新版本的即时通讯 SDK 或实时音视频(直播)SDK,应用可以实现一个具体场景或解决一个具体问题,并提交作品的全部源码、编译好的真机安装包,以及必要的说明文档(README.md),源码部分均以 MIT 开源协议对外开放。

本次挑战赛的作品评选会根据作品完成度(60%)、潜在商业价值(20%)、创意度(20%)等三个维度由专家进行点评打分。在杨攀看来,优秀的作品应该更加具有创意和想法。在作品具有一定完整度的前提下,是否具有创意的场景,同时也富有商业价值,是整个作品的加分项。“我认为大家并不需要追求项目的代码量,不在于规模,而在于开发者做的事情要有创意、有想法,可以直击人心,这样更容易获得更多评委的加分。”

03 致敬开发者精神 为开发者提供专业服务

值得注意的是,此次 Geek Online 2020 编程挑战赛有两个方面区别于其他开发者大赛,即作品提交渠道以及比赛服务模式。

首先,参赛作品并不是在融云官网提交,而是要求在 GitHub 上提交。杨攀解释道,众所周知,GitHub 是全球最大的开源社区,编程挑战赛的作品在 GitHub 提交是想要向开发者精神致敬,要求所有作品开源,以便能接受所有开发者的检验,让整个赛事更加公平公正。

此外,过去很多开发者大赛都是自助模式,即由比赛组委会公布完赛题、时间、赛程安排、作品要求、奖项等大赛内容之后,开发者便可以按照官方提供的文档,自行研究工具的使用,完成后在线提交作品。而融云的做法却截然不同,融云会给所有的开发团队提供专门的支持。杨攀表示,一是让服务团队及研发团队可以为参赛队伍提供一对一的支持服务,以便他们能够在有限的时间内完成更好的作品;另一方面,也是想借此机会,让研发团队与开发者进行更深入地交流,聆听并收集开发者的想法和反馈,以助于融云的产品迭代演进。

在挑战赛奖励方面,除了奖金和奖杯以外,融云还会引入投资机构,如果开发团队的作品在完整度、商业价值等方面均受到了认可,融云会作为桥梁,将其对接给投资机构。此外,如果团队选手愿意以个人身份加入融云,也会开放融云招聘的绿色通道。优胜者还会受邀到 WICC 2020 全球互联网通信云大会现场参加颁奖典礼,与受邀参会的众多专家面对面学习交流

微信图片_20200921142258.png

▲ 扫码免费报名

04 赋能开发者 以硬实力赢取信赖

在即时通讯以及音视频领域,不乏很多有竞争实力的企业,大到云计算服务提供商,小到初创企业,在通信云赛道上,可谓“百家争鸣”。而融云又有哪些核心竞争力,可以在行业内脱颖而出,赢得众多开发者的信赖呢?

据杨攀介绍,即时通讯技术相对比较封闭和私有,业界开源的通信协议只有 XMPP。由于该协议是在 1999 年开源,在协议设计之处并未预知到未来移动互联网时代的网络复杂情况,因此这一开源协议在如今使用会存在很多问题,例如通信质量,系统支持人数限制等等。融云的核心研发团队来自于飞信,具有丰富的通信技术经验,自主设计了通讯协议,保证了平台通讯的基础质量。如今,融云的日活跃用户数量达到 7000 多万,在国内仅次于微信、QQ 等巨头产品,足见其技术实力。

在音视频领域,谷歌于 2010 年收购 VoIP 软件开发商 Global IP Solutions 而获得 WebRTC 技术,并于 2011 年开源该项目,但是谷歌只开源了部分功能,即端到端的通信,支持两个人之间的传输音视频流,无法支持多人沟通场景,此外,在更加复杂的网络环境中,经常会遇到丢包、带宽不够等情况,因此,服务提供商就需要在遵守公共开源的协议下进行调优。于是,融云在音视频的用户规模、网络质量、通信链路以及接口等方面进行了开发和优化,保证了音视频的质量以及技术的易用性。

虽然业界有标准的协议以及开源的框架,但是,对于音视频和即时通讯领域的自研开发还是有门槛的。杨攀表示,首先是成本问题,包括团队成员的组建和投入,需要组织大量人力来完成;其次是时间的投入,在如今互联网竞争激烈的时代,时间不等人,需要快速开发出稳定可用的产品或功能;第三,规模问题,当用户量激增或业务扩张时,系统不稳定有可能导致功能不可用,从而流失用户。融云基于多年的积累,满足市面上绝大部分的客户需求,并将开发者需要的功能和能力封装成接口,甚至提供了标准化的 UI 界面,帮助开发者快速完成自己的产品功能研发。

通信云技术发展多年,未来会有哪些发展趋势呢?杨攀表示,通信云的发展过程是相对循序渐进的。随着 5G 的到来,互联网通信基础设施质量也逐步提升,更多的变化则是场景的创新应用,功能丰富度,以及产品接口的易用性。未来,融云也会重点以平台为依托,在场景应用、产品功能、基础设施和接口等方面,全方位提升能力,赋能开发者。

懂程序员的产品经理是什么样子?

IM即时通讯王叫兽 发表了文章 • 0 个评论 • 124 次浏览 • 2020-09-16 10:36 • 来自相关话题

在互联网行业,产品经理和程序员之间的关系很微妙。表面看上去水火不容,在一方的眼里看另外一方总是有这样那样的问题,相互吐槽。但现实是,大家都知道和对方在同一条船上。产品没做好的话,除了公司利益受损,产品经理和程序员也会各回各家各找各妈,重新找新工作去。产品做得好... ...查看全部

在互联网行业,产品经理和程序员之间的关系很微妙。表面看上去水火不容,在一方的眼里看另外一方总是有这样那样的问题,相互吐槽。但现实是,大家都知道和对方在同一条船上。

产品没做好的话,除了公司利益受损,产品经理和程序员也会各回各家各找各妈,重新找新工作去。

产品做得好的话,双方和睦相处、其乐融融?那是不可能的,这个辈子都不可能和睦相处。矛盾会更加严重……(都觉得自己功不可没)

所以Z哥就想来聊聊产品经理和程序员之间的协作问题。不管你是产品经理还是程序员,都应该找到与对方打交道的好方法。好的方法必然是寻求双赢的,而不是一个零和博弈。

这个主题会分别从不同的两个视角展开,今天我们先聊程序员视角,本来想两个视角一起聊,发现内容太多,写到一半还是拆了,先把一个视角写了。

如果你是程序员可以看看以下这些描述是你眼中的产品经理么?

如果你是产品经理可以看看从程序员起家的Z哥给出的一些建议。

程序员吐槽产品经理最多的原因主要是以下几个(以下内容可能会引起程序员们的极度舒适~):

  1. 开发过程中频繁修改需求。

  2. 验收过程中要求做比较大的修改。

  3. 说不清楚需求的价值

  4. 替程序员评估工作量

  5. 需求整理的不够细。

其中,频繁修改需求是程序员们最反感的,这是毋庸置疑的。

从产品经理的角度来说,虽然无法100%在开发过程中不修改需求,但是如果前期的工作做得足够充分,与业务方的沟通足够到位,至少去掉“频繁”两个字还是很有可能的。我甚至遇到过一些产品经理,在自己对业务都是一知半解的时候就开始整需求了,这必然会导致后续频繁的需求变更。

第二,验收过程中要求做比较大的修改。此时往往会伴随一句短语——“这不是我要的”。每当程序员听到这6个字的时候,脑子里是一万头草泥马奔过……

产生这个情况的原因有很多。可能是程序员理解偏差,也有可能是产品觉得功能效果不佳。但是大多数时候,产生这个情况的根本原因还是在需求评审阶段的沟通不够充分,双方之间并没有达成真正的共识。

但是如果要说什么时候双方的矛盾最激烈,那还不是修改需求的时候,而是需求评审的时候。

此时,很容易看到的一个景象是“讨价还价”。产品经理站在「价值」一方,程序员站在「成本」一方。当程序员们追问某个他们不认同的功能时,如果产品经理无法阐述出该功能令人信服的价值,那么必然受到吐槽。这是原因三。

原因四,有些产品经理是从程序员转过去的,之前做过一两年的开发工作。这个时长的经验其实是很危险的,很容易陷入到「达克效应」的第一阶段:高估自己的技术能力,低估他人的技术能力和工作难度。这会导致不管是明面上还是私底下会不自然地去评估程序员的工期是否合理,甚至会在需求评审的时候替程序员预估时间,如果高于自己的预估,便会认为他们偷懒。

最后一点。相信每个人程序员都提出过这样的问题“这里如果……,那么要怎么处理?”。这种就是需求考虑不够细致的体现。不过,要做好这点的确挺难的,这也是产品经理花费时间最多的地方。

聊了这么多场景,作为产品经理应该如何应对呢?

从思路上分为以下几步。

01

先明确大方向,并与程序员达成一致。

正如前面所提到的,产品经理站在「价值」方,程序员站在「成本」方,这注定了他们是对立的。最坏的结果就是双方互掐,就算相对好的结果也只是相互妥协做一个半吊子的功能(用系统的人不太舒服)。

但如果你的视野更大,格局更高,就会发现,如果以「投入产出比」角度来切入,双方不但都能理解,而且很容达成共识,毕竟花最小的成本干价值最大的活,是个正常人都能理解和认可不是么。

所以,可以在日常工作中不断的强化这个共识。一旦出现争执,就从这个角度来做最终决定,甚至基于这慢慢地还能建立起相互的信任,程序员真正拥有了产品思维,产品经理真正懂了程序员的难处。

02

将产品经理范畴内的事情做到极致。

所谓术业有专攻,与其相互吐槽,不如多花点时间把对方吐槽的地方做到极致。

03

有时候你虽然做的很好,想的也很仔细,但是还是会出现无法说服程序员认可你方案的情况。这是因为我们每个人本身都会存在「确认偏误」现象。

确认偏误是指搜寻,解释,偏爱和回想确认或支持一个人先前信念或价值观的信息的倾向。会导致对个人信念的过度自信,并且在面对相反的证据时可以保持或加强信念。

维基百科

所以,运用一些沟通技巧显得至关重要。只要一件事不是单凭一个人就能完成,你就得考虑如何提高协作效率。而产品经理和程序员的协作中,沟通又是最重要的。

下面展开说说具体可以做的一些事。主要是思路中的2和3。

01 提高专业性

我观察过一个现象,需求变更比较多的产品经理,他们的工作习惯往往是直接抄起原型工具就画原型,或者有很多工作时间在原型工具里。

这样非常容易陷入到一个思维惯性里面去,就是过于关注交互层面的事情,而轻视了背后业务流程的设计,甚至是业务的合理性。

我认为产品经理做事的时候一定要以User Story为核心来展开,先构思好一个User Story,然后就是把它真实发生的各种细节阐述清楚。做这事的过程先后分为以下四步:

  1. 定义User Story

  2. 定义交付标准

  3. 提供低保真原型

  4. 编写Use Case

这里面最费时费力的就是第四环节。并且,你想把User Story阐述清楚离不开一个专业的 Use Case编写。我之前收藏了一个非常专业的Use Case模版,是从知乎上的张恂老师那看到的,你感受一下。

用例名称:提问 
层次:!(用户目标层) 
范围:问答网站(以下简称系统) 
主用角:注册用户(以下简称用户) 
其他干系者:...
后态: 
前态:用户已登录。 
触发事件:用户选择提问。 
基本流:1. 系统显示新建问题框。 
输入问题 { 
2. 用户输入问题陈述(字数限制?);系统即时验证输入的有效性,并提示已有答案的类似问题(数量?)以免重复提问。 
3. 用户设定该问题的相关话题。 
4. 可选项 
用户可补充输入问题说明(背景、条件等详细信息)。 
5. 可选项 
…… 
6. 用户提交问题。 

7. 系统验证该问题的有效性。 
8. 系统发布该问题,并显示该问题页面。 
 扩展流:用户放弃提问:...
https://www.zhihu.com/question/48899115/answer/113274323 张恂老师的回答。

作为产品经理的你,如果想要减少被程序员吐槽需求不够细,或者降低开发过程中变更需求的频次,把use case用心做好是必不可少的。

02 沟通方面

与程序员的沟通方面,我总结了五动作,分别是「齐、拉、捧、说、谦」,可以根据情况组合出击。

「齐」就是视角对齐的意思。在聊需求之前,先交代需求的背景、意义。特别在中途需求变更的时候,这点非常重要。

继续搬出之前用过好几次的图。

640.jpg

如果视角不同,你说接下去还怎么聊?

「拉」是拉拢的意思。亚里士多德说过:

我们无法通过智力去影响别人,而情感却能做到这一点。

亚里士多德

所以,在沟通的时候要把程序员当作自己人看待,而不是敌对。比如,可以多用“我们”,“一起”等词语,进入一个协商的氛围。举个例子:“我们一起来看下这个问题”。少用”我觉得“、”我认为“;

「捧」是吹捧的意思,但并不是简单的拍马屁。

人都是有多面性的,针对不同的情况和场景,可能会表现出不同的特质,这会影响到双方的沟通。比如有的人在生活中很温和,但在工作时非常严苛,要求很高,这就是激发了不同的特质。

类似的,为了激活程序员的积极性,你可以在当下需要他发挥的地方吹捧一下。比如,你觉得某个程序员做的东西质量一般,小问题比较多。那么你在和他聊的时候特地捧一句,“我知道做程序员的都或多或少有完美主义倾向,对细节很关注。我这个功能设计的细节可是想了好久呢,不过对你来说应该很容易搞定吧。”

「说」是说服的意思。想要让对方从心底里的认同你,单凭打感情牌可不行。所以需要多用数据和用户反馈来提高你观点的可信度。

重视数据的产品经理有可能是优秀的产品经理,但不重视数据的产品经理一定不是优秀的产品经理。因为要看得懂数据的前提是得懂业务,并且还不能仅仅懂个皮毛。比如,

你得知道哪些环节产生的数据是关键。

多个数据之间的间接关系和影响是什么。

你设计的每一个功能会如何影响这些数据。

……

心里一直有着这些概念,程序员还会吐槽你提的需求价值低?

「让」是谦让的意思。俗话说,“三个臭皮匠顶一个诸葛亮”。可以给程序员留有表达他们观点的空间。

原因有两点。

大多数的产品设计背后有很多的知识是通用知识,每个人的生活经历都能成为经验。而每个人的生活经历又是不同的。

专业不同,哪怕站的视角相同,看到的同一个事物也会有些差别。用高端的说法叫“看到的本质不同”。基于这个本质出发,提出的观点可能会让你眼前一亮。

以上就是「齐、拉、捧、说、谦」五点。最后再送给你一句话:非必要情况,一定不要用“这是老板的要求“!,重复,重复。重要的事情说三遍。

还有一些比较成熟的方法体系也能改善产品和开发之间共识达成问题。比如,在领域驱动设计范畴中Event Storming。它就非常适合在前期的需求评审环节去使用。

感兴趣的可以自行了解。

好了,总结一下。

这篇呢,Z哥和你分享了我对产品经理如何更好地与程序员达成共识这件事的看法。

思路上分为三步:

  1. 先明确大方向,并与程序员达成一致。

  2. 将产品经理范畴内的事情做到极致

  3. 运用一些沟通技巧解决「确认偏误」现象。

关于第二点,给出的具体措施是。以User Story为核心,做好Use Case的编写工作,而不是花很多时间在原型上。

关于第三点,总结了五个动作,分别是「齐、拉、捧、说、谦」,可以根据情况组合出击。

希望对你有所帮助。

作者:Z哥,公众号“跨界架构师” 

为什么有 HTTPS?因为 HTTP 不安全!

IM即时通讯王叫兽 发表了文章 • 0 个评论 • 107 次浏览 • 2020-09-15 17:24 • 来自相关话题

为什么有 HTTPS?因为 HTTP 不安全! 现在的互联网已经不再是 " 田园时代 "," 黑暗森林 " 已经到来。上网的记录会被轻易截获,网站是否真实也无法验证,黑客可以伪装成银行网站,盗取真实姓名、密码、银行卡等敏... ...查看全部

u=1241929776,2696424852&fm=26&gp=0.jpg

为什么有 HTTPS?因为 HTTP 不安全! 现在的互联网已经不再是 " 田园时代 "," 黑暗森林 " 已经到来。上网的记录会被轻易截获,网站是否真实也无法验证,黑客可以伪装成银行网站,盗取真实姓名、密码、银行卡等敏感信息,威胁人身安全和财产安全。

上网的时候必须步步为营、处处小心,否则就会被不知道埋伏在哪里的黑客所 " 猎杀 "。

HTTPS 如何实现安全通信?如何构建出固若金汤的网络城堡?主要涉及的知识点如下:

了解什么是 HTTPS

什么样的才是安全的通信

对称加密与非对称加密、摘要算法、数字签名、完整性校验到底是什么

迁移 HTTPS 的必要性

什么是安全

做事要稳,老司机【码哥字节】开车要安全!不管是戴杜蕾斯还是安全气囊," 安全至关重要 "!

在通信过程中,具备以下特性则认为安全:机密性、完整性、不可否认、身份认证。

机密性

数据必须保密,只能有信任的人读取,其他人是不可见的秘密。诸葛亮的密报总不能让司马懿知道呀,不然还玩个蛋。通俗的说:就是不能让不相关的人看到不该看的东西。

完整性

也叫作一致性,也就是数据在传输过程中没有被非法篡改,内容不能多也不能少,一五一十的保持原状。

打个比方,原本张无忌说:" 赵敏,么么哒。",传信的飞鸽被周芷若抓到了,截取了消息,改成了 " 赵敏,去死吧!"。这么子搞,倚天屠龙记可能就会被改写了。

不可否认

也就做不可抵赖,不能否认已经发生过的事情。所谓 " 君子一言,驷马难追 "。" 老懒 " 这种事情不能发生。

就像尹志平亲密接触了小龙女,事后一直隐瞒否认,装作不知道,这是万万不可的。所以最终就嗝屁了。

身份验证

也就是确认对方的真实身份," 证明你是真的是你 ",保证消息发送到可信的人,而不是非法之徒。

比如令狐冲写了一份情书给任盈盈:" 盈盈,冲哥哥爱你哟 ",但是岳不群看到快递小哥,冒充是令狐冲,截取了情书后回复:" 傻逼,白日做梦 "。令狐冲不知道这是岳不群的回复,以为是任盈盈的,笑傲江湖又要重写了……

所以同时具备了机密性、完整性、身份认证、不可够人四个特性,通信双方的安全才有保证,才是真正的安全。

什么是 HTTPS

到这里,终于轮到 HTTPS 上台了,也就是它为 HTTP 增加了刚刚说的四大安全特性。

HTTPS 其实是一个 " 非常简单 " 的协议,规定了新的协议名 "https",默认端口号 443,至于其他的什么请求 - 应答模式、报文结构、请求方法、URI、头字段、连接管理等等都完全沿用 HTTP,没有任何新的东西。唯一的差别就是端口号不同、去掉明文传输。

那 HTTPS 凭啥就变得安全了呢?

就是因为他在 TCP/IP 与 HTTP 之间加上了 SSL/TLS ,从原来的 HTTP over TCP/IP 变成了 HTTP over SSL/TLS,让 HTTP 运行在 安全的 SSL/TLS 协议上,安全开车。

http 与 https

所以重点就是去掌握 SSL/TLS 到底是什么玩意成就了安全。

SSL/TLS

SSL 即安全套接层(Secure Sockets Layer),在 OSI 模型中处于第 5 层(会话层),由网景公司于 1994 年发明,有 v2 和 v3 两个版本,而 v1 因为有严重的缺陷从未公开过。

SSL 发展到 v3 时已经证明了它自身是一个非常好的安全通信协议,于是互联网工程组 IETF 在 1999 年把它改名为 TLS(传输层安全,Transport Layer Security),正式标准化,版本号从 1.0 重新算起,所以 TLS1.0 实际上就是 SSLv3.1。

TLS 由记录协议、握手协议、警告协议、变更密码规范协议、扩展协议等几个子协议组成,综合使用了对称加密、非对称加密、身份认证等许多密码学前沿技术。

浏览器与服务器在使用 TLS 建立连接的时候实际上就是选了一组加密算法实现安全通信,这些算法组合叫做 " 密码套件(cipher suite)"。

套件命名很有规律,比如 "ECDHE-RSA-AES256-GCM-SHA384"。按照 密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法 " 组成的 .

所以这个套件的意思就是:使用 ECDHE 算法进行密钥交换,使用 RSA 签名和身份验证,握手后使用 AES 对称加密,密钥长度 256 位,分组模式 GCM,消息认证和随机数生成使用摘要算法 SHA384。

对称加密与非对称加密

前面提到四个实现安全的必要条件,先说 机密性,也就是消息只能给想给的人看到并且看得懂。

实现机密性的手段就是 加密(encrypt),也就是将原本明文消息使用加密算法转换成别人看不懂的密文,只有掌握特有的 密钥 的人才能解密出原始内容。就好像是诸葛亮将发给关二爷密报的内容通过一种转换算法转成其他的内容,司马懿看不懂。关二爷持有解密该内容的关键钥匙。

钥匙也就是 密钥(key),未加密的消息叫做 明文 (plain text/clear text),加密后的内容叫做 密文(cipher text),通过密钥解密出原文的过程叫做 解密(decrypt),而加解密的整个过程就是 加密算法。

由于 HTTPS、TLS 都运行在计算机上,所以 " 密钥 " 就是一长串的数字,但约定俗成的度量单位是 " 位 "(bit),而不是 " 字节 "(byte)。比如,说密钥长度是 128,就是 16 字节的二进制串,密钥长度 1024,就是 128 字节的二进制串。

加密算法通常有两大类:对称加密和非对称加密。

对称加密

加密和解密使用的密钥都是同一个,是 " 对称的 "。双方只要保证不会有泄露其他人知道这个密钥,通信就具有机密性。


对称加密算法常见的有 RC4、DES、3DES、AES、ChaCha20 等,但前三种算法都被认为是不安全的,通常都禁止使用,目前常用的只有 AES 和 ChaCha20。


AES 的意思是 " 高级加密标准 "(Advanced Encryption Standard),密钥长度可以是 128、192 或 256。它是 DES 算法的替代者,安全强度很高,性能也很好,而且有的硬件还会做特殊优化,所以非常流行,是应用最广泛的对称加密算法。

加密分组模式

对称算法还有一个 " 分组模式 " 的概念,目的是通过算法用固定长度的密钥加密任意长度的明文。

最新的分组模式被称为 AEAD(Authenticated Encryption with Associated Data),在加密的同时增加了认证的功能,常用的是 GCM、CCM 和 Poly1305。

非对称加密

有对称加密,为何还搞出一个非对称加密呢?

对称加密确实解决了机密性,只有相关的人才能读取出信息。但是最大的问题是:如何安全的把密钥传递对方,专业术语 " 密钥交换 "。

这个很容易理解,对称加密的密钥在飞鸽传书过程中被打鸟的敌军捕获窃取,那

么就能随意加解密收发作战密报数据了,诸葛亮的密报没有机密可言。

所以非对称加密诞生了。

由两个密钥组成,分别是 公钥(public key) 和 " 私钥(private key)",两个密钥是不一样的,这也就是不对称的由来,公钥可以任何人使用,私钥则自己保密。

这里需要注意的是:公钥和私钥都可以用来加密解密,公钥加密的密文只能用私钥解密,反之亦然。

服务端保存私钥,在互联网上分发公钥,当访问服务器网站的时候使用授予的公钥加密明文即可,服务端则使用对应的私钥来解密。敌军没有私钥也就无法破解密文了。


非对称加密


TLS 中常见的加密算法有 DH、RSA、ECC、DSA 等。其中的 RSA 最常用,它的安全性基于 " 整数分解 " 的数学难题,使用两个超大素数的乘积作为生成密钥的材料,想要从公钥推算出私钥是非常困难的。

ECC(Elliptic Curve Cryptography)是非对称加密里的 " 后起之秀 ",它基于 " 椭圆曲线离散对数 " 的数学难题,使用特定的曲线方程和基点生成公钥和私钥,子算法 ECDHE 用于密钥交换,ECDSA 用于数字签名。

比起 RSA,ECC 在安全强度和性能上都有明显的优势。160 位的 ECC 相当于 1024 位的 RSA,而 224 位的 ECC 则相当于 2048 位的 RSA。因为密钥短,所以相应的计算量、消耗的内存和带宽也就少,加密解密的性能就上去了,对于现在的移动互联网非常有吸引力。

现在我们为了机密性从对称加密到非对称加密,而非对称加密还解决了密钥交换不安全的问题。那么是否可以直接使用非对称加密来实现机密性呢?

答案是否定的!

因为非对称加密运算速度比较慢。所以需要两者结合,混合模式实现机密性问题,同时又有很好的性能。

加密流程如下所示:

先创建一个随机数的对称加密密钥,会话密钥(session key);

使用会话密钥加密需要传输的明文消息,因为对称加密性能较好,接着再使用非对称加密的公钥对会话密钥加密,因为会话密钥很短,通常只有 16 字节或 32 字节,所以加密也不会太慢。这里主要就是解决了非对称加密的性能问题,同时实现了会话密钥的机密交换。

另一方接收到密文后使用非对称加密的私钥解密出上一步加密的 会话密钥,接着使用会话密钥解密出加密的消息明文。


混合加密


总结一下就是使用非对称加密算法来加密会话密钥,使用对称加密算法来加密消息明文,接收方则使用非对称加密算法的私钥解密出会话密钥,再利用会话密钥解密消息密文。

这样混合加密就解决了对称加密算法的密钥交换问题,而且安全和性能兼顾,完美地实现了机密性。

后面还有完整性、身份认证、不可否认等特性没有实现,所以现在的通信还不是绝对安全。

摘要算法与完整性

摘要算法的主要目的就是实现完整性,通过常见的散列函数、哈希函数实现。

我们可以简单理解成这事一种特殊的压缩算法,将任意长度的明文数据处理成固定长度、又是独一无二的 " 摘要 " 字符串,就是该数据的指纹。

同时摘要算法是单向加密算法,没有密钥,加密后的数据也无法解密,也就是不能从 " 摘要 " 推导出明文。

比如我们听过或者用过的 MD5(Message-Digest 5)、SHA-1(Secure Hash Algorithm 1),它们就是最常用的两个摘要算法,能够生成 16 字节和 20 字节长度的数字摘要。

完整性实现

有了摘要算法生成的数字摘要,那么我们只需要在明文数据附上对应的摘要,就能保证数据的完整性。

但是由于摘要算法不具有机密性,不能明文传输,否则黑客可以修改消息后把摘要也一起改了,网站还是鉴别不出完整性。

所以完整性还是要建立在机密性上,我们结合之前提到的混合加密使用 " 会话密钥 " 加密明文消息 + 摘要,这样的话黑客也就无法得到明文,无法做修改了。这里有个专业术语叫 " 哈希消息认证码(HMAC)"。


哈希消息认证码(HMAC)


比如诸葛亮使用上面提到的混合加密过程给关二爷发消息:" 明天攻城 " + "SHA-

2 摘要 ",关二爷收到后使用密钥将解密出来的会话密钥解密出明文消息,同时对明文消息使用解密出来的摘要算法进行摘要计算,接着比对两份 " 摘要 " 字符串是否一致,如果一致就说明消息完整可信,没有被敌军修改过。

消息被修改是很危险的,要以史为鉴,比如赵高与李斯伪造遗诏,直接把扶苏给送西天了,这太可怕了。

总结下就是通过摘要比对防止篡改,同时利用混合加密实现密文与摘要的安全传输。

数字签名和 CA

到这里已经很安全了,但是还是有漏洞,就是通信的两头。黑客可以伪装成网站来窃取信息。而反过来,他也可以伪装成你,向网站发送支付、转账等消息,网站没有办法确认你的身份,钱可能就这么被偷走了。

现在如何实现身份认证呢?

现实生活中,解决身份认证的手段是签名和印章,只要在纸上写下签名或者盖个章,就能够证明这份文件确实是由本人而不是其他人发出的。

非对称加密依然可以解决此问题,只不过跟之前反过来用,使用私钥再加上摘要算法,就能够实现 " 数字签名 ",同时实现 " 身份认证 " 和 " 不可否认 "。

就是把公钥私钥的用法反过来,之前是公钥加密、私钥解密,现在是私钥加密、公钥解密。但又因为非对称加密效率太低,所以私钥只加密原文的摘要,这样运算量就小的多,而且得到的数字签名也很小,方便保管和传输。

重点就是使用非对称加密的 " 私钥 " 加密原文的摘,对方则使用非对称加密的公钥解密出摘要,再比对解密出的原文通过摘要算法计算摘要与解密出的摘要比对是否一致。这样就能像签署文件一样证明消息确实是你发送的。


签名验签


只要你和网站互相交换公钥,就可以用 " 签名 " 和 " 验签 " 来确认消息的真实性,因为私钥保密,黑客不能伪造签名,就能够保证通信双方的身份。

到这里似乎已经大功告成,可惜还不是。

综合使用对称加密、非对称加密和摘要算法,我们已经实现了安全的四大特性,是不是已经完美了呢?

不是的,这里还有一个 " 公钥的信任 " 问题。因为谁都可以发布公钥,我们还缺少防止黑客伪造公钥的手段,也就是说,怎么来判断这个公钥就是你或者张三丰的公钥呢?

这个 " 第三方 " 就是我们常说的 CA(Certificate Authority,证书认证机构)。它就像网络世界里的公安局、教育部、公证中心,具有极高的可信度,由它来给各个公钥签名,用自身的信誉来保证公钥无法伪造,是可信的。

CA 对公钥的签名认证也是有格式的,不是简单地把公钥绑定在持有者身份上就完事了,还要包含序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证明公钥关联的各种信息,形成 " 数字证书 "(Certificate)。

OpenSSL

它是一个著名的开源密码学程序库和工具包,几乎支持所有公开的加密算法和协议,已经成为了事实上的标准,许多应用软件都会使用它作为底层库来实现 TLS 功能,包括常用的 Web 服务器 Apache、Nginx 等。

由于 OpenSSL 是开源的,所以它还有一些代码分支,比如 Google 的 BoringSSL、OpenBSD 的 LibreSSL,这些分支在 OpenSSL 的基础上删除了一些老旧代码,也增加了一些新特性,虽然背后有 " 大金主 ",但离取代 OpenSSL 还差得很远。

总结下就是:OpenSSL 是著名的开源密码学工具包,是 SSL/TLS 的具体实现。

迁移 HTTPS 必要性

如果你做移动应用开发的话,那么就一定知道,Apple、Android、某信等开发平台在 2017 年就相继发出通知,要求所有的应用必须使用 HTTPS 连接,禁止不安全的 HTTP。

在台式机上,主流的浏览器 Chrome、Firefox 等也早就开始 " 强推 "HTTPS,把 HTTP 站点打上 " 不安全 " 的标签,给用户以 " 心理压力 "。

Google 等搜索巨头还利用自身的 " 话语权 " 优势,降低 HTTP 站点的排名,而给 HTTPS 更大的权重,力图让网民只访问到 HTTPS 网站。

这些手段都逐渐 " 挤压 " 了纯明文 HTTP 的生存空间," 迁移到 HTTPS" 已经不是 " 要不要做 " 的问题,而是 " 要怎么做 " 的问题了。HTTPS 的大潮无法阻挡,如果还是死守着 HTTP,那么无疑会被冲刷到互联网的角落里。

顾虑

阻碍 HTTPS 实施的因素还有一些这样、那样的顾虑,我总结出了三个比较流行的观点:" 慢、贵、难 "。

而 " 慢 " 则是惯性思维,拿以前的数据来评估 HTTPS 的性能,认为 HTTPS 会增加服务器的成本,增加客户端的时延,影响用户体验。

其实现在服务器和客户端的运算能力都已经有了很大的提升,性能方面完全没有担心的必要,而且还可以应用很多的优化解决方案。

所谓 " 贵 ",主要是指证书申请和维护的成本太高,网站难以承担。

这也属于惯性思维,在早几年的确是个问题,向 CA 申请证书的过程不仅麻烦,而且价格昂贵,每年要交几千甚至几万元。

但现在就不一样了,为了推广 HTTPS,很多云服务厂商都提供了一键申请、价格低廉的证书,而且还出现了专门颁发免费证书的 CA,其中最著名的就是 "Let ’ s Encrypt"。

所谓的 " 难 ",是指 HTTPS 涉及的知识点太多、太复杂,有一定的技术门槛,不能很快上手。

总结

从什么是安全我们延展出 HTTPS,解释了什么是 HTTPS,以及与 HTTP 的区别。HTTPS 主要就是通过 SSL/TLS 实现安全,而安全我们又接触了什么是对称加密与非对称加密,非对称加密性能较弱,所以我们使用非对称加密来加密对称加密的 " 会话密钥 ",利用会话密钥加密明文解决了性能问题。

通过混合加密实现了机密性,利用摘要算法实现了完整性,通过数字签名使用非对称加密的 " 私钥 " 加密原文的摘要,对方则使用非对称加密的公钥解密出摘要,再比对解密出的原文通过摘要算法计算摘要与解密出的摘要比对是否一致实现了身份认证与不可否认。


文章来源于码哥字节 ,作者 MageByte 技术团队

如何用JAVA设计一个亿级消息量的 IM 系统

IM即时通讯大兴 发表了文章 • 0 个评论 • 81 次浏览 • 2020-09-11 11:01 • 来自相关话题

本文不会给出一套通用的IM方案,也不会评判某种架构的好坏,而是讨论设计IM系统的常见难题跟业界的解决方案。因为也没有所谓的通用方案,不同的解决方案都有其优缺点,只有最满足业务的系统才是一个好的系统。而且,在有限的人力、物力跟时间资源下,通常需要做出很多权衡,此... ...查看全部

本文不会给出一套通用的IM方案,也不会评判某种架构的好坏,而是讨论设计IM系统的常见难题跟业界的解决方案。因为也没有所谓的通用方案,不同的解决方案都有其优缺点,只有最满足业务的系统才是一个好的系统。而且,在有限的人力、物力跟时间资源下,通常需要做出很多权衡,此时,一个能够快速迭代、方便扩展的系统才是一个好的系统。

 

IM核心概念

用户:系统的使用者

消息:是指用户之间的沟通内容。通常在IM系统中,消息会有以下几类:文本消息、表情消息、图片消息、视频消息、文件消息等等

会话:通常指两个用户之间因聊天而建立起的关联

群:通常指多个用户之间因聊天而建立起的关联

终端:指用户使用IM系统的机器。通常有Android端、iOS端、Web端等等

未读数:指用户还没读的消息数量

用户状态:指用户当前是在线、离线还是挂起等状态

关系链:是指用户与用户之间的关系,通常有单向的好友关系、双向的好友关系、关注关系等等。这里需要注意与会话的区别,用户只有在发起聊天时才产生会话,但关系并不需要聊天才能建立。对于关系链的存储,可以使用图数据库(Neo4j等等),可以很自然地表达现实世界中的关系,易于建模

单聊:一对一聊天

群聊:多人聊天

客服:在电商领域,通常需要对用户提供售前咨询、售后咨询等服务。这时,就需要引入客服来处理用户的咨询

消息分流:在电商领域,一个店铺通常会有多个客服,此时决定用户的咨询由哪个客服来处理就是消息分流。通常消息分流会根据一系列规则来确定消息会分流给哪个客服,例如客服是否在线(客服不在线的话需要重新分流给另一个客服)、该消息是售前咨询还是售后咨询、当前客服的繁忙程度等等

信箱:本文的信箱我们指一个Timeline、一个收发消息的队列

 

读扩散 vs 写扩散

读扩散

我们先来看看读扩散。如上图所示,A与每个聊天的人跟群都有一个信箱(有些博文会叫Timeline),A在查看聊天信息的时候需要读取所有有新消息的信箱。这里的读扩散需要注意与Feeds系统的区别,在Feeds系统中,每个人都有一个写信箱,写只需要往自己的写信箱里写一次就好了,读需要从所有关注的人的写信箱里读。但IM系统里的读扩散通常是每两个相关联的人就有一个信箱,或者每个群一个信箱。

读扩散的优点:

写操作(发消息)很轻量,不管是单聊还是群聊,只需要往相应的信箱写一次就好了

每一个信箱天然就是两个人的聊天记录,可以方便查看聊天记录跟进行聊天记录的搜索

读扩散的缺点:

读操作(读消息)很重

写扩散

接下来看看写扩散。

e38c316470c48ab4e7f8492ec20398672f5e14.jpg.png

在写扩散中,每个人都只从自己的信箱里读取消息,但写(发消息)的时候,对于单聊跟群聊处理如下:

单聊:往自己的信箱跟对方的信箱都写一份消息,同时,如果需要查看两个人的聊天历史记录的话还需要再写一份(当然,如果从个人信箱也能回溯出两个人的所有聊天记录,但这样效率会很低)。

群聊:需要往所有的群成员的信箱都写一份消息,同时,如果需要查看群的聊天历史记录的话还需要再写一份。可以看出,写扩散对于群聊来说大大地放大了写操作。

写扩散优点:

读操作很轻量

可以很方便地做消息的多终端同步

写扩散缺点:

写操作很重,尤其是对于群聊来说

注意,在Feeds系统中:

写扩散也叫:Push、Fan-out或者Write-fanout

读扩散也叫:Pull、Fan-in或者Read-fanout

 

唯一ID设计

通常情况下,ID的设计主要有以下几大类:

UUID

基于Snowflake的ID生成方式

基于申请DB步长的生成方式

基于Redis或者DB的自增ID生成方式

特殊的规则生成唯一ID

具体的实现方法跟优缺点可以参考之前的一篇博文:分布式唯一 ID 解析

在IM系统中需要唯一Id的地方主要是:

会话ID

消息ID

 

消息ID

我们来看看在设计消息ID时需要考虑的三个问题。

 

消息ID不递增可以吗

我们先看看不递增的话会怎样:

使用字符串,浪费存储空间,而且不能利用存储引擎的特性让相邻的消息存储在一起,降低消息的写入跟读取性能

使用数字,但数字随机,也不能利用存储引擎的特性让相邻的消息存储在一起,会加大随机IO,降低性能;而且随机的ID不好保证ID的唯一性

因此,消息ID最好是递增的。

 

全局递增 vs 用户级别递增 vs 会话级别递增

全局递增:指消息ID在整个IM系统随着时间的推移是递增的。全局递增的话一般可以使用Snowflake(当然,Snowflake也只是worker级别的递增)。此时,如果你的系统是读扩散的话为了防止消息丢失,那每一条消息就只能带上上一条消息的ID,前端根据上一条消息判断是否有丢失消息,有消息丢失的话需要重新拉一次。

用户级别递增:指消息ID只保证在单个用户中是递增的,不同用户之间不影响并且可能重复。典型代表:微信。如果是写扩散系统的话信箱时间线ID跟消息ID需要分开设计,信箱时间线ID用户级别递增,消息ID全局递增。如果是读扩散系统的话感觉使用用户级别递增必要性不是很大。

会话级别递增:指消息ID只保证在单个会话中是递增的,不同会话之间不影响并且可能重复。典型代表:QQ。

 

连续递增 vs 单调递增

连续递增是指ID按 1,2,3...n 的方式生成;而单调递增是指只要保证后面生成的ID比前面生成的ID大就可以了,不需要连续。

据我所知,QQ的消息ID就是在会话级别使用的连续递增,这样的好处是,如果丢失了消息,当下一条消息来的时候发现ID不连续就会去请求服务器,避免丢失消息。此时,可能有人会想,我不能用定时拉的方式看有没有消息丢失吗?当然不能,因为消息ID只在会话级别连续递增的话那如果一个人有上千个会话,那得拉多少次啊,服务器肯定是抗不住的。

对于读扩散来说,消息ID使用连续递增就是一种不错的方式了。如果使用单调递增的话当前消息需要带上前一条消息的ID(即聊天消息组成一个链表),这样,才能判断消息是否丢失。

总结一下就是:

写扩散:信箱时间线ID使用用户级别递增,消息ID全局递增,此时只要保证单调递增就可以了

读扩散:消息ID可以使用会话级别递增并且最好是连续递增

 

会话ID

我们来看看设计会话ID需要注意的问题:

其中,会话ID有种比较简单的生成方式(特殊的规则生成唯一ID):拼接 from_user_id 跟 to_user_id:

如果 from_user_id 跟 to_user_id 都是32位整形数据的话可以很方便地用位运算拼接成一个64位的会话ID,即: conversation_id = ${from_user_id} << 32 | ${to_user_id} (在拼接前需要确保值比较小的用户ID是 from_user_id,这样任意两个用户发起会话可以很方便地知道会话ID)

如果from_user_id 跟 to_user_id 都是64位整形数据的话那就只能拼接成一个字符串了,拼接成字符串的话就比较伤了,浪费存储空间性能又不好。

前东家就是使用的上面第1种方式,第1种方式有个硬伤:随着业务在全球的扩展,32位的用户ID如果不够用需要扩展到64位的话那就需要大刀阔斧地改了。32位整形ID看起来能够容纳21亿个用户,但通常我们为了防止别人知道真实的用户数据,使用的ID通常不是连续的,这时,32位的用户ID就完全不够用了。因此,该设计完全依赖于用户ID,不是一种可取的设计方式。

因此,会话ID的设计可以使用全局递增的方式,加一个映射表,保存from_user_id、to_user_id跟conversation_id的关系。

 

推模式 vs 拉模式 vs 推拉结合模式

在IM系统中,新消息的获取通常会有三种可能的做法:

推模式:有新消息时服务器主动推给所有端(iOS、Android、PC等)

拉模式:由前端主动发起拉取消息的请求,为了保证消息的实时性,一般采用推模式,拉模式一般用于获取历史消息

推拉结合模式:有新消息时服务器会先推一个有新消息的通知给前端,前端接收到通知后就向服务器拉取消息

推模式简化图如下:

04cfb696364aeffcfdd83382d29a45bfefb11a.jpg.png

如上图所示,正常情况下,用户发的消息经过服务器存储等操作后会推给接收方的所有端。但推是有可能会丢失的,最常见的情况就是用户可能会伪在线(是指如果推送服务基于长连接,而长连接可能已经断开,即用户已经掉线,但一般需要经过一个心跳周期后服务器才能感知到,这时服务器会错误地以为用户还在线;伪在线是本人自己想的一个概念,没想到合适的词来解释)。因此如果单纯使用推模式的话,是有可能会丢失消息的。

推拉结合模式简化图如下:

6760f5926b20f8763ec72480c1328e859795dd.jpg.png

可以使用推拉结合模式解决推模式可能会丢消息的问题。在用户发新消息时服务器推送一个通知,然后前端请求最新消息列表,为了防止有消息丢失,可以再每隔一段时间主动请求一次。可以看出,使用推拉结合模式最好是用写扩散,因为写扩散只需要拉一条时间线的个人信箱就好了,而读扩散有N条时间线(每个信箱一条),如果也定时拉取的话性能会很差。

 

业界解决方案

前面了解了IM系统的常见设计问题,接下来我们再看看业界是怎么设计IM系统的。研究业界的主流方案有助于我们深入理解IM系统的设计。以下研究都是基于网上已经公开的资料,不一定正确,大家仅作参考就好了。

微信

虽然微信很多基础框架都是自研,但这并不妨碍我们理解微信的架构设计。从微信公开的《从0到1:微信后台系统的演进之路》这篇文章可以看出,微信采用的主要是:写扩散 + 推拉结合。由于群聊使用的也是写扩散,而写扩散很消耗资源,因此微信群有人数上限(目前是500)。所以这也是写扩散的一个明显缺点,如果需要万人群就比较难了。

从文中还可以看出,微信采用了多数据中心架构:

 62f39582378e16672d3132062133f47142ce8e.jpg.png

 


微信每个数据中心都是自治的,每个数据中心都有全量的数据,数据中心间通过自研的消息队列来同步数据。为了保证数据的一致性,每个用户都只属于一个数据中心,只能在自己所属的数据中心进行数据读写,如果用户连了其它数据中心则会自动引导用户接入所属的数据中心。而如果需要访问其它用户的数据那只需要访问自己所属的数据中心就可以了。同时,微信使用了三园区容灾的架构,使用Paxos来保证数据的一致性。

从微信公开的《万亿级调用系统:微信序列号生成器架构设计及演变》这篇文章可以看出,微信的ID设计采用的是:基于申请DB步长的生成方式 + 用户级别递增。如下图所示:

1.png

微信的序列号生成器由仲裁服务生成路由表(路由表保存了uid号段到AllocSvr的全映射),路由表会同步到AllocSvr跟Client。如果AllocSvr宕机的话会由仲裁服务重新调度uid号段到其它AllocSvr。

 

钉钉

钉钉公开的资料不多,从《阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处》这篇文章我们只能知道,钉钉最开始使用的是写扩散模型,为了支持万人群,后来貌似优化成了读扩散。

但聊到阿里的IM系统,不得不提的是阿里自研的Tablestore。一般情况下,IM系统都会有一个自增ID生成系统,但Tablestore创造性地引入了主键列自增,即把ID的生成整合到了DB层,支持了用户级别递增(传统MySQL等DB只能支持表级自增,即全局自增)。具体可以参考:《如何优化高并发IM系统架构》

 

Twitter

什么?Twitter不是Feeds系统吗?这篇文章不是讨论IM的吗?是的,Twitter是Feeds系统,但Feeds系统跟IM系统其实有很多设计上的共性,研究下Feeds系统有助于我们在设计IM系统时进行参考。再说了,研究下Feeds系统也没有坏处,扩展下技术视野嘛。

Twitter的自增ID设计估计大家都耳熟能详了,即大名鼎鼎的Snowflake,因此ID是全局递增的。


从这个视频分享《How We Learned to Stop Worrying and Love Fan-In at Twitter》可以看出,Twitter一开始使用的是写扩散模型,Fanout Service负责扩散写到Timelines Cache(使用了Redis),Timeline Service负责读取Timeline数据,然后由API Services返回给用户。

但由于写扩散对于大V来说写的消耗太大,因此后面Twitter又使用了写扩散跟读扩散结合的方式。如下图所示:



 2.png

对于粉丝数不多的用户如果发Twitter使用的还是写扩散模型,由Timeline Mixer服务将用户的Timeline、大V的写Timeline跟系统推荐等内容整合起来,最后再由API Services返回给用户。

 

58到家

58到家实现了一个通用的实时消息平台:

3.png

可以看出,msg-server保存了应用跟MQ主题之间的对应关系,msg-server根据这个配置将消息推到不同的MQ队列,具体的应用来消费就可以了。因此,新增一个应用只需要修改配置就可以了。

58到家为了保证消息投递的可靠性,还引入了确认机制:消息平台收到消息先落地数据库,接收方收到后应用层ACK再删除。使用确认机制最好是只能单点登录,如果多端能够同时登录的话那就比较麻烦了,因为需要所有端都确认收到消息后才能删除。

看到这里,估计大家已经明白了,设计一个IM系统很有挑战性。我们还是继续来看设计一个IM系统需要考虑的问题吧。

 

IM需要解决的问题

如何保证消息的实时性

在通信协议的选择上,我们主要有以下几个选择:

使用TCP Socket通信,自己设计协议:58到家等等

使用UDP Socket通信:QQ等等

使用HTTP长轮循:微信网页版等等

不管使用哪种方式,我们都能够做到消息的实时通知。但影响我们消息实时性的可能会在我们处理消息的方式上。例如:假如我们推送的时候使用MQ去处理并推送一个万人群的消息,推送一个人需要2ms,那么推完一万人需要20s,那么后面的消息就阻塞了20s。如果我们需要在10ms内推完,那么我们推送的并发度应该是:人数:10000 / (推送总时长:10 / 单个人推送时长:2) = 2000

因此,我们在选择具体的实现方案的时候一定要评估好我们系统的吞吐量,系统的每一个环节都要进行评估压测。只有把每一个环节的吞吐量评估好了,才能保证消息推送的实时性。

如何保证消息时序

以下情况下消息可能会乱序:

发送消息如果使用的不是长连接,而是使用HTTP的话可能会出现乱序。因为后端一般是集群部署,使用HTTP的话请求可能会打到不同的服务器,由于网络延迟或者服务器处理速度的不同,后发的消息可能会先完成,此时就产生了消息乱序。解决方案:

前端依次对消息进行处理,发送完一个消息再发送下一个消息。这种方式会降低用户体验,一般情况下不建议使用。

带上一个前端生成的顺序ID,让接收方根据该ID进行排序。这种方式前端处理会比较麻烦一点,而且聊天的过程中接收方的历史消息列表中可能会在中间插入一条消息,这样会很奇怪,而且用户可能会漏读消息。但这种情况可以通过在用户切换窗口的时候再进行重排来解决,接收方每次收到消息都先往最后面追加。

通常为了优化体验,有的IM系统可能会采取异步发送确认机制(例如:QQ)。即消息只要到达服务器,然后服务器发送到MQ就算发送成功。如果由于权限等问题发送失败的话后端再推一个通知下去。这种情况下MQ就要选择合适的Sharding策略了:

按to_user_id进行Sharding:使用该策略如果需要做多端同步的话发送方多个端进行同步可能会乱序,因为不同队列的处理速度可能会不一样。例如发送方先发送m1然后发送m2,但服务器可能会先处理完m2再处理m1,这里其它端会先收到m2然后是m1,此时其它端的会话列表就乱了。

按conversation_id进行Sharding:使用该策略同样会导致多端同步会乱序。

按from_user_id进行Sharding:这种情况下使用该策略是比较好的选择

通常为了优化性能,推送前可能会先往MQ推,这种情况下使用to_user_id才是比较好的选择。

用户在线状态如何做

很多IM系统都需要展示用户的状态:是否在线,是否忙碌等。主要可以使用Redis或者分布式一致性哈希来实现用户在线状态的存储。

看上面的图可能会有人疑惑,为什么每次心跳都需要更新Redis?如果我使用的是TCP长连接那是不是就不用每次心跳都更新了?确实,正常情况下服务器只需要在新建连接或者断开连接的时候更新一下Redis就好了。但由于服务器可能会出现异常,或者服务器跟Redis之间的网络会出现问题,此时基于事件的更新就会出现问题,导致用户状态不正确。因此,如果需要用户在线状态准确的话最好通过心跳来更新在线状态。

由于Redis是单机存储的,因此,为了提高可靠性跟性能,我们可以使用Redis Cluster或者Codis。

使用分布式一致性哈希需要注意在对Status Server Cluster进行扩容或者缩容的时候要先对用户状态进行迁移,不然在刚操作时会出现用户状态不一致的情况。同时还需要使用虚拟节点避免数据倾斜的问题。

 

多端同步怎么做

读扩散

前面也提到过,对于读扩散,消息的同步主要是以推模式为主,单个会话的消息ID顺序递增,前端收到推的消息如果发现消息ID不连续就请求后端重新获取消息。但这样仍然可能丢失会话的最后一条消息,为了加大消息的可靠性,可以在历史会话列表的会话里再带上最后一条消息的ID,前端在收到新消息的时候会先拉取最新的会话列表,然后判断会话的最后一条消息是否存在,如果不存在,消息就可能丢失了,前端需要再拉一次会话的消息列表;如果会话的最后一条消息ID跟消息列表里的最后一条消息ID一样,前端就不再处理。这种做法的性能瓶颈会在拉取历史会话列表那里,因为每次新消息都需要拉取后端一次,如果按微信的量级来看,单是消息就可能会有20万的QPS,如果历史会话列表放到MySQL等传统DB的话肯定抗不住。因此,最好将历史会话列表存到开了AOF(用RDB的话可能会丢数据)的Redis集群。这里只能感慨性能跟简单性不能兼得。

 

写扩散

对于写扩散来说,多端同步就简单些了。前端只需要记录最后同步的位点,同步的时候带上同步位点,然后服务器就将该位点后面的数据全部返回给前端,前端更新同步位点就可以了。

如何处理未读数

在IM系统中,未读数的处理非常重要。未读数一般分为会话未读数跟总未读数,如果处理不当,会话未读数跟总未读数可能会不一致,严重降低用户体验。

读扩散

对于读扩散来说,我们可以将会话未读数跟总未读数都存在后端,但后端需要保证两个未读数更新的原子性跟一致性,一般可以通过以下两种方法来实现:

使用Redis的multi事务功能,事务更新失败可以重试。但要注意如果你使用Codis集群的话并不支持事务功能。

使用Lua嵌入脚本的方式。使用这种方式需要保证会话未读数跟总未读数都在同一个Redis节点(Codis的话可以使用Hashtag)。这种方式会导致实现逻辑分散,加大维护成本。

写扩散

对于写扩散来说,服务端通常会弱化会话的概念,即服务端不存储历史会话列表。未读数的计算可由前端来负责,标记已读跟标记未读可以只记录一个事件到信箱里,各个端通过重放该事件的形式来处理会话未读数。使用这种方式可能会造成各个端的未读数不一致,至少微信就会有这个问题。

如果写扩散也通过历史会话列表来存储未读数的话那用户时间线服务跟会话服务紧耦合,这个时候需要保证原子性跟一致性的话那就只能使用分布式事务了,会大大降低系统的性能。

如何存储历史消息

读扩散

对于读扩散,只需要按会话ID进行Sharding存储一份就可以了。

 

写扩散

对于写扩散,需要存储两份:一份是以用户为Timeline的消息列表,一份是以会话为Timeline的消息列表。以用户为Timeline的消息列表可以用用户ID来做Sharding,以会话为Timeline的消息列表可以用会话ID来做Sharding。

 

数据冷热分离

对于IM来说,历史消息的存储有很强的时间序列特性,时间越久,消息被访问的概率也越低,价值也越低。如果我们需要存储几年甚至是永久的历史消息的话(电商IM中比较常见),那么做历史消息的冷热分离就非常有必要了。数据的冷热分离一般是HWC(Hot-Warm-Cold)架构。对于刚发送的消息可以放到Hot存储系统(可以用Redis)跟Warm存储系统,然后由Store Scheduler根据一定的规则定时将冷数据迁移到Cold存储系统。获取消息的时候需要依次访问Hot、Warm跟Cold存储系统,由Store Service整合数据返回给IM Service。

 

接入层怎么做

实现接入层的负载均衡主要有以下几个方法:

硬件负载均衡:例如F5、A10等等。硬件负载均衡性能强大,稳定性高,但价格非常贵,不是土豪公司不建议使用。

使用DNS实现负载均衡:使用DNS实现负载均衡比较简单,但使用DNS实现负载均衡如果需要切换或者扩容那生效会很慢,而且使用DNS实现负载均衡支持的IP个数有限制、支持的负载均衡策略也比较简单。

DNS + 4层负载均衡 + 7层负载均衡架构:例如 DNS + DPVS + Nginx 或者 DNS + LVS + Nginx。有人可能会疑惑为什么要加入4层负载均衡呢?这是因为7层负载均衡很耗CPU,并且经常需要扩容或者缩容,对于大型网站来说可能需要很多7层负载均衡服务器,但只需要少量的4层负载均衡服务器即可。因此,该架构对于HTTP等短连接大型应用很有用。当然,如果流量不大的话只使用DNS + 7层负载均衡即可。但对于长连接来说,加入7层负载均衡Nginx就不大好了。因为Nginx经常需要改配置并且reload配置,reload的时候TCP连接会断开,造成大量掉线。

DNS + 4层负载均衡:4层负载均衡一般比较稳定,很少改动,比较适合于长连接。

对于长连接的接入层,如果我们需要更加灵活的负载均衡策略或者需要做灰度的话,那我们可以引入一个调度服务,如下图所示:

 4.png

Access Schedule Service可以实现根据各种策略来分配Access Service,例如:

根据灰度策略来分配

根据就近原则来分配

根据最少连接数来分配

 

架构心得

最后,分享一下做大型应用的架构心得:

灰度!灰度!灰度!

监控!监控!监控!

告警!告警!告警!

缓存!缓存!缓存!

限流!熔断!降级!

低耦合,高内聚!

避免单点,拥抱无状态!

评估!评估!评估!

压测!压测!压测!

 

来源:InfoQ 


【Geek Online 2020 编程挑战赛】有人组队吗?

GeekOnline编程挑战赛梅川酷子 回复了问题 • 2 人关注 • 2 个回复 • 249 次浏览 • 2020-09-10 18:25 • 来自相关话题

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

GeekOnline编程挑战赛梅川酷子 发表了文章 • 0 个评论 • 430 次浏览 • 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开发,融云开发文档建议等技术问题欢迎留言讨论

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

GeekOnline编程挑战赛梅川酷子 发表了文章 • 0 个评论 • 456 次浏览 • 2020-10-28 17:40 • 来自相关话题

Geek Online 2020 编程挑战赛圆满落幕,一张图回顾 Geek Online 2020 编程挑战赛精彩瞬间!

Geek Online 2020 编程挑战赛圆满落幕,

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

微信图片_20201202164614.png微信图片_20201028173842.png

微信图片_20201202164655.png

微信图片_20201202164718.png

微信图片_20201202164744.png

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

GeekOnline编程挑战赛梅川酷子 发表了文章 • 0 个评论 • 469 次浏览 • 2020-10-27 10:12 • 来自相关话题

Geek Online 2020 编程挑战赛是融云 面向全球 IM 和 RTC 开发者、编程爱好者与极客举办的一场在线黑客马拉松。融云作为全球领先的互联网通信云厂商,一直致力于 IM 和 RTC 技术的创新和发展,希望与全球开发者一道,共同... ...查看全部

Geek Online 2020 编程挑战赛是融云 面向全球 IM 和 RTC 开发者、编程爱好者与极客举办的一场在线黑客马拉松。融云作为全球领先的互联网通信云厂商,一直致力于 IM 和 RTC 技术的创新和发展,希望与全球开发者一道,共同寻找 IM 和 RTC 技术的更多落地场景,开辟更多使用途径。

本届 Geek Online 2020 编程挑战赛以《后疫情时代,通信云技术的创新及实践》为主题,也是希望借此机会鼓励开发者挖掘关于实时音视频和即时通讯技术的更多创意。通过近 2 个月的激烈角逐,在近百份参赛作品中,15 支队伍突出重围,闯入总决赛。

其中,缘拼、红鲤鱼与绿鲤鱼与驴、youwe young、萍水相逢的生活、MAXFLOAT 五组参赛团队分获了最终的奖项。

在比赛中,他们不仅夺得奖杯、获得声誉,也赢得了丰厚的奖金;而在比赛后,我们也采访了其中的三组选手,和他们聊了聊参赛前和赛后的一些“独家记忆”。



      lPc6q1vIgtC3pM40__thumbnail.png

“作为大学在读生,我能深刻体会到目前很多大学生的社交问题 —— 不愿甚至排斥参与社交,难以与陌生人沟通。正是为了改善乃至解决这个问题,我们设计出了缘拼。”

冠军团队:缘拼

选手:康帅 杨桢 张晨博

1、请介绍一下自己/团队

我们是来自内蒙古师范大学计算机科学技术学院蚂蚁工坊的大三在校生,团队中有两名前端开发工程师和一名后端开发工程师,擅长 uniapp 以及微信小程序开发,有多个企业合作项目开发经验。我们都热爱编程,热爱生活,有创意并愿意将其付诸于实际。

2、能谈一谈你在比赛中的项目设计思路,以及比赛中的一些趣事么?

作为大学在读生,我能深刻体会到目前很多大学生的社交问题 —— 不愿甚至排斥参与社交,难以与陌生人沟通。正是为了改善乃至解决这个问题,我们设计出了缘拼。而在比赛的设计过程中,我们一开始决定的项目名称是约拼,但是经过几回队内讨论后,认为陌生人社交,更多靠的是缘分,而不是按部就班,所以改名为缘拼。

3、如果有更充分的时间与资源,你还想要借助 RTC 技术来实现哪些场景应用?

受当前疫情影响,人们的活动范围很是受限,但受限并不意味着无趣 —— 基于 RTC 技术,我们有了一个设想:用户可以发帖自由提问,而帖子增加的同时会创建一个直播连麦群聊,用户可以在其中畅所欲言,足不出户却一见如故,共同探讨问题的解决方法。

4、对于你们来讲,参加编程挑战赛的经历给你带来了什么?参赛的意义是什么?

对于我们来说,这次参加编程挑战赛意义重大,参加编程挑战赛不仅给我带来了莫大的鼓舞,也让我自己对编程更加热爱,同时也意识到自身有许多可以进步的空间。而且这次获得冠军也是对我自身两年编程学习的一次肯定与激励,让我有更大的动力去向编程水平的顶峰发起冲刺。

5、对没有参加过类似比赛、一直持观望态度的朋友,你有什么建议吗?

勇敢参加,迈出第一步才知道路顺不顺,有了竞争才能有进步。

6、提供一张照片或者能代表你们团队的图片吧

 

       LKAlADNHRPLUiivP__thumbnail.png      

 

三个男人,三台电脑,三个月,一个奇迹(缘拼)。




GLSHGa6TWXQxGklG__thumbnail.jpg       

“我想各架一个摄像头在东京、威尼斯和九寨沟,然后在我的房间投影成门窗,这样我就拥有了一座「伪·哈尔的移动城堡」。”

亚军 & 突出贡献奖团队:红鲤鱼与绿鲤鱼与驴

选手:顾俊 陆禹淳

1、先介绍一下你的团队与本次大赛的作品吧

「红鲤鱼与绿鲤鱼与驴」是一个固定的团队,由三个人构成:熟悉前端、WebRTC方向的红鲤鱼(也就是我本人),熟悉后端、大数据方向的绿鲤鱼,以及熟悉视觉、法务方面的驴(希望不会用到法务方面)。这次比赛是由红鲤鱼与绿鲤鱼两名成员参与的,但仍沿用了团队名。

本次大赛的参赛作品「点解」,是一个面向程序员的解谜游戏。该谜题层次丰富如洋葱,第一层需要用户集成融云SDK、掌握融云的基本概念。第二层需要用户做一定程度的视频后处理。第三层需要用户做一些图像识别。整个过程需要像打游戏一样走出新手村、打怪练级、挑战大BOSS,最终拿到宝藏。

2、能谈一谈你在比赛中的项目设计思路,以及比赛中的一些趣事么

「点解」的核心是一个不断翻转的二维码。它的灵感来源于一个物联网界的著名协议。这个协议在一个加密的 WIFI 信道中,通过发送的包的长度来向并不拥有密码的客户端传递消息。这让我对于信道有了颠覆性的认知 —— 信道可以如此不走寻常路!于是我就构思了这个利用 RTC 信道降级传输元信息的通信方式。它不够精巧,但足够特别。

3、如果有更充分的时间与资源,你还想要借助 RTC 技术来实现哪些场景应用?

我想各架一个摄像头在东京、威尼斯和九寨沟,然后在我的房间投影成门窗,这样我就拥有了一座「伪·哈尔的移动城堡」。

4、对于你个人来讲,参加编程挑战赛的经历给你带来了什么?参赛的意义是什么?

因为工作的原因,我平时会接触各种各样的、不同场景的实时音视频应用。看多了之后就有点审美疲劳。对我而言,很多音视频项目的「创新」,多多少少能够见到已有应用的影子。从另一方面来说,我作为一个 WebRTC 工程师,如果仍然拘泥于我见过的场景,或者说创新力度不够大的话,那么参加挑战赛又跟上班有什么分别呢?

所以其实像 GeekOnline 这样的比赛给了这样的项目一些机会,这些项目也许不是什么赚大钱的项目,但是它们足够有趣。而唯有在这样的场景下,这样的项目才有机会被买单,这样的项目才有机会被人看见。

那么为什么不做这样的项目呢?想赚钱去上班就好了啊。

5、对没有参加过类似比赛、一直持观望态度的朋友,你有什么建议吗?

参加啊,大不了搞砸,怕什么。搞砸一次,浑身轻松。

6、提供一张照片或者能代表你们团队的图片吧

 

       vJLVQjzLzAOw5znq__thumbnail.png      

你看这个小人,其实是一半安卓,代表了程序员,它的“帽子”其实是一条吞了大象的蛇,取自《小王子》。



 jQnAbrcslfHJGuJm__thumbnail.jpeg.jpg

“就如队名一样,我们的爱心无限大,我们的潜力无限大,我们的梦想无限大,我们的能力也无限大。”

商业价值奖团队:MAXFLOAT

选手:张先红 华辰 杨小重 焉红霞

1. 请结合几个关键词介绍一下自己/团队

MAXFLOAT是一支有实力,有梦想,有创意,敢拼搏,即想即做的队伍。团队成员经验丰富,思维灵敏,活泼可爱,富有爱心。就如队名一样,我们的爱心无限大,我们的潜力无限大,我们的梦想无限大,我们的能力也无限大。

2. 能谈一谈你在比赛中的项目设计思路,以及比赛中的一些趣事么?

“宠宝儿”是一款为宠物服务的软件,面向的都是比较有爱心的群体,因此在整体风格上,定义为暖色调。而内容素材上,偏卡通化,使其具有治愈系能力。在功能架构上,我们尽量做到简约,不让用户在杂余的地方浪费时间。

分享个比较有趣的事。在开发过程遇到了一个问题,融云的同事帮忙找了两天,最后发现是两个方法太像了,作用差不多,调错了,那时心中顿时是万马奔腾啊,但是也比较感谢他们,他们的认真和负责,深深的打动了我。我觉得其它的比赛很难做到这点。

3. 如果有更充分的时间与资源,你还想要借助 RTC 技术来实现哪些场景应用?

1)屏幕共享

对于直播,单纯的视频直播,只能看到摄像头前的东西,而考虑到医生在进行直播的时候,有时普及一些东西,需展示一些素材。如果接入商城,用户可能在直播推荐自己的一些产品,这个时候需要做产品展示,因此屏幕共享是必须的。但这个屏幕共享不是单纯的手机屏幕共享,而应该将多个硬件的屏幕结合,用户自己选择展示。

2)内部会议

后期如果接入宠物医院,这样就相当于面向企业了,因此会考虑为他们提供一些服务。

4. 对于你们来讲,参加编程挑战赛的经历给你带来了什么?参赛的意义是什么?

当我看到咱们融云举办的活动时候,报名时间已经过去差不多半个月,当时担心时间不够用,但是到最后,我还提前一个多星期提交了作品。所以我觉得,想做什么,那就动手去做吧,不要管其它的,做了再说,决定了之后,我们开始确立参赛的项目,是构思已经的宠物项目,而这一次,它有机会展现给更多的人。然后我们对功能的删减,确定要做哪些,大概需要多长时间,通过合理的规划,自己的努力和坚持,我们提前一个多星期完成了作品。而且之前,我们没有想过做直播方面的功能,而这次融云给了我们一个很好的思路。

5. 对没有参加过类似比赛、一直持观望态度的朋友,你有什么建议吗?

之前我们没有参加过任何比赛,这次也是偶尔看到的,正好大家都比较感兴趣,就报名参加了。

对于那些观望的,其实也没什么好的建议,如果平时比较忙的话,那确实是没有精力在放到其它事情上了,但如果有兴趣,有精力,那么我建议,还是要多做多想,这样能更好的提升自己,如果瞻前顾后,那将一事无成。

6. 提供一张照片或者能代表你们团队的图片吧

 VtotPQXvY38Pzp7w__thumbnail.jpeg.jpg

星空代表着梦想,而我们有自己的梦想,我们想做那颗最亮的星。


这次比赛中取得的成绩,对于这些参赛选手来说都只是个开始,但正如他们所说,Geek Online 2020 编程挑战赛的这一经历,一定会是他们人生中的一次宝贵经验。

Geek Online 2020 编程挑战赛虽然是第一次举办,但已经收获了参赛选手以及观看决赛路演直播观众们的一致好评,融云作为专注于通信的 PaaS 云服务平台,想要通过底层的基础模块支持,帮助企业与开发者构建「云通信」的能力。

举办此次编程挑战赛的目的,也是希望让开发者们碰撞出技术的思维火花,加速潮流技术的应用创新,也为开发者们搭建了一个沟通、交流、合作的平台,希望能够掀起一股通信技术应用的探索与实践热潮。

也希望全球 IM 和 RTC 开发者、编程爱好者与极客

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

GeekOnline编程挑战赛梅川酷子 发表了文章 • 1 个评论 • 451 次浏览 • 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       


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

IM即时通讯放肆小青年 回复了问题 • 28 人关注 • 27 个回复 • 919 次浏览 • 2020-10-26 09:33 • 来自相关话题

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

回复

IM即时通讯放肆小青年 回复了问题 • 28 人关注 • 27 个回复 • 919 次浏览 • 2020-10-26 09:33 • 来自相关话题

【Geek Online 2020 编程挑战赛】有人组队吗?

回复

GeekOnline编程挑战赛梅川酷子 回复了问题 • 2 人关注 • 2 个回复 • 249 次浏览 • 2020-09-10 18:25 • 来自相关话题

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

GeekOnline编程挑战赛梅川酷子 发表了文章 • 0 个评论 • 430 次浏览 • 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 编程挑战赛完美收官!

GeekOnline编程挑战赛梅川酷子 发表了文章 • 1 个评论 • 451 次浏览 • 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       


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

GeekOnline编程挑战赛梅川酷子 发表了文章 • 0 个评论 • 456 次浏览 • 2020-10-28 17:40 • 来自相关话题

Geek Online 2020 编程挑战赛圆满落幕,一张图回顾 Geek Online 2020 编程挑战赛精彩瞬间!

Geek Online 2020 编程挑战赛圆满落幕,

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

微信图片_20201202164614.png微信图片_20201028173842.png

微信图片_20201202164655.png

微信图片_20201202164718.png

微信图片_20201202164744.png

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

GeekOnline编程挑战赛梅川酷子 发表了文章 • 0 个评论 • 469 次浏览 • 2020-10-27 10:12 • 来自相关话题

Geek Online 2020 编程挑战赛是融云 面向全球 IM 和 RTC 开发者、编程爱好者与极客举办的一场在线黑客马拉松。融云作为全球领先的互联网通信云厂商,一直致力于 IM 和 RTC 技术的创新和发展,希望与全球开发者一道,共同... ...查看全部

Geek Online 2020 编程挑战赛是融云 面向全球 IM 和 RTC 开发者、编程爱好者与极客举办的一场在线黑客马拉松。融云作为全球领先的互联网通信云厂商,一直致力于 IM 和 RTC 技术的创新和发展,希望与全球开发者一道,共同寻找 IM 和 RTC 技术的更多落地场景,开辟更多使用途径。

本届 Geek Online 2020 编程挑战赛以《后疫情时代,通信云技术的创新及实践》为主题,也是希望借此机会鼓励开发者挖掘关于实时音视频和即时通讯技术的更多创意。通过近 2 个月的激烈角逐,在近百份参赛作品中,15 支队伍突出重围,闯入总决赛。

其中,缘拼、红鲤鱼与绿鲤鱼与驴、youwe young、萍水相逢的生活、MAXFLOAT 五组参赛团队分获了最终的奖项。

在比赛中,他们不仅夺得奖杯、获得声誉,也赢得了丰厚的奖金;而在比赛后,我们也采访了其中的三组选手,和他们聊了聊参赛前和赛后的一些“独家记忆”。



      lPc6q1vIgtC3pM40__thumbnail.png

“作为大学在读生,我能深刻体会到目前很多大学生的社交问题 —— 不愿甚至排斥参与社交,难以与陌生人沟通。正是为了改善乃至解决这个问题,我们设计出了缘拼。”

冠军团队:缘拼

选手:康帅 杨桢 张晨博

1、请介绍一下自己/团队

我们是来自内蒙古师范大学计算机科学技术学院蚂蚁工坊的大三在校生,团队中有两名前端开发工程师和一名后端开发工程师,擅长 uniapp 以及微信小程序开发,有多个企业合作项目开发经验。我们都热爱编程,热爱生活,有创意并愿意将其付诸于实际。

2、能谈一谈你在比赛中的项目设计思路,以及比赛中的一些趣事么?

作为大学在读生,我能深刻体会到目前很多大学生的社交问题 —— 不愿甚至排斥参与社交,难以与陌生人沟通。正是为了改善乃至解决这个问题,我们设计出了缘拼。而在比赛的设计过程中,我们一开始决定的项目名称是约拼,但是经过几回队内讨论后,认为陌生人社交,更多靠的是缘分,而不是按部就班,所以改名为缘拼。

3、如果有更充分的时间与资源,你还想要借助 RTC 技术来实现哪些场景应用?

受当前疫情影响,人们的活动范围很是受限,但受限并不意味着无趣 —— 基于 RTC 技术,我们有了一个设想:用户可以发帖自由提问,而帖子增加的同时会创建一个直播连麦群聊,用户可以在其中畅所欲言,足不出户却一见如故,共同探讨问题的解决方法。

4、对于你们来讲,参加编程挑战赛的经历给你带来了什么?参赛的意义是什么?

对于我们来说,这次参加编程挑战赛意义重大,参加编程挑战赛不仅给我带来了莫大的鼓舞,也让我自己对编程更加热爱,同时也意识到自身有许多可以进步的空间。而且这次获得冠军也是对我自身两年编程学习的一次肯定与激励,让我有更大的动力去向编程水平的顶峰发起冲刺。

5、对没有参加过类似比赛、一直持观望态度的朋友,你有什么建议吗?

勇敢参加,迈出第一步才知道路顺不顺,有了竞争才能有进步。

6、提供一张照片或者能代表你们团队的图片吧

 

       LKAlADNHRPLUiivP__thumbnail.png      

 

三个男人,三台电脑,三个月,一个奇迹(缘拼)。




GLSHGa6TWXQxGklG__thumbnail.jpg       

“我想各架一个摄像头在东京、威尼斯和九寨沟,然后在我的房间投影成门窗,这样我就拥有了一座「伪·哈尔的移动城堡」。”

亚军 & 突出贡献奖团队:红鲤鱼与绿鲤鱼与驴

选手:顾俊 陆禹淳

1、先介绍一下你的团队与本次大赛的作品吧

「红鲤鱼与绿鲤鱼与驴」是一个固定的团队,由三个人构成:熟悉前端、WebRTC方向的红鲤鱼(也就是我本人),熟悉后端、大数据方向的绿鲤鱼,以及熟悉视觉、法务方面的驴(希望不会用到法务方面)。这次比赛是由红鲤鱼与绿鲤鱼两名成员参与的,但仍沿用了团队名。

本次大赛的参赛作品「点解」,是一个面向程序员的解谜游戏。该谜题层次丰富如洋葱,第一层需要用户集成融云SDK、掌握融云的基本概念。第二层需要用户做一定程度的视频后处理。第三层需要用户做一些图像识别。整个过程需要像打游戏一样走出新手村、打怪练级、挑战大BOSS,最终拿到宝藏。

2、能谈一谈你在比赛中的项目设计思路,以及比赛中的一些趣事么

「点解」的核心是一个不断翻转的二维码。它的灵感来源于一个物联网界的著名协议。这个协议在一个加密的 WIFI 信道中,通过发送的包的长度来向并不拥有密码的客户端传递消息。这让我对于信道有了颠覆性的认知 —— 信道可以如此不走寻常路!于是我就构思了这个利用 RTC 信道降级传输元信息的通信方式。它不够精巧,但足够特别。

3、如果有更充分的时间与资源,你还想要借助 RTC 技术来实现哪些场景应用?

我想各架一个摄像头在东京、威尼斯和九寨沟,然后在我的房间投影成门窗,这样我就拥有了一座「伪·哈尔的移动城堡」。

4、对于你个人来讲,参加编程挑战赛的经历给你带来了什么?参赛的意义是什么?

因为工作的原因,我平时会接触各种各样的、不同场景的实时音视频应用。看多了之后就有点审美疲劳。对我而言,很多音视频项目的「创新」,多多少少能够见到已有应用的影子。从另一方面来说,我作为一个 WebRTC 工程师,如果仍然拘泥于我见过的场景,或者说创新力度不够大的话,那么参加挑战赛又跟上班有什么分别呢?

所以其实像 GeekOnline 这样的比赛给了这样的项目一些机会,这些项目也许不是什么赚大钱的项目,但是它们足够有趣。而唯有在这样的场景下,这样的项目才有机会被买单,这样的项目才有机会被人看见。

那么为什么不做这样的项目呢?想赚钱去上班就好了啊。

5、对没有参加过类似比赛、一直持观望态度的朋友,你有什么建议吗?

参加啊,大不了搞砸,怕什么。搞砸一次,浑身轻松。

6、提供一张照片或者能代表你们团队的图片吧

 

       vJLVQjzLzAOw5znq__thumbnail.png      

你看这个小人,其实是一半安卓,代表了程序员,它的“帽子”其实是一条吞了大象的蛇,取自《小王子》。



 jQnAbrcslfHJGuJm__thumbnail.jpeg.jpg

“就如队名一样,我们的爱心无限大,我们的潜力无限大,我们的梦想无限大,我们的能力也无限大。”

商业价值奖团队:MAXFLOAT

选手:张先红 华辰 杨小重 焉红霞

1. 请结合几个关键词介绍一下自己/团队

MAXFLOAT是一支有实力,有梦想,有创意,敢拼搏,即想即做的队伍。团队成员经验丰富,思维灵敏,活泼可爱,富有爱心。就如队名一样,我们的爱心无限大,我们的潜力无限大,我们的梦想无限大,我们的能力也无限大。

2. 能谈一谈你在比赛中的项目设计思路,以及比赛中的一些趣事么?

“宠宝儿”是一款为宠物服务的软件,面向的都是比较有爱心的群体,因此在整体风格上,定义为暖色调。而内容素材上,偏卡通化,使其具有治愈系能力。在功能架构上,我们尽量做到简约,不让用户在杂余的地方浪费时间。

分享个比较有趣的事。在开发过程遇到了一个问题,融云的同事帮忙找了两天,最后发现是两个方法太像了,作用差不多,调错了,那时心中顿时是万马奔腾啊,但是也比较感谢他们,他们的认真和负责,深深的打动了我。我觉得其它的比赛很难做到这点。

3. 如果有更充分的时间与资源,你还想要借助 RTC 技术来实现哪些场景应用?

1)屏幕共享

对于直播,单纯的视频直播,只能看到摄像头前的东西,而考虑到医生在进行直播的时候,有时普及一些东西,需展示一些素材。如果接入商城,用户可能在直播推荐自己的一些产品,这个时候需要做产品展示,因此屏幕共享是必须的。但这个屏幕共享不是单纯的手机屏幕共享,而应该将多个硬件的屏幕结合,用户自己选择展示。

2)内部会议

后期如果接入宠物医院,这样就相当于面向企业了,因此会考虑为他们提供一些服务。

4. 对于你们来讲,参加编程挑战赛的经历给你带来了什么?参赛的意义是什么?

当我看到咱们融云举办的活动时候,报名时间已经过去差不多半个月,当时担心时间不够用,但是到最后,我还提前一个多星期提交了作品。所以我觉得,想做什么,那就动手去做吧,不要管其它的,做了再说,决定了之后,我们开始确立参赛的项目,是构思已经的宠物项目,而这一次,它有机会展现给更多的人。然后我们对功能的删减,确定要做哪些,大概需要多长时间,通过合理的规划,自己的努力和坚持,我们提前一个多星期完成了作品。而且之前,我们没有想过做直播方面的功能,而这次融云给了我们一个很好的思路。

5. 对没有参加过类似比赛、一直持观望态度的朋友,你有什么建议吗?

之前我们没有参加过任何比赛,这次也是偶尔看到的,正好大家都比较感兴趣,就报名参加了。

对于那些观望的,其实也没什么好的建议,如果平时比较忙的话,那确实是没有精力在放到其它事情上了,但如果有兴趣,有精力,那么我建议,还是要多做多想,这样能更好的提升自己,如果瞻前顾后,那将一事无成。

6. 提供一张照片或者能代表你们团队的图片吧

 VtotPQXvY38Pzp7w__thumbnail.jpeg.jpg

星空代表着梦想,而我们有自己的梦想,我们想做那颗最亮的星。


这次比赛中取得的成绩,对于这些参赛选手来说都只是个开始,但正如他们所说,Geek Online 2020 编程挑战赛的这一经历,一定会是他们人生中的一次宝贵经验。

Geek Online 2020 编程挑战赛虽然是第一次举办,但已经收获了参赛选手以及观看决赛路演直播观众们的一致好评,融云作为专注于通信的 PaaS 云服务平台,想要通过底层的基础模块支持,帮助企业与开发者构建「云通信」的能力。

举办此次编程挑战赛的目的,也是希望让开发者们碰撞出技术的思维火花,加速潮流技术的应用创新,也为开发者们搭建了一个沟通、交流、合作的平台,希望能够掀起一股通信技术应用的探索与实践热潮。

也希望全球 IM 和 RTC 开发者、编程爱好者与极客

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

GeekOnline编程挑战赛梅川酷子 发表了文章 • 0 个评论 • 515 次浏览 • 2020-09-21 14:27 • 来自相关话题

近日,首届 Geek Online 2020 编程挑战赛正式启动,作为挑战赛主办方的融云,希望借此机会与开发者一起,共同挖掘 RTC 和 IM 技术的创新应用场景,发现更多通信云领域的落地实践。据了解,此次编程挑战赛采用线上形式,开发者通过使用融云 ... ...查看全部

近日,首届 Geek Online 2020 编程挑战赛正式启动,作为挑战赛主办方的融云,希望借此机会与开发者一起,共同挖掘 RTC 和 IM 技术的创新应用场景,发现更多通信云领域的落地实践。据了解,此次编程挑战赛采用线上形式,开发者通过使用融云 IM+RTC SDK 进行创新应用开发,参赛作品通过 GitHub 提交,秉承开源、公平、公正的原则,从作品完整度、创新性以及商业价值三方面进行评选,致敬开发者精神。

c1b9f25c8aea944c7856a7110dfc54a.jpg

01 疫情推动音视频技术的应用场景发展

过去,音视频技术应用最广的两个场景集中在娱乐视频直播以及视频会议。在今年疫情的推动下,催生出更多的音视频应用场景,尤其以在线教育以及远程办公两大领域的使用最为广泛。

借助音视频技术,用户体验的方式从线下转移到线上,省去了路程奔波的时间,减少线下的空间成本,同时利用相关技术可以在线上获取到更好的互动体验,带来了远程体验的普及,让线上交流由被动变为主动。

后疫情时代,远程在线的沟通方式逐渐受到大家的认可,除了在线教育和远程办公外,其它线下场景也逐步线上化,例如用户可以远程开通银行卡,法庭可以在线上进行审判等等,通过各种远程无接触的服务,大家享受着音视频技术带来的便捷性。

因此,疫情不仅推动音视频技术的应用场景发展,相对应,音视频技术也逐渐成为了各行业、各产品作为支撑业务形态所必备的基础能力。

02 Geek Online 编程挑战赛上线开拓更多业务场景

为了挖掘更多更优秀的产品应用场景,融云发起了 Geek Online 2020 编程挑战赛,以“后疫情时代,通信云技术的创新及实践”为主题,鼓励开发者挖掘更多即时通讯和音视频技术的应用场景。挑战赛已于 8 月 24 日开始报名,赛程近 2 个月,10 月 17 日进行线上决赛,并计划于 10 月 31 日在 WICC 2020 互联网通信云大会现场颁奖

在谈到举办编程挑战赛的初衷时,融云 CTO 杨攀告诉笔者,融云服务的对象就是开发者群体,融云的使命是与开发者共成长。过去,融云与开发者建立了多种沟通渠道,包括线上的工单、电话、技术群、文档,以及线下的技术沙龙和 WICC 峰会。而编程挑战赛是想让开发者之间进行更好地交流互动,让开发者站在舞台中央,表达他们创新的想法和点子,也是融云与开发者互动模式的迭代。

微信图片_20200921142307.png

据了解,此次挑战赛的参赛作品须集成融云官网最新版本的即时通讯 SDK 或实时音视频(直播)SDK,应用可以实现一个具体场景或解决一个具体问题,并提交作品的全部源码、编译好的真机安装包,以及必要的说明文档(README.md),源码部分均以 MIT 开源协议对外开放。

本次挑战赛的作品评选会根据作品完成度(60%)、潜在商业价值(20%)、创意度(20%)等三个维度由专家进行点评打分。在杨攀看来,优秀的作品应该更加具有创意和想法。在作品具有一定完整度的前提下,是否具有创意的场景,同时也富有商业价值,是整个作品的加分项。“我认为大家并不需要追求项目的代码量,不在于规模,而在于开发者做的事情要有创意、有想法,可以直击人心,这样更容易获得更多评委的加分。”

03 致敬开发者精神 为开发者提供专业服务

值得注意的是,此次 Geek Online 2020 编程挑战赛有两个方面区别于其他开发者大赛,即作品提交渠道以及比赛服务模式。

首先,参赛作品并不是在融云官网提交,而是要求在 GitHub 上提交。杨攀解释道,众所周知,GitHub 是全球最大的开源社区,编程挑战赛的作品在 GitHub 提交是想要向开发者精神致敬,要求所有作品开源,以便能接受所有开发者的检验,让整个赛事更加公平公正。

此外,过去很多开发者大赛都是自助模式,即由比赛组委会公布完赛题、时间、赛程安排、作品要求、奖项等大赛内容之后,开发者便可以按照官方提供的文档,自行研究工具的使用,完成后在线提交作品。而融云的做法却截然不同,融云会给所有的开发团队提供专门的支持。杨攀表示,一是让服务团队及研发团队可以为参赛队伍提供一对一的支持服务,以便他们能够在有限的时间内完成更好的作品;另一方面,也是想借此机会,让研发团队与开发者进行更深入地交流,聆听并收集开发者的想法和反馈,以助于融云的产品迭代演进。

在挑战赛奖励方面,除了奖金和奖杯以外,融云还会引入投资机构,如果开发团队的作品在完整度、商业价值等方面均受到了认可,融云会作为桥梁,将其对接给投资机构。此外,如果团队选手愿意以个人身份加入融云,也会开放融云招聘的绿色通道。优胜者还会受邀到 WICC 2020 全球互联网通信云大会现场参加颁奖典礼,与受邀参会的众多专家面对面学习交流

微信图片_20200921142258.png

▲ 扫码免费报名

04 赋能开发者 以硬实力赢取信赖

在即时通讯以及音视频领域,不乏很多有竞争实力的企业,大到云计算服务提供商,小到初创企业,在通信云赛道上,可谓“百家争鸣”。而融云又有哪些核心竞争力,可以在行业内脱颖而出,赢得众多开发者的信赖呢?

据杨攀介绍,即时通讯技术相对比较封闭和私有,业界开源的通信协议只有 XMPP。由于该协议是在 1999 年开源,在协议设计之处并未预知到未来移动互联网时代的网络复杂情况,因此这一开源协议在如今使用会存在很多问题,例如通信质量,系统支持人数限制等等。融云的核心研发团队来自于飞信,具有丰富的通信技术经验,自主设计了通讯协议,保证了平台通讯的基础质量。如今,融云的日活跃用户数量达到 7000 多万,在国内仅次于微信、QQ 等巨头产品,足见其技术实力。

在音视频领域,谷歌于 2010 年收购 VoIP 软件开发商 Global IP Solutions 而获得 WebRTC 技术,并于 2011 年开源该项目,但是谷歌只开源了部分功能,即端到端的通信,支持两个人之间的传输音视频流,无法支持多人沟通场景,此外,在更加复杂的网络环境中,经常会遇到丢包、带宽不够等情况,因此,服务提供商就需要在遵守公共开源的协议下进行调优。于是,融云在音视频的用户规模、网络质量、通信链路以及接口等方面进行了开发和优化,保证了音视频的质量以及技术的易用性。

虽然业界有标准的协议以及开源的框架,但是,对于音视频和即时通讯领域的自研开发还是有门槛的。杨攀表示,首先是成本问题,包括团队成员的组建和投入,需要组织大量人力来完成;其次是时间的投入,在如今互联网竞争激烈的时代,时间不等人,需要快速开发出稳定可用的产品或功能;第三,规模问题,当用户量激增或业务扩张时,系统不稳定有可能导致功能不可用,从而流失用户。融云基于多年的积累,满足市面上绝大部分的客户需求,并将开发者需要的功能和能力封装成接口,甚至提供了标准化的 UI 界面,帮助开发者快速完成自己的产品功能研发。

通信云技术发展多年,未来会有哪些发展趋势呢?杨攀表示,通信云的发展过程是相对循序渐进的。随着 5G 的到来,互联网通信基础设施质量也逐步提升,更多的变化则是场景的创新应用,功能丰富度,以及产品接口的易用性。未来,融云也会重点以平台为依托,在场景应用、产品功能、基础设施和接口等方面,全方位提升能力,赋能开发者。

懂程序员的产品经理是什么样子?

IM即时通讯王叫兽 发表了文章 • 0 个评论 • 124 次浏览 • 2020-09-16 10:36 • 来自相关话题

在互联网行业,产品经理和程序员之间的关系很微妙。表面看上去水火不容,在一方的眼里看另外一方总是有这样那样的问题,相互吐槽。但现实是,大家都知道和对方在同一条船上。产品没做好的话,除了公司利益受损,产品经理和程序员也会各回各家各找各妈,重新找新工作去。产品做得好... ...查看全部

在互联网行业,产品经理和程序员之间的关系很微妙。表面看上去水火不容,在一方的眼里看另外一方总是有这样那样的问题,相互吐槽。但现实是,大家都知道和对方在同一条船上。

产品没做好的话,除了公司利益受损,产品经理和程序员也会各回各家各找各妈,重新找新工作去。

产品做得好的话,双方和睦相处、其乐融融?那是不可能的,这个辈子都不可能和睦相处。矛盾会更加严重……(都觉得自己功不可没)

所以Z哥就想来聊聊产品经理和程序员之间的协作问题。不管你是产品经理还是程序员,都应该找到与对方打交道的好方法。好的方法必然是寻求双赢的,而不是一个零和博弈。

这个主题会分别从不同的两个视角展开,今天我们先聊程序员视角,本来想两个视角一起聊,发现内容太多,写到一半还是拆了,先把一个视角写了。

如果你是程序员可以看看以下这些描述是你眼中的产品经理么?

如果你是产品经理可以看看从程序员起家的Z哥给出的一些建议。

程序员吐槽产品经理最多的原因主要是以下几个(以下内容可能会引起程序员们的极度舒适~):

  1. 开发过程中频繁修改需求。

  2. 验收过程中要求做比较大的修改。

  3. 说不清楚需求的价值

  4. 替程序员评估工作量

  5. 需求整理的不够细。

其中,频繁修改需求是程序员们最反感的,这是毋庸置疑的。

从产品经理的角度来说,虽然无法100%在开发过程中不修改需求,但是如果前期的工作做得足够充分,与业务方的沟通足够到位,至少去掉“频繁”两个字还是很有可能的。我甚至遇到过一些产品经理,在自己对业务都是一知半解的时候就开始整需求了,这必然会导致后续频繁的需求变更。

第二,验收过程中要求做比较大的修改。此时往往会伴随一句短语——“这不是我要的”。每当程序员听到这6个字的时候,脑子里是一万头草泥马奔过……

产生这个情况的原因有很多。可能是程序员理解偏差,也有可能是产品觉得功能效果不佳。但是大多数时候,产生这个情况的根本原因还是在需求评审阶段的沟通不够充分,双方之间并没有达成真正的共识。

但是如果要说什么时候双方的矛盾最激烈,那还不是修改需求的时候,而是需求评审的时候。

此时,很容易看到的一个景象是“讨价还价”。产品经理站在「价值」一方,程序员站在「成本」一方。当程序员们追问某个他们不认同的功能时,如果产品经理无法阐述出该功能令人信服的价值,那么必然受到吐槽。这是原因三。

原因四,有些产品经理是从程序员转过去的,之前做过一两年的开发工作。这个时长的经验其实是很危险的,很容易陷入到「达克效应」的第一阶段:高估自己的技术能力,低估他人的技术能力和工作难度。这会导致不管是明面上还是私底下会不自然地去评估程序员的工期是否合理,甚至会在需求评审的时候替程序员预估时间,如果高于自己的预估,便会认为他们偷懒。

最后一点。相信每个人程序员都提出过这样的问题“这里如果……,那么要怎么处理?”。这种就是需求考虑不够细致的体现。不过,要做好这点的确挺难的,这也是产品经理花费时间最多的地方。

聊了这么多场景,作为产品经理应该如何应对呢?

从思路上分为以下几步。

01

先明确大方向,并与程序员达成一致。

正如前面所提到的,产品经理站在「价值」方,程序员站在「成本」方,这注定了他们是对立的。最坏的结果就是双方互掐,就算相对好的结果也只是相互妥协做一个半吊子的功能(用系统的人不太舒服)。

但如果你的视野更大,格局更高,就会发现,如果以「投入产出比」角度来切入,双方不但都能理解,而且很容达成共识,毕竟花最小的成本干价值最大的活,是个正常人都能理解和认可不是么。

所以,可以在日常工作中不断的强化这个共识。一旦出现争执,就从这个角度来做最终决定,甚至基于这慢慢地还能建立起相互的信任,程序员真正拥有了产品思维,产品经理真正懂了程序员的难处。

02

将产品经理范畴内的事情做到极致。

所谓术业有专攻,与其相互吐槽,不如多花点时间把对方吐槽的地方做到极致。

03

有时候你虽然做的很好,想的也很仔细,但是还是会出现无法说服程序员认可你方案的情况。这是因为我们每个人本身都会存在「确认偏误」现象。

确认偏误是指搜寻,解释,偏爱和回想确认或支持一个人先前信念或价值观的信息的倾向。会导致对个人信念的过度自信,并且在面对相反的证据时可以保持或加强信念。

维基百科

所以,运用一些沟通技巧显得至关重要。只要一件事不是单凭一个人就能完成,你就得考虑如何提高协作效率。而产品经理和程序员的协作中,沟通又是最重要的。

下面展开说说具体可以做的一些事。主要是思路中的2和3。

01 提高专业性

我观察过一个现象,需求变更比较多的产品经理,他们的工作习惯往往是直接抄起原型工具就画原型,或者有很多工作时间在原型工具里。

这样非常容易陷入到一个思维惯性里面去,就是过于关注交互层面的事情,而轻视了背后业务流程的设计,甚至是业务的合理性。

我认为产品经理做事的时候一定要以User Story为核心来展开,先构思好一个User Story,然后就是把它真实发生的各种细节阐述清楚。做这事的过程先后分为以下四步:

  1. 定义User Story

  2. 定义交付标准

  3. 提供低保真原型

  4. 编写Use Case

这里面最费时费力的就是第四环节。并且,你想把User Story阐述清楚离不开一个专业的 Use Case编写。我之前收藏了一个非常专业的Use Case模版,是从知乎上的张恂老师那看到的,你感受一下。

用例名称:提问 
层次:!(用户目标层) 
范围:问答网站(以下简称系统) 
主用角:注册用户(以下简称用户) 
其他干系者:...
后态: 
前态:用户已登录。 
触发事件:用户选择提问。 
基本流:1. 系统显示新建问题框。 
输入问题 { 
2. 用户输入问题陈述(字数限制?);系统即时验证输入的有效性,并提示已有答案的类似问题(数量?)以免重复提问。 
3. 用户设定该问题的相关话题。 
4. 可选项 
用户可补充输入问题说明(背景、条件等详细信息)。 
5. 可选项 
…… 
6. 用户提交问题。 

7. 系统验证该问题的有效性。 
8. 系统发布该问题,并显示该问题页面。 
 扩展流:用户放弃提问:...
https://www.zhihu.com/question/48899115/answer/113274323 张恂老师的回答。

作为产品经理的你,如果想要减少被程序员吐槽需求不够细,或者降低开发过程中变更需求的频次,把use case用心做好是必不可少的。

02 沟通方面

与程序员的沟通方面,我总结了五动作,分别是「齐、拉、捧、说、谦」,可以根据情况组合出击。

「齐」就是视角对齐的意思。在聊需求之前,先交代需求的背景、意义。特别在中途需求变更的时候,这点非常重要。

继续搬出之前用过好几次的图。

640.jpg

如果视角不同,你说接下去还怎么聊?

「拉」是拉拢的意思。亚里士多德说过:

我们无法通过智力去影响别人,而情感却能做到这一点。

亚里士多德

所以,在沟通的时候要把程序员当作自己人看待,而不是敌对。比如,可以多用“我们”,“一起”等词语,进入一个协商的氛围。举个例子:“我们一起来看下这个问题”。少用”我觉得“、”我认为“;

「捧」是吹捧的意思,但并不是简单的拍马屁。

人都是有多面性的,针对不同的情况和场景,可能会表现出不同的特质,这会影响到双方的沟通。比如有的人在生活中很温和,但在工作时非常严苛,要求很高,这就是激发了不同的特质。

类似的,为了激活程序员的积极性,你可以在当下需要他发挥的地方吹捧一下。比如,你觉得某个程序员做的东西质量一般,小问题比较多。那么你在和他聊的时候特地捧一句,“我知道做程序员的都或多或少有完美主义倾向,对细节很关注。我这个功能设计的细节可是想了好久呢,不过对你来说应该很容易搞定吧。”

「说」是说服的意思。想要让对方从心底里的认同你,单凭打感情牌可不行。所以需要多用数据和用户反馈来提高你观点的可信度。

重视数据的产品经理有可能是优秀的产品经理,但不重视数据的产品经理一定不是优秀的产品经理。因为要看得懂数据的前提是得懂业务,并且还不能仅仅懂个皮毛。比如,

你得知道哪些环节产生的数据是关键。

多个数据之间的间接关系和影响是什么。

你设计的每一个功能会如何影响这些数据。

……

心里一直有着这些概念,程序员还会吐槽你提的需求价值低?

「让」是谦让的意思。俗话说,“三个臭皮匠顶一个诸葛亮”。可以给程序员留有表达他们观点的空间。

原因有两点。

大多数的产品设计背后有很多的知识是通用知识,每个人的生活经历都能成为经验。而每个人的生活经历又是不同的。

专业不同,哪怕站的视角相同,看到的同一个事物也会有些差别。用高端的说法叫“看到的本质不同”。基于这个本质出发,提出的观点可能会让你眼前一亮。

以上就是「齐、拉、捧、说、谦」五点。最后再送给你一句话:非必要情况,一定不要用“这是老板的要求“!,重复,重复。重要的事情说三遍。

还有一些比较成熟的方法体系也能改善产品和开发之间共识达成问题。比如,在领域驱动设计范畴中Event Storming。它就非常适合在前期的需求评审环节去使用。

感兴趣的可以自行了解。

好了,总结一下。

这篇呢,Z哥和你分享了我对产品经理如何更好地与程序员达成共识这件事的看法。

思路上分为三步:

  1. 先明确大方向,并与程序员达成一致。

  2. 将产品经理范畴内的事情做到极致

  3. 运用一些沟通技巧解决「确认偏误」现象。

关于第二点,给出的具体措施是。以User Story为核心,做好Use Case的编写工作,而不是花很多时间在原型上。

关于第三点,总结了五个动作,分别是「齐、拉、捧、说、谦」,可以根据情况组合出击。

希望对你有所帮助。

作者:Z哥,公众号“跨界架构师” 

为什么有 HTTPS?因为 HTTP 不安全!

IM即时通讯王叫兽 发表了文章 • 0 个评论 • 107 次浏览 • 2020-09-15 17:24 • 来自相关话题

为什么有 HTTPS?因为 HTTP 不安全! 现在的互联网已经不再是 " 田园时代 "," 黑暗森林 " 已经到来。上网的记录会被轻易截获,网站是否真实也无法验证,黑客可以伪装成银行网站,盗取真实姓名、密码、银行卡等敏... ...查看全部

u=1241929776,2696424852&fm=26&gp=0.jpg

为什么有 HTTPS?因为 HTTP 不安全! 现在的互联网已经不再是 " 田园时代 "," 黑暗森林 " 已经到来。上网的记录会被轻易截获,网站是否真实也无法验证,黑客可以伪装成银行网站,盗取真实姓名、密码、银行卡等敏感信息,威胁人身安全和财产安全。

上网的时候必须步步为营、处处小心,否则就会被不知道埋伏在哪里的黑客所 " 猎杀 "。

HTTPS 如何实现安全通信?如何构建出固若金汤的网络城堡?主要涉及的知识点如下:

了解什么是 HTTPS

什么样的才是安全的通信

对称加密与非对称加密、摘要算法、数字签名、完整性校验到底是什么

迁移 HTTPS 的必要性

什么是安全

做事要稳,老司机【码哥字节】开车要安全!不管是戴杜蕾斯还是安全气囊," 安全至关重要 "!

在通信过程中,具备以下特性则认为安全:机密性、完整性、不可否认、身份认证。

机密性

数据必须保密,只能有信任的人读取,其他人是不可见的秘密。诸葛亮的密报总不能让司马懿知道呀,不然还玩个蛋。通俗的说:就是不能让不相关的人看到不该看的东西。

完整性

也叫作一致性,也就是数据在传输过程中没有被非法篡改,内容不能多也不能少,一五一十的保持原状。

打个比方,原本张无忌说:" 赵敏,么么哒。",传信的飞鸽被周芷若抓到了,截取了消息,改成了 " 赵敏,去死吧!"。这么子搞,倚天屠龙记可能就会被改写了。

不可否认

也就做不可抵赖,不能否认已经发生过的事情。所谓 " 君子一言,驷马难追 "。" 老懒 " 这种事情不能发生。

就像尹志平亲密接触了小龙女,事后一直隐瞒否认,装作不知道,这是万万不可的。所以最终就嗝屁了。

身份验证

也就是确认对方的真实身份," 证明你是真的是你 ",保证消息发送到可信的人,而不是非法之徒。

比如令狐冲写了一份情书给任盈盈:" 盈盈,冲哥哥爱你哟 ",但是岳不群看到快递小哥,冒充是令狐冲,截取了情书后回复:" 傻逼,白日做梦 "。令狐冲不知道这是岳不群的回复,以为是任盈盈的,笑傲江湖又要重写了……

所以同时具备了机密性、完整性、身份认证、不可够人四个特性,通信双方的安全才有保证,才是真正的安全。

什么是 HTTPS

到这里,终于轮到 HTTPS 上台了,也就是它为 HTTP 增加了刚刚说的四大安全特性。

HTTPS 其实是一个 " 非常简单 " 的协议,规定了新的协议名 "https",默认端口号 443,至于其他的什么请求 - 应答模式、报文结构、请求方法、URI、头字段、连接管理等等都完全沿用 HTTP,没有任何新的东西。唯一的差别就是端口号不同、去掉明文传输。

那 HTTPS 凭啥就变得安全了呢?

就是因为他在 TCP/IP 与 HTTP 之间加上了 SSL/TLS ,从原来的 HTTP over TCP/IP 变成了 HTTP over SSL/TLS,让 HTTP 运行在 安全的 SSL/TLS 协议上,安全开车。

http 与 https

所以重点就是去掌握 SSL/TLS 到底是什么玩意成就了安全。

SSL/TLS

SSL 即安全套接层(Secure Sockets Layer),在 OSI 模型中处于第 5 层(会话层),由网景公司于 1994 年发明,有 v2 和 v3 两个版本,而 v1 因为有严重的缺陷从未公开过。

SSL 发展到 v3 时已经证明了它自身是一个非常好的安全通信协议,于是互联网工程组 IETF 在 1999 年把它改名为 TLS(传输层安全,Transport Layer Security),正式标准化,版本号从 1.0 重新算起,所以 TLS1.0 实际上就是 SSLv3.1。

TLS 由记录协议、握手协议、警告协议、变更密码规范协议、扩展协议等几个子协议组成,综合使用了对称加密、非对称加密、身份认证等许多密码学前沿技术。

浏览器与服务器在使用 TLS 建立连接的时候实际上就是选了一组加密算法实现安全通信,这些算法组合叫做 " 密码套件(cipher suite)"。

套件命名很有规律,比如 "ECDHE-RSA-AES256-GCM-SHA384"。按照 密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法 " 组成的 .

所以这个套件的意思就是:使用 ECDHE 算法进行密钥交换,使用 RSA 签名和身份验证,握手后使用 AES 对称加密,密钥长度 256 位,分组模式 GCM,消息认证和随机数生成使用摘要算法 SHA384。

对称加密与非对称加密

前面提到四个实现安全的必要条件,先说 机密性,也就是消息只能给想给的人看到并且看得懂。

实现机密性的手段就是 加密(encrypt),也就是将原本明文消息使用加密算法转换成别人看不懂的密文,只有掌握特有的 密钥 的人才能解密出原始内容。就好像是诸葛亮将发给关二爷密报的内容通过一种转换算法转成其他的内容,司马懿看不懂。关二爷持有解密该内容的关键钥匙。

钥匙也就是 密钥(key),未加密的消息叫做 明文 (plain text/clear text),加密后的内容叫做 密文(cipher text),通过密钥解密出原文的过程叫做 解密(decrypt),而加解密的整个过程就是 加密算法。

由于 HTTPS、TLS 都运行在计算机上,所以 " 密钥 " 就是一长串的数字,但约定俗成的度量单位是 " 位 "(bit),而不是 " 字节 "(byte)。比如,说密钥长度是 128,就是 16 字节的二进制串,密钥长度 1024,就是 128 字节的二进制串。

加密算法通常有两大类:对称加密和非对称加密。

对称加密

加密和解密使用的密钥都是同一个,是 " 对称的 "。双方只要保证不会有泄露其他人知道这个密钥,通信就具有机密性。


对称加密算法常见的有 RC4、DES、3DES、AES、ChaCha20 等,但前三种算法都被认为是不安全的,通常都禁止使用,目前常用的只有 AES 和 ChaCha20。


AES 的意思是 " 高级加密标准 "(Advanced Encryption Standard),密钥长度可以是 128、192 或 256。它是 DES 算法的替代者,安全强度很高,性能也很好,而且有的硬件还会做特殊优化,所以非常流行,是应用最广泛的对称加密算法。

加密分组模式

对称算法还有一个 " 分组模式 " 的概念,目的是通过算法用固定长度的密钥加密任意长度的明文。

最新的分组模式被称为 AEAD(Authenticated Encryption with Associated Data),在加密的同时增加了认证的功能,常用的是 GCM、CCM 和 Poly1305。

非对称加密

有对称加密,为何还搞出一个非对称加密呢?

对称加密确实解决了机密性,只有相关的人才能读取出信息。但是最大的问题是:如何安全的把密钥传递对方,专业术语 " 密钥交换 "。

这个很容易理解,对称加密的密钥在飞鸽传书过程中被打鸟的敌军捕获窃取,那

么就能随意加解密收发作战密报数据了,诸葛亮的密报没有机密可言。

所以非对称加密诞生了。

由两个密钥组成,分别是 公钥(public key) 和 " 私钥(private key)",两个密钥是不一样的,这也就是不对称的由来,公钥可以任何人使用,私钥则自己保密。

这里需要注意的是:公钥和私钥都可以用来加密解密,公钥加密的密文只能用私钥解密,反之亦然。

服务端保存私钥,在互联网上分发公钥,当访问服务器网站的时候使用授予的公钥加密明文即可,服务端则使用对应的私钥来解密。敌军没有私钥也就无法破解密文了。


非对称加密


TLS 中常见的加密算法有 DH、RSA、ECC、DSA 等。其中的 RSA 最常用,它的安全性基于 " 整数分解 " 的数学难题,使用两个超大素数的乘积作为生成密钥的材料,想要从公钥推算出私钥是非常困难的。

ECC(Elliptic Curve Cryptography)是非对称加密里的 " 后起之秀 ",它基于 " 椭圆曲线离散对数 " 的数学难题,使用特定的曲线方程和基点生成公钥和私钥,子算法 ECDHE 用于密钥交换,ECDSA 用于数字签名。

比起 RSA,ECC 在安全强度和性能上都有明显的优势。160 位的 ECC 相当于 1024 位的 RSA,而 224 位的 ECC 则相当于 2048 位的 RSA。因为密钥短,所以相应的计算量、消耗的内存和带宽也就少,加密解密的性能就上去了,对于现在的移动互联网非常有吸引力。

现在我们为了机密性从对称加密到非对称加密,而非对称加密还解决了密钥交换不安全的问题。那么是否可以直接使用非对称加密来实现机密性呢?

答案是否定的!

因为非对称加密运算速度比较慢。所以需要两者结合,混合模式实现机密性问题,同时又有很好的性能。

加密流程如下所示:

先创建一个随机数的对称加密密钥,会话密钥(session key);

使用会话密钥加密需要传输的明文消息,因为对称加密性能较好,接着再使用非对称加密的公钥对会话密钥加密,因为会话密钥很短,通常只有 16 字节或 32 字节,所以加密也不会太慢。这里主要就是解决了非对称加密的性能问题,同时实现了会话密钥的机密交换。

另一方接收到密文后使用非对称加密的私钥解密出上一步加密的 会话密钥,接着使用会话密钥解密出加密的消息明文。


混合加密


总结一下就是使用非对称加密算法来加密会话密钥,使用对称加密算法来加密消息明文,接收方则使用非对称加密算法的私钥解密出会话密钥,再利用会话密钥解密消息密文。

这样混合加密就解决了对称加密算法的密钥交换问题,而且安全和性能兼顾,完美地实现了机密性。

后面还有完整性、身份认证、不可否认等特性没有实现,所以现在的通信还不是绝对安全。

摘要算法与完整性

摘要算法的主要目的就是实现完整性,通过常见的散列函数、哈希函数实现。

我们可以简单理解成这事一种特殊的压缩算法,将任意长度的明文数据处理成固定长度、又是独一无二的 " 摘要 " 字符串,就是该数据的指纹。

同时摘要算法是单向加密算法,没有密钥,加密后的数据也无法解密,也就是不能从 " 摘要 " 推导出明文。

比如我们听过或者用过的 MD5(Message-Digest 5)、SHA-1(Secure Hash Algorithm 1),它们就是最常用的两个摘要算法,能够生成 16 字节和 20 字节长度的数字摘要。

完整性实现

有了摘要算法生成的数字摘要,那么我们只需要在明文数据附上对应的摘要,就能保证数据的完整性。

但是由于摘要算法不具有机密性,不能明文传输,否则黑客可以修改消息后把摘要也一起改了,网站还是鉴别不出完整性。

所以完整性还是要建立在机密性上,我们结合之前提到的混合加密使用 " 会话密钥 " 加密明文消息 + 摘要,这样的话黑客也就无法得到明文,无法做修改了。这里有个专业术语叫 " 哈希消息认证码(HMAC)"。


哈希消息认证码(HMAC)


比如诸葛亮使用上面提到的混合加密过程给关二爷发消息:" 明天攻城 " + "SHA-

2 摘要 ",关二爷收到后使用密钥将解密出来的会话密钥解密出明文消息,同时对明文消息使用解密出来的摘要算法进行摘要计算,接着比对两份 " 摘要 " 字符串是否一致,如果一致就说明消息完整可信,没有被敌军修改过。

消息被修改是很危险的,要以史为鉴,比如赵高与李斯伪造遗诏,直接把扶苏给送西天了,这太可怕了。

总结下就是通过摘要比对防止篡改,同时利用混合加密实现密文与摘要的安全传输。

数字签名和 CA

到这里已经很安全了,但是还是有漏洞,就是通信的两头。黑客可以伪装成网站来窃取信息。而反过来,他也可以伪装成你,向网站发送支付、转账等消息,网站没有办法确认你的身份,钱可能就这么被偷走了。

现在如何实现身份认证呢?

现实生活中,解决身份认证的手段是签名和印章,只要在纸上写下签名或者盖个章,就能够证明这份文件确实是由本人而不是其他人发出的。

非对称加密依然可以解决此问题,只不过跟之前反过来用,使用私钥再加上摘要算法,就能够实现 " 数字签名 ",同时实现 " 身份认证 " 和 " 不可否认 "。

就是把公钥私钥的用法反过来,之前是公钥加密、私钥解密,现在是私钥加密、公钥解密。但又因为非对称加密效率太低,所以私钥只加密原文的摘要,这样运算量就小的多,而且得到的数字签名也很小,方便保管和传输。

重点就是使用非对称加密的 " 私钥 " 加密原文的摘,对方则使用非对称加密的公钥解密出摘要,再比对解密出的原文通过摘要算法计算摘要与解密出的摘要比对是否一致。这样就能像签署文件一样证明消息确实是你发送的。


签名验签


只要你和网站互相交换公钥,就可以用 " 签名 " 和 " 验签 " 来确认消息的真实性,因为私钥保密,黑客不能伪造签名,就能够保证通信双方的身份。

到这里似乎已经大功告成,可惜还不是。

综合使用对称加密、非对称加密和摘要算法,我们已经实现了安全的四大特性,是不是已经完美了呢?

不是的,这里还有一个 " 公钥的信任 " 问题。因为谁都可以发布公钥,我们还缺少防止黑客伪造公钥的手段,也就是说,怎么来判断这个公钥就是你或者张三丰的公钥呢?

这个 " 第三方 " 就是我们常说的 CA(Certificate Authority,证书认证机构)。它就像网络世界里的公安局、教育部、公证中心,具有极高的可信度,由它来给各个公钥签名,用自身的信誉来保证公钥无法伪造,是可信的。

CA 对公钥的签名认证也是有格式的,不是简单地把公钥绑定在持有者身份上就完事了,还要包含序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证明公钥关联的各种信息,形成 " 数字证书 "(Certificate)。

OpenSSL

它是一个著名的开源密码学程序库和工具包,几乎支持所有公开的加密算法和协议,已经成为了事实上的标准,许多应用软件都会使用它作为底层库来实现 TLS 功能,包括常用的 Web 服务器 Apache、Nginx 等。

由于 OpenSSL 是开源的,所以它还有一些代码分支,比如 Google 的 BoringSSL、OpenBSD 的 LibreSSL,这些分支在 OpenSSL 的基础上删除了一些老旧代码,也增加了一些新特性,虽然背后有 " 大金主 ",但离取代 OpenSSL 还差得很远。

总结下就是:OpenSSL 是著名的开源密码学工具包,是 SSL/TLS 的具体实现。

迁移 HTTPS 必要性

如果你做移动应用开发的话,那么就一定知道,Apple、Android、某信等开发平台在 2017 年就相继发出通知,要求所有的应用必须使用 HTTPS 连接,禁止不安全的 HTTP。

在台式机上,主流的浏览器 Chrome、Firefox 等也早就开始 " 强推 "HTTPS,把 HTTP 站点打上 " 不安全 " 的标签,给用户以 " 心理压力 "。

Google 等搜索巨头还利用自身的 " 话语权 " 优势,降低 HTTP 站点的排名,而给 HTTPS 更大的权重,力图让网民只访问到 HTTPS 网站。

这些手段都逐渐 " 挤压 " 了纯明文 HTTP 的生存空间," 迁移到 HTTPS" 已经不是 " 要不要做 " 的问题,而是 " 要怎么做 " 的问题了。HTTPS 的大潮无法阻挡,如果还是死守着 HTTP,那么无疑会被冲刷到互联网的角落里。

顾虑

阻碍 HTTPS 实施的因素还有一些这样、那样的顾虑,我总结出了三个比较流行的观点:" 慢、贵、难 "。

而 " 慢 " 则是惯性思维,拿以前的数据来评估 HTTPS 的性能,认为 HTTPS 会增加服务器的成本,增加客户端的时延,影响用户体验。

其实现在服务器和客户端的运算能力都已经有了很大的提升,性能方面完全没有担心的必要,而且还可以应用很多的优化解决方案。

所谓 " 贵 ",主要是指证书申请和维护的成本太高,网站难以承担。

这也属于惯性思维,在早几年的确是个问题,向 CA 申请证书的过程不仅麻烦,而且价格昂贵,每年要交几千甚至几万元。

但现在就不一样了,为了推广 HTTPS,很多云服务厂商都提供了一键申请、价格低廉的证书,而且还出现了专门颁发免费证书的 CA,其中最著名的就是 "Let ’ s Encrypt"。

所谓的 " 难 ",是指 HTTPS 涉及的知识点太多、太复杂,有一定的技术门槛,不能很快上手。

总结

从什么是安全我们延展出 HTTPS,解释了什么是 HTTPS,以及与 HTTP 的区别。HTTPS 主要就是通过 SSL/TLS 实现安全,而安全我们又接触了什么是对称加密与非对称加密,非对称加密性能较弱,所以我们使用非对称加密来加密对称加密的 " 会话密钥 ",利用会话密钥加密明文解决了性能问题。

通过混合加密实现了机密性,利用摘要算法实现了完整性,通过数字签名使用非对称加密的 " 私钥 " 加密原文的摘要,对方则使用非对称加密的公钥解密出摘要,再比对解密出的原文通过摘要算法计算摘要与解密出的摘要比对是否一致实现了身份认证与不可否认。


文章来源于码哥字节 ,作者 MageByte 技术团队

如何用JAVA设计一个亿级消息量的 IM 系统

IM即时通讯大兴 发表了文章 • 0 个评论 • 81 次浏览 • 2020-09-11 11:01 • 来自相关话题

本文不会给出一套通用的IM方案,也不会评判某种架构的好坏,而是讨论设计IM系统的常见难题跟业界的解决方案。因为也没有所谓的通用方案,不同的解决方案都有其优缺点,只有最满足业务的系统才是一个好的系统。而且,在有限的人力、物力跟时间资源下,通常需要做出很多权衡,此... ...查看全部

本文不会给出一套通用的IM方案,也不会评判某种架构的好坏,而是讨论设计IM系统的常见难题跟业界的解决方案。因为也没有所谓的通用方案,不同的解决方案都有其优缺点,只有最满足业务的系统才是一个好的系统。而且,在有限的人力、物力跟时间资源下,通常需要做出很多权衡,此时,一个能够快速迭代、方便扩展的系统才是一个好的系统。

 

IM核心概念

用户:系统的使用者

消息:是指用户之间的沟通内容。通常在IM系统中,消息会有以下几类:文本消息、表情消息、图片消息、视频消息、文件消息等等

会话:通常指两个用户之间因聊天而建立起的关联

群:通常指多个用户之间因聊天而建立起的关联

终端:指用户使用IM系统的机器。通常有Android端、iOS端、Web端等等

未读数:指用户还没读的消息数量

用户状态:指用户当前是在线、离线还是挂起等状态

关系链:是指用户与用户之间的关系,通常有单向的好友关系、双向的好友关系、关注关系等等。这里需要注意与会话的区别,用户只有在发起聊天时才产生会话,但关系并不需要聊天才能建立。对于关系链的存储,可以使用图数据库(Neo4j等等),可以很自然地表达现实世界中的关系,易于建模

单聊:一对一聊天

群聊:多人聊天

客服:在电商领域,通常需要对用户提供售前咨询、售后咨询等服务。这时,就需要引入客服来处理用户的咨询

消息分流:在电商领域,一个店铺通常会有多个客服,此时决定用户的咨询由哪个客服来处理就是消息分流。通常消息分流会根据一系列规则来确定消息会分流给哪个客服,例如客服是否在线(客服不在线的话需要重新分流给另一个客服)、该消息是售前咨询还是售后咨询、当前客服的繁忙程度等等

信箱:本文的信箱我们指一个Timeline、一个收发消息的队列

 

读扩散 vs 写扩散

读扩散

我们先来看看读扩散。如上图所示,A与每个聊天的人跟群都有一个信箱(有些博文会叫Timeline),A在查看聊天信息的时候需要读取所有有新消息的信箱。这里的读扩散需要注意与Feeds系统的区别,在Feeds系统中,每个人都有一个写信箱,写只需要往自己的写信箱里写一次就好了,读需要从所有关注的人的写信箱里读。但IM系统里的读扩散通常是每两个相关联的人就有一个信箱,或者每个群一个信箱。

读扩散的优点:

写操作(发消息)很轻量,不管是单聊还是群聊,只需要往相应的信箱写一次就好了

每一个信箱天然就是两个人的聊天记录,可以方便查看聊天记录跟进行聊天记录的搜索

读扩散的缺点:

读操作(读消息)很重

写扩散

接下来看看写扩散。

e38c316470c48ab4e7f8492ec20398672f5e14.jpg.png

在写扩散中,每个人都只从自己的信箱里读取消息,但写(发消息)的时候,对于单聊跟群聊处理如下:

单聊:往自己的信箱跟对方的信箱都写一份消息,同时,如果需要查看两个人的聊天历史记录的话还需要再写一份(当然,如果从个人信箱也能回溯出两个人的所有聊天记录,但这样效率会很低)。

群聊:需要往所有的群成员的信箱都写一份消息,同时,如果需要查看群的聊天历史记录的话还需要再写一份。可以看出,写扩散对于群聊来说大大地放大了写操作。

写扩散优点:

读操作很轻量

可以很方便地做消息的多终端同步

写扩散缺点:

写操作很重,尤其是对于群聊来说

注意,在Feeds系统中:

写扩散也叫:Push、Fan-out或者Write-fanout

读扩散也叫:Pull、Fan-in或者Read-fanout

 

唯一ID设计

通常情况下,ID的设计主要有以下几大类:

UUID

基于Snowflake的ID生成方式

基于申请DB步长的生成方式

基于Redis或者DB的自增ID生成方式

特殊的规则生成唯一ID

具体的实现方法跟优缺点可以参考之前的一篇博文:分布式唯一 ID 解析

在IM系统中需要唯一Id的地方主要是:

会话ID

消息ID

 

消息ID

我们来看看在设计消息ID时需要考虑的三个问题。

 

消息ID不递增可以吗

我们先看看不递增的话会怎样:

使用字符串,浪费存储空间,而且不能利用存储引擎的特性让相邻的消息存储在一起,降低消息的写入跟读取性能

使用数字,但数字随机,也不能利用存储引擎的特性让相邻的消息存储在一起,会加大随机IO,降低性能;而且随机的ID不好保证ID的唯一性

因此,消息ID最好是递增的。

 

全局递增 vs 用户级别递增 vs 会话级别递增

全局递增:指消息ID在整个IM系统随着时间的推移是递增的。全局递增的话一般可以使用Snowflake(当然,Snowflake也只是worker级别的递增)。此时,如果你的系统是读扩散的话为了防止消息丢失,那每一条消息就只能带上上一条消息的ID,前端根据上一条消息判断是否有丢失消息,有消息丢失的话需要重新拉一次。

用户级别递增:指消息ID只保证在单个用户中是递增的,不同用户之间不影响并且可能重复。典型代表:微信。如果是写扩散系统的话信箱时间线ID跟消息ID需要分开设计,信箱时间线ID用户级别递增,消息ID全局递增。如果是读扩散系统的话感觉使用用户级别递增必要性不是很大。

会话级别递增:指消息ID只保证在单个会话中是递增的,不同会话之间不影响并且可能重复。典型代表:QQ。

 

连续递增 vs 单调递增

连续递增是指ID按 1,2,3...n 的方式生成;而单调递增是指只要保证后面生成的ID比前面生成的ID大就可以了,不需要连续。

据我所知,QQ的消息ID就是在会话级别使用的连续递增,这样的好处是,如果丢失了消息,当下一条消息来的时候发现ID不连续就会去请求服务器,避免丢失消息。此时,可能有人会想,我不能用定时拉的方式看有没有消息丢失吗?当然不能,因为消息ID只在会话级别连续递增的话那如果一个人有上千个会话,那得拉多少次啊,服务器肯定是抗不住的。

对于读扩散来说,消息ID使用连续递增就是一种不错的方式了。如果使用单调递增的话当前消息需要带上前一条消息的ID(即聊天消息组成一个链表),这样,才能判断消息是否丢失。

总结一下就是:

写扩散:信箱时间线ID使用用户级别递增,消息ID全局递增,此时只要保证单调递增就可以了

读扩散:消息ID可以使用会话级别递增并且最好是连续递增

 

会话ID

我们来看看设计会话ID需要注意的问题:

其中,会话ID有种比较简单的生成方式(特殊的规则生成唯一ID):拼接 from_user_id 跟 to_user_id:

如果 from_user_id 跟 to_user_id 都是32位整形数据的话可以很方便地用位运算拼接成一个64位的会话ID,即: conversation_id = ${from_user_id} << 32 | ${to_user_id} (在拼接前需要确保值比较小的用户ID是 from_user_id,这样任意两个用户发起会话可以很方便地知道会话ID)

如果from_user_id 跟 to_user_id 都是64位整形数据的话那就只能拼接成一个字符串了,拼接成字符串的话就比较伤了,浪费存储空间性能又不好。

前东家就是使用的上面第1种方式,第1种方式有个硬伤:随着业务在全球的扩展,32位的用户ID如果不够用需要扩展到64位的话那就需要大刀阔斧地改了。32位整形ID看起来能够容纳21亿个用户,但通常我们为了防止别人知道真实的用户数据,使用的ID通常不是连续的,这时,32位的用户ID就完全不够用了。因此,该设计完全依赖于用户ID,不是一种可取的设计方式。

因此,会话ID的设计可以使用全局递增的方式,加一个映射表,保存from_user_id、to_user_id跟conversation_id的关系。

 

推模式 vs 拉模式 vs 推拉结合模式

在IM系统中,新消息的获取通常会有三种可能的做法:

推模式:有新消息时服务器主动推给所有端(iOS、Android、PC等)

拉模式:由前端主动发起拉取消息的请求,为了保证消息的实时性,一般采用推模式,拉模式一般用于获取历史消息

推拉结合模式:有新消息时服务器会先推一个有新消息的通知给前端,前端接收到通知后就向服务器拉取消息

推模式简化图如下:

04cfb696364aeffcfdd83382d29a45bfefb11a.jpg.png

如上图所示,正常情况下,用户发的消息经过服务器存储等操作后会推给接收方的所有端。但推是有可能会丢失的,最常见的情况就是用户可能会伪在线(是指如果推送服务基于长连接,而长连接可能已经断开,即用户已经掉线,但一般需要经过一个心跳周期后服务器才能感知到,这时服务器会错误地以为用户还在线;伪在线是本人自己想的一个概念,没想到合适的词来解释)。因此如果单纯使用推模式的话,是有可能会丢失消息的。

推拉结合模式简化图如下:

6760f5926b20f8763ec72480c1328e859795dd.jpg.png

可以使用推拉结合模式解决推模式可能会丢消息的问题。在用户发新消息时服务器推送一个通知,然后前端请求最新消息列表,为了防止有消息丢失,可以再每隔一段时间主动请求一次。可以看出,使用推拉结合模式最好是用写扩散,因为写扩散只需要拉一条时间线的个人信箱就好了,而读扩散有N条时间线(每个信箱一条),如果也定时拉取的话性能会很差。

 

业界解决方案

前面了解了IM系统的常见设计问题,接下来我们再看看业界是怎么设计IM系统的。研究业界的主流方案有助于我们深入理解IM系统的设计。以下研究都是基于网上已经公开的资料,不一定正确,大家仅作参考就好了。

微信

虽然微信很多基础框架都是自研,但这并不妨碍我们理解微信的架构设计。从微信公开的《从0到1:微信后台系统的演进之路》这篇文章可以看出,微信采用的主要是:写扩散 + 推拉结合。由于群聊使用的也是写扩散,而写扩散很消耗资源,因此微信群有人数上限(目前是500)。所以这也是写扩散的一个明显缺点,如果需要万人群就比较难了。

从文中还可以看出,微信采用了多数据中心架构:

 62f39582378e16672d3132062133f47142ce8e.jpg.png

 


微信每个数据中心都是自治的,每个数据中心都有全量的数据,数据中心间通过自研的消息队列来同步数据。为了保证数据的一致性,每个用户都只属于一个数据中心,只能在自己所属的数据中心进行数据读写,如果用户连了其它数据中心则会自动引导用户接入所属的数据中心。而如果需要访问其它用户的数据那只需要访问自己所属的数据中心就可以了。同时,微信使用了三园区容灾的架构,使用Paxos来保证数据的一致性。

从微信公开的《万亿级调用系统:微信序列号生成器架构设计及演变》这篇文章可以看出,微信的ID设计采用的是:基于申请DB步长的生成方式 + 用户级别递增。如下图所示:

1.png

微信的序列号生成器由仲裁服务生成路由表(路由表保存了uid号段到AllocSvr的全映射),路由表会同步到AllocSvr跟Client。如果AllocSvr宕机的话会由仲裁服务重新调度uid号段到其它AllocSvr。

 

钉钉

钉钉公开的资料不多,从《阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处》这篇文章我们只能知道,钉钉最开始使用的是写扩散模型,为了支持万人群,后来貌似优化成了读扩散。

但聊到阿里的IM系统,不得不提的是阿里自研的Tablestore。一般情况下,IM系统都会有一个自增ID生成系统,但Tablestore创造性地引入了主键列自增,即把ID的生成整合到了DB层,支持了用户级别递增(传统MySQL等DB只能支持表级自增,即全局自增)。具体可以参考:《如何优化高并发IM系统架构》

 

Twitter

什么?Twitter不是Feeds系统吗?这篇文章不是讨论IM的吗?是的,Twitter是Feeds系统,但Feeds系统跟IM系统其实有很多设计上的共性,研究下Feeds系统有助于我们在设计IM系统时进行参考。再说了,研究下Feeds系统也没有坏处,扩展下技术视野嘛。

Twitter的自增ID设计估计大家都耳熟能详了,即大名鼎鼎的Snowflake,因此ID是全局递增的。


从这个视频分享《How We Learned to Stop Worrying and Love Fan-In at Twitter》可以看出,Twitter一开始使用的是写扩散模型,Fanout Service负责扩散写到Timelines Cache(使用了Redis),Timeline Service负责读取Timeline数据,然后由API Services返回给用户。

但由于写扩散对于大V来说写的消耗太大,因此后面Twitter又使用了写扩散跟读扩散结合的方式。如下图所示:



 2.png

对于粉丝数不多的用户如果发Twitter使用的还是写扩散模型,由Timeline Mixer服务将用户的Timeline、大V的写Timeline跟系统推荐等内容整合起来,最后再由API Services返回给用户。

 

58到家

58到家实现了一个通用的实时消息平台:

3.png

可以看出,msg-server保存了应用跟MQ主题之间的对应关系,msg-server根据这个配置将消息推到不同的MQ队列,具体的应用来消费就可以了。因此,新增一个应用只需要修改配置就可以了。

58到家为了保证消息投递的可靠性,还引入了确认机制:消息平台收到消息先落地数据库,接收方收到后应用层ACK再删除。使用确认机制最好是只能单点登录,如果多端能够同时登录的话那就比较麻烦了,因为需要所有端都确认收到消息后才能删除。

看到这里,估计大家已经明白了,设计一个IM系统很有挑战性。我们还是继续来看设计一个IM系统需要考虑的问题吧。

 

IM需要解决的问题

如何保证消息的实时性

在通信协议的选择上,我们主要有以下几个选择:

使用TCP Socket通信,自己设计协议:58到家等等

使用UDP Socket通信:QQ等等

使用HTTP长轮循:微信网页版等等

不管使用哪种方式,我们都能够做到消息的实时通知。但影响我们消息实时性的可能会在我们处理消息的方式上。例如:假如我们推送的时候使用MQ去处理并推送一个万人群的消息,推送一个人需要2ms,那么推完一万人需要20s,那么后面的消息就阻塞了20s。如果我们需要在10ms内推完,那么我们推送的并发度应该是:人数:10000 / (推送总时长:10 / 单个人推送时长:2) = 2000

因此,我们在选择具体的实现方案的时候一定要评估好我们系统的吞吐量,系统的每一个环节都要进行评估压测。只有把每一个环节的吞吐量评估好了,才能保证消息推送的实时性。

如何保证消息时序

以下情况下消息可能会乱序:

发送消息如果使用的不是长连接,而是使用HTTP的话可能会出现乱序。因为后端一般是集群部署,使用HTTP的话请求可能会打到不同的服务器,由于网络延迟或者服务器处理速度的不同,后发的消息可能会先完成,此时就产生了消息乱序。解决方案:

前端依次对消息进行处理,发送完一个消息再发送下一个消息。这种方式会降低用户体验,一般情况下不建议使用。

带上一个前端生成的顺序ID,让接收方根据该ID进行排序。这种方式前端处理会比较麻烦一点,而且聊天的过程中接收方的历史消息列表中可能会在中间插入一条消息,这样会很奇怪,而且用户可能会漏读消息。但这种情况可以通过在用户切换窗口的时候再进行重排来解决,接收方每次收到消息都先往最后面追加。

通常为了优化体验,有的IM系统可能会采取异步发送确认机制(例如:QQ)。即消息只要到达服务器,然后服务器发送到MQ就算发送成功。如果由于权限等问题发送失败的话后端再推一个通知下去。这种情况下MQ就要选择合适的Sharding策略了:

按to_user_id进行Sharding:使用该策略如果需要做多端同步的话发送方多个端进行同步可能会乱序,因为不同队列的处理速度可能会不一样。例如发送方先发送m1然后发送m2,但服务器可能会先处理完m2再处理m1,这里其它端会先收到m2然后是m1,此时其它端的会话列表就乱了。

按conversation_id进行Sharding:使用该策略同样会导致多端同步会乱序。

按from_user_id进行Sharding:这种情况下使用该策略是比较好的选择

通常为了优化性能,推送前可能会先往MQ推,这种情况下使用to_user_id才是比较好的选择。

用户在线状态如何做

很多IM系统都需要展示用户的状态:是否在线,是否忙碌等。主要可以使用Redis或者分布式一致性哈希来实现用户在线状态的存储。

看上面的图可能会有人疑惑,为什么每次心跳都需要更新Redis?如果我使用的是TCP长连接那是不是就不用每次心跳都更新了?确实,正常情况下服务器只需要在新建连接或者断开连接的时候更新一下Redis就好了。但由于服务器可能会出现异常,或者服务器跟Redis之间的网络会出现问题,此时基于事件的更新就会出现问题,导致用户状态不正确。因此,如果需要用户在线状态准确的话最好通过心跳来更新在线状态。

由于Redis是单机存储的,因此,为了提高可靠性跟性能,我们可以使用Redis Cluster或者Codis。

使用分布式一致性哈希需要注意在对Status Server Cluster进行扩容或者缩容的时候要先对用户状态进行迁移,不然在刚操作时会出现用户状态不一致的情况。同时还需要使用虚拟节点避免数据倾斜的问题。

 

多端同步怎么做

读扩散

前面也提到过,对于读扩散,消息的同步主要是以推模式为主,单个会话的消息ID顺序递增,前端收到推的消息如果发现消息ID不连续就请求后端重新获取消息。但这样仍然可能丢失会话的最后一条消息,为了加大消息的可靠性,可以在历史会话列表的会话里再带上最后一条消息的ID,前端在收到新消息的时候会先拉取最新的会话列表,然后判断会话的最后一条消息是否存在,如果不存在,消息就可能丢失了,前端需要再拉一次会话的消息列表;如果会话的最后一条消息ID跟消息列表里的最后一条消息ID一样,前端就不再处理。这种做法的性能瓶颈会在拉取历史会话列表那里,因为每次新消息都需要拉取后端一次,如果按微信的量级来看,单是消息就可能会有20万的QPS,如果历史会话列表放到MySQL等传统DB的话肯定抗不住。因此,最好将历史会话列表存到开了AOF(用RDB的话可能会丢数据)的Redis集群。这里只能感慨性能跟简单性不能兼得。

 

写扩散

对于写扩散来说,多端同步就简单些了。前端只需要记录最后同步的位点,同步的时候带上同步位点,然后服务器就将该位点后面的数据全部返回给前端,前端更新同步位点就可以了。

如何处理未读数

在IM系统中,未读数的处理非常重要。未读数一般分为会话未读数跟总未读数,如果处理不当,会话未读数跟总未读数可能会不一致,严重降低用户体验。

读扩散

对于读扩散来说,我们可以将会话未读数跟总未读数都存在后端,但后端需要保证两个未读数更新的原子性跟一致性,一般可以通过以下两种方法来实现:

使用Redis的multi事务功能,事务更新失败可以重试。但要注意如果你使用Codis集群的话并不支持事务功能。

使用Lua嵌入脚本的方式。使用这种方式需要保证会话未读数跟总未读数都在同一个Redis节点(Codis的话可以使用Hashtag)。这种方式会导致实现逻辑分散,加大维护成本。

写扩散

对于写扩散来说,服务端通常会弱化会话的概念,即服务端不存储历史会话列表。未读数的计算可由前端来负责,标记已读跟标记未读可以只记录一个事件到信箱里,各个端通过重放该事件的形式来处理会话未读数。使用这种方式可能会造成各个端的未读数不一致,至少微信就会有这个问题。

如果写扩散也通过历史会话列表来存储未读数的话那用户时间线服务跟会话服务紧耦合,这个时候需要保证原子性跟一致性的话那就只能使用分布式事务了,会大大降低系统的性能。

如何存储历史消息

读扩散

对于读扩散,只需要按会话ID进行Sharding存储一份就可以了。

 

写扩散

对于写扩散,需要存储两份:一份是以用户为Timeline的消息列表,一份是以会话为Timeline的消息列表。以用户为Timeline的消息列表可以用用户ID来做Sharding,以会话为Timeline的消息列表可以用会话ID来做Sharding。

 

数据冷热分离

对于IM来说,历史消息的存储有很强的时间序列特性,时间越久,消息被访问的概率也越低,价值也越低。如果我们需要存储几年甚至是永久的历史消息的话(电商IM中比较常见),那么做历史消息的冷热分离就非常有必要了。数据的冷热分离一般是HWC(Hot-Warm-Cold)架构。对于刚发送的消息可以放到Hot存储系统(可以用Redis)跟Warm存储系统,然后由Store Scheduler根据一定的规则定时将冷数据迁移到Cold存储系统。获取消息的时候需要依次访问Hot、Warm跟Cold存储系统,由Store Service整合数据返回给IM Service。

 

接入层怎么做

实现接入层的负载均衡主要有以下几个方法:

硬件负载均衡:例如F5、A10等等。硬件负载均衡性能强大,稳定性高,但价格非常贵,不是土豪公司不建议使用。

使用DNS实现负载均衡:使用DNS实现负载均衡比较简单,但使用DNS实现负载均衡如果需要切换或者扩容那生效会很慢,而且使用DNS实现负载均衡支持的IP个数有限制、支持的负载均衡策略也比较简单。

DNS + 4层负载均衡 + 7层负载均衡架构:例如 DNS + DPVS + Nginx 或者 DNS + LVS + Nginx。有人可能会疑惑为什么要加入4层负载均衡呢?这是因为7层负载均衡很耗CPU,并且经常需要扩容或者缩容,对于大型网站来说可能需要很多7层负载均衡服务器,但只需要少量的4层负载均衡服务器即可。因此,该架构对于HTTP等短连接大型应用很有用。当然,如果流量不大的话只使用DNS + 7层负载均衡即可。但对于长连接来说,加入7层负载均衡Nginx就不大好了。因为Nginx经常需要改配置并且reload配置,reload的时候TCP连接会断开,造成大量掉线。

DNS + 4层负载均衡:4层负载均衡一般比较稳定,很少改动,比较适合于长连接。

对于长连接的接入层,如果我们需要更加灵活的负载均衡策略或者需要做灰度的话,那我们可以引入一个调度服务,如下图所示:

 4.png

Access Schedule Service可以实现根据各种策略来分配Access Service,例如:

根据灰度策略来分配

根据就近原则来分配

根据最少连接数来分配

 

架构心得

最后,分享一下做大型应用的架构心得:

灰度!灰度!灰度!

监控!监控!监控!

告警!告警!告警!

缓存!缓存!缓存!

限流!熔断!降级!

低耦合,高内聚!

避免单点,拥抱无状态!

评估!评估!评估!

压测!压测!压测!

 

来源:InfoQ 


手把手教学实现消息通信

IM即时通讯王叫兽 发表了文章 • 2 个评论 • 117 次浏览 • 2020-09-09 10:09 • 来自相关话题

一、背景作为一名 Web 开发者,在日常工作中,经常都会遇到消息通信的场景。比如实现组件间通信、实现插件间通信、实现不同的系统间通信。那么针对这些场景,我们应该怎么实现消息通信呢?本文阿宝哥将带大家一起来学习如何优雅的实现消息通信。好的,接下来我们马上步入正题... ...查看全部

一、背景

作为一名 Web 开发者,在日常工作中,经常都会遇到消息通信的场景。比如实现组件间通信、实现插件间通信、实现不同的系统间通信。那么针对这些场景,我们应该怎么实现消息通信呢?本文阿宝哥将带大家一起来学习如何优雅的实现消息通信。

好的,接下来我们马上步入正题,这里阿宝哥以一个文章订阅的例子来拉开本文的序幕。小秦与小王是阿宝哥的两个好朋友,他们在阿宝哥的 “全栈修仙之路” 博客中发现了 TS 专题文章,刚好他们近期也打算系统地学习 TS,所以他们就开启了 TS 的学习之旅。

时间就这样过了半个月,小秦和小王都陆续找到了阿宝哥,说 “全栈修仙之路” 博客上的 TS 文章都差不多学完了,他们有空的时候都会到 “全栈修仙之路” 博客上查看是否有新发的 TS 文章。他们觉得这样挺麻烦的,看能不能在阿宝哥发完新的 TS 文章之后,主动通知他们。


好友提的建议,阿宝哥怎能拒绝呢?所以阿宝哥分别跟他们说:“我会给博客加个订阅的功能,功能发布后,你填写一下邮箱地址。以后发布新的 TS 文章,系统会及时给你发邮件”。此时新的流程如下图所示:

在阿宝哥的一顿 “操作” 之后,博客的订阅功能上线了,阿宝哥第一时间通知了小秦与小王,让他们填写各自的邮箱。之后,每当阿宝哥发布新的 TS 文章,他们就会收到新的邮件通知了。

阿宝哥是个技术宅,对新的技术也很感兴趣。在遇到 Deno 之后,阿宝哥燃起了学习 Deno 的热情,同时也开启了新的 Deno 专题。在写了几篇 Deno 专题文章之后,两个读者小池和小郭分别联系到我,说他们看到了阿宝哥的 Deno 文章,想跟阿宝哥一起学习 Deno。

在了解他们的情况之后,阿宝哥突然想到了之前小秦与小王提的建议。因此,又是一顿 “操作” 之后,阿宝哥为了博客增加了专题订阅功能。该功能上线之后,阿宝哥及时联系了小池和小郭,邀请他们订阅 Deno 专题。之后小池和小郭也成为了阿宝哥博客的订阅者。现在的流程变成这样:

这个例子看起来很简单,但它背后却与一些设计思想和设计模式相关联。因此,接下来阿宝哥将分析以上三个场景与软件开发中一些设计思想和设计模式的关联性。

二、场景与模式

2.1 消息轮询模式

在第一个场景中,小秦和小王为了能查看阿宝哥新发的 TS 文章,他们需要不断地访问 “全栈修仙之路” 博客:

这个场景跟软件开发过程中的轮询模式类似。早期,很多网站为了实现推送技术,所用的技术都是轮询。轮询是指由浏览器每隔一段时间向服务器发出 HTTP 请求,然后服务器返回最新的数据给客户端。常见的轮询方式分为轮询与长轮询,它们的区别如下图所示:

这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而 HTTP 请求与响应可能会包含较长的头部,其中真正有效的数据可能只是很小的一部分,所以这样会消耗很多带宽资源。为了解决上述问题 HTML5 定义了 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

WebSocket 是一种网络传输协议,可在单个 TCP 连接上进行全双工通信,位于 OSI 模型的应用层。WebSocket 协议在 2011 年由 IETF 标准化为 RFC 6455,后由 RFC 7936 补充规范。

既然已经提到了 OSI(Open System Interconnection Model)模型,这里阿宝哥来分享一张很生动、很形象描述 OSI 模型的示意图:

(图片来源:https://www.networkingsphere.com/2019/07/what-is-osi-model.html)

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输。

介绍完轮询和 WebSocket 的相关内容之后,接下来我们来看一下 XHR Polling 与 WebSocket 之间的区别:

对于 XHR Polling 与 WebSocket 来说,它们分别对应了消息通信的两种模式,即 Pull(拉)模式与 Push(推)模式:

场景一我们就介绍到这里,对轮询和 WebSocket 感兴趣的小伙伴可以阅读阿宝哥写的 “你不知道的 WebSocket” 这一篇文章。下面我们来继续分析第二个场景。

2.2 观察者模式

在第二个场景中,为了让小秦和小王能及时收到阿宝哥新发布的 TS 文章,阿宝哥给博客增加了订阅功能。这里假设阿宝哥博客一开始只发布 TS 专题的文章。

针对这个场景,我们可以考虑使用设计模式中观察者模式来实现上述功能。观察者模式,它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。

在观察者模式中有两个主要角色:Subject(主题)和 Observer(观察者)。

在第二个场景中,Subject(主题)就是阿宝哥的 TS 专题文章,而观察者就是小秦和小王。由于观察者模式支持简单的广播通信,当消息更新时,会自动通知所有的观察者。因此对于第二个场景,我们可以考虑使用观察者设计模式来实现上述的功能。接下来,我们来继续分析第三个场景。

2.3 发布订阅模式

在第三个场景中,为了让小池和小郭能及时收到阿宝哥新发布的 Deno 文章,阿宝哥给博客增加了专题订阅功能。即支持为阿宝哥博客的订阅者分别推送新发布的 TS 或 Deno 文章。

针对这个场景,我们可以考虑使用发布订阅模式来实现上述功能。在软件架构中,发布 — 订阅是一种消息范式,消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,然后分别发送给不同的订阅者。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者存在。

在发布订阅模式中有三个主要角色:Publisher(发布者)、 Channels(通道)和 Subscriber(订阅者)。

在第三个场景中,Publisher(发布者)是阿宝哥,Channels(通道)中 Topic A 和 Topic B 分别对应于 TS 专题和 Deno 专题,而 Subscriber(订阅者)就是小秦、小王、小池和小郭。好的,了解完发布订阅模式,下面我们来介绍一下它的一些应用场景。

三、发布订阅模式的应用

3.1 前端框架中模块/页面间消息通信

在一些主流的前端框架中,内部也会提供用于模块间或页面间通信的组件。比如在 Vue 框架中,我们可以通过 new Vue() 来创建 EventBus 组件。而在 Ionic 3 中我们可以使用 ionic-angular 模块中的 Events 组件来实现模块间或页面间的消息通信。下面我们来分别介绍在 Vue 和 Ionic 中如何实现模块/页面间的消息通信。

3.1.1 Vue 使用 EventBus 进行消息通信

在 Vue 中我们可以通过创建 EventBus 来实现组件间或模块间的消息通信,使用方式很简单。在下图中包含两个 Vue 组件:Greet 和 Alert 组件。Alert 组件用于显示消息,而 Greet 组件中包含一个按钮,即下图中 ”显示问候消息“ 的按钮。当用户点击按钮时,Greet 组件会通过 EventBus 把消息传递给 Alert 组件,该组件接收到消息后,会调用 alert 方法把收到的消息显示出来。

以上示例对应的代码如下:

main.js

Vue.prototype.$bus = new Vue();

Alert.vue


<script>
export default {
  name: "alert",
  created() {
    // 监听alert:message事件
    this.$bus.$on("alert:message", msg => {
      this.showMessage(msg);
    });
  },
  methods: {
    showMessage(msg) {
      alert(msg);
    },
  },
  beforeDestroy: function() {
    // 组件销毁时,移除alert:message事件监听
    this.$bus.$off("alert:message");
  }
}
</script>

Greet.vue


<template>
  <div>
    <button @click="greet(message)">显示问候信息</button>
  </div>
</template>
 
<script>
export default {
  name: "Greet",
  data() {
    return {
      message: "大家好,我是阿宝哥",
    };
  },
  methods: {
    greet(msg) {
      this.$bus.$emit("alert:message", msg);
    }
  }
};
</script>

3.1.2 Ionic 使用 Events 组件进行消息通信

在 Ionic 3 项目中,要实现页面间消息通信很简单。我们只要通过构造注入的方式注入 ionic-angular 模块中提供的 Events 组件即可。具体的使用示例如下所示:

import { Events } from 'ionic-angular';
 
// first page (publish an event when a user is created)
constructor(public events: Events) {}
createUser(user) {
  console.log('User created!')
  this.events.publish('user:created', user, Date.now());
}
 
 
// second page (listen for the user created event after function is called)
constructor(public events: Events) {
  events.subscribe('user:created', (user, time) => {
    // user and time are the same arguments passed in `events.publish(user, time)`
    console.log('Welcome', user, 'at', time);
  });
}

介绍完发布订阅模式在 Vue 和 Ionic 框架中的应用之后,接下来阿宝哥将介绍该模式在微内核架构中是如何实现插件通信的。

3.2 微内核架构中插件通信

微内核架构(Microkernel Architecture),有时也被称为插件化架构(Plug-in Architecture),是一种面向功能进行拆分的可扩展性架构,通常用于实现基于产品的应用。微内核架构模式允许你将其他应用程序功能作为插件添加到核心应用程序,从而提供可扩展性以及功能分离和隔离。

微内核架构模式包括两种类型的架构组件:核心系统(Core System)和插件模块(Plug-in modules)。应用逻辑被分割为独立的插件模块和核心系统,提供了可扩展性、灵活性、功能隔离和自定义处理逻辑的特性。


对于微内核的核心系统设计来说,它涉及三个关键技术:插件管理、插件连接和插件通信,这里我们重点来分析一下插件通信。

插件通信是指插件间的通信。虽然设计的时候插件间是完全解耦的,但实际业务运行过程中,必然会出现某个业务流程需要多个插件协作,这就要求两个插件间进行通信;由于插件之间没有直接联系,通信必须通过核心系统,因此核心系统需要提供插件通信机制。

这种情况和计算机类似,计算机的 CPU、硬盘、内存、网卡是独立设计的配置,但计算机运行过程中,CPU 和内存、内存和硬盘肯定是有通信的,计算机通过主板上的总线提供了这些组件之间的通信功能。

下面阿宝哥将以基于微内核架构设计的西瓜播放器为例,介绍它的内部是如何提供插件通信机制。在西瓜播放器内部,定义了一个 Player 类来创建播放器实例:


let player = new Player({
  id: 'mse',
  url: '//abc.com/**/*.mp4'
});

Player 类继承于 Proxy 类,而在 Proxy 类内部会通过构造继承的方式继承 EventEmitter 事件派发器:


import EventEmitter from 'event-emitter'
 
class Proxy {
  constructor (options) {
    this._hasStart = false;
    // 省略大部分代码
    EventEmitter(this);
  }
}

所以我们创建的西瓜播放器也是一个事件派发器,利用它就可以实现插件的通信。为了让大家能够更好地理解具体的通信流程,我们以内置的 poster 插件为例,来看一下它内部如何使用事件派发器。

poster 插件用于在播放器播放音视频前显示海报图,该插件的使用方式如下:


new Player({
  el:document.querySelector('#mse'),
  url: 'video_url',
  poster: '//abc.com/**/*.png' // 默认值""
});

poster 插件的对应源码如下:


import Player from '../player'
 
let poster = function () {
  let player = this; 
  let util = Player.util
  let poster = util.createDom('xg-poster', '', {}, 'xgplayer-poster');
  let root = player.root
  if (player.config.poster) {
    poster.style.backgroundImage = `url(${player.config.poster})`
    root.appendChild(poster)
  }
 
  // 监听播放事件,播放时隐藏封面图
  function playFunc () {
    poster.style.display = 'none'
  }
  player.on('play', playFunc)
 
  // 监听销毁事件,执行清理操作
  function destroyFunc () {
    player.off('play', playFunc)
    player.off('destroy', destroyFunc)
  }
  player.once('destroy', destroyFunc)
}
 
Player.install('poster', poster)

(https://github.com/bytedance/xgplayer/blob/master/packages/xgplayer/src/control/poster.js)

通过观察源码可知,在注册 poster 插件时,会把播放器实例注入到插件中。之后,在插件内部会使用 player 这个事件派发器来监听播放器的 play 和 destroy 事件。当 poster 插件监听到播放器的 play 事件之后,就会隐藏海报图。而当 poster 插件监听到播放器的 destroy 事件时,就会执行清理操作,比如移除已绑定的事件。

看到这里我们就已经很清楚了,西瓜播放器内部使用 EventEmitter 来提供插件通信机制,每个插件都会注入 player 这个全局的事件派发器,通过它就可以轻松地实现插件间通信了。

提到 EventEmitter,相信很多小伙伴对它并不会陌生。在 Node.js 中有一个名为 events 的内置模块,通过它我们可以方便地实现一个自定义的事件派发器,比如:


const EventEmitter = require('events');
 
class MyEmitter extends EventEmitter {}
 
const myEmitter = new MyEmitter();
 
myEmitter.on('event', () => {
  console.log('大家好,我是阿宝哥!');
});
 
myEmitter.emit('event');

3.3 基于 Redis 实现不同系统间通信

在前面我们介绍了发布订阅模式在单个系统中的应用。其实,在日常开发过程中,我们也会遇到不同系统间通信的问题。接下来阿宝哥将介绍如何利用 Redis 提供的发布与订阅功能实现系统间的通信,不过在介绍具体应用前,我们得先熟悉一下 Redis 提供的发布与订阅功能。

3.3.1 Redis 发布与订阅功能

Redis 订阅功能

通过 Redis 的 subscribe 命令,我们可以订阅感兴趣的通道,其语法为:SUBSCRIBE channel [channel …]。


➜  ~ redis-cli
127.0.0.1:6379> subscribe deno ts
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "deno"
3) (integer) 1
1) "subscribe"
2) "ts"
3) (integer) 2

在上述命令中,我们通过 subscribe 命令订阅了 deno 和 ts 两个通道。接下来我们新开一个命令行窗口,来测试 Redis 的发布功能。

Redis 发布功能

通过 Redis 的 publish 命令,我们可以为指定的通道发布消息,其语法为:PUBLISH

channel message。
➜  ~ redis-cli
127.0.0.1:6379> publish ts "
pub/sub design mode"

当成功发布消息之后,订阅该通道的客户端就会收到消息,对应的控制台就会输出如下信息:


1) "message"
2) "ts"
3) "pub/sub design mode"

了解完 Redis 的发布与订阅功能,接下来阿宝哥将介绍如何利用 Redis 提供的发布与订阅功能实现不同系统间的通信。

3.3.2 实现不同系统间的通信

这里我们使用 Node.js 的 Express 框架和 redis 模块来快速搭建不同的 Web 应用,首先创建一个新的 Web 项目并安装一下相关的依赖:


$ npm init --yes
$ npm install express redis

接着创建一个发布者应用:

publisher.js


const redis = require("redis");
const express = require("express");
 
const publisher = redis.createClient();
 
const app = express();
 
app.get("/", (req, res) => {
  const article = {
    id: "666",
    name: "TypeScript实战之发布订阅模式",
  };
 
  publisher.publish("ts", JSON.stringify(article));
  res.send("阿宝哥写了一篇TS文章");
});
 
app.listen(3005, () => {
  console.log(`server is listening on PORT 3005`);
});

然后分别创建两个订阅者应用:

subscriber-1.js


const redis = require("redis");
const express = require("express");
 
const subscriber = redis.createClient();
 
const app = express();
 
subscriber.on("message", (channel, message) => {
  console.log("小王收到了阿宝哥的TS文章: " + message);
});
 
subscriber.subscribe("ts");
 
app.get("/", (req, res) => {
  res.send("我是阿宝哥的粉丝,小王");
});
 
app.listen(3006, () => {
  console.log("server is listening to port 3006");
});

subscriber-2.js


const redis = require("redis");
const express = require("express");
 
const subscriber = redis.createClient();
 
// https://dev.to/ganeshmani/implementing-redis-pub-sub-in-node-js-application-12he
const app = express();
 
subscriber.on("message", (channel, message) => {
  console.log("小秦收到了阿宝哥的TS文章: " + message);
});
 
subscriber.subscribe("ts");
 
app.get("/", (req, res) => {
  res.send("我是阿宝哥的粉丝,小秦");
});
 
app.listen(3007, () => {
  console.log("server is listening to port 3007");
});

接着分别启动上面的三个应用,当所有应用都成功启动之后,在浏览器中访问 http://localhost:3005/ 地址,此时上面的两个订阅者应用对应的终端会分别输出以下信息:

subscriber-1.js


server is listening to port 3006
小王收到了阿宝哥的TS文章: {"id":"666","name":"TypeScript实战之发布订阅模式"}

subscriber-2.js


server is listening to port 3007
小秦收到了阿宝哥的TS文章: {"id":"666","name":"TypeScript实战之发布订阅模式"}

以上示例对应的通信流程如下图所示:

到这里发布订阅模式的应用场景,已经介绍完了。最后,阿宝哥来介绍一下如何使用 TS 实现一个支持发布与订阅功能的 EventEmitter 组件。

四、发布订阅模式实战

4.1 定义 EventEmitter 类


type EventHandler = (...args: any[]) => any;
 
class EventEmitter {
  private c = new Map<string, EventHandler[]>();
 
  // 订阅指定的主题
  subscribe(topic: string, ...handlers: EventHandler[]) {
    let topics = this.c.get(topic);
    if (!topics) {
      this.c.set(topic, topics = []);
    }
    topics.push(...handlers);
  }
 
  // 取消订阅指定的主题
  unsubscribe(topic: string, handler?: EventHandler): boolean {
    if (!handler) {
      return this.c.delete(topic);
    }
 
    const topics = this.c.get(topic);
    if (!topics) {
      return false;
    }
    
    const index = topics.indexOf(handler);
 
    if (index < 0) {
      return false;
    }
    topics.splice(index, 1);
    if (topics.length === 0) {
      this.c.delete(topic);
    }
    return true;
  }
 
  // 为指定的主题发布消息
  publish(topic: string, ...args: any[]): any[] | null {
    const topics = this.c.get(topic);
    if (!topics) {
      return null;
    }
    return topics.map(handler => {
      try {
        return handler(...args);
      } catch (e) {
        console.error(e);
        return null;
      }
    });
  }
}

4.2 使用示例


const eventEmitter = new EventEmitter();
eventEmitter.subscribe("ts", (msg) => console.log(`收到订阅的消息:${msg}`) );
 
eventEmitter.publish("ts", "TypeScript发布订阅模式");
eventEmitter.unsubscribe("ts");
eventEmitter.publish("ts", "TypeScript发布订阅模式");

以上代码成功运行之后,控制台会输出以下信息:

收到订阅的消息:TypeScript发布订阅模式

五、参考资源

维基百科 - 发布/订阅

Ionic 3 - Events

implementing-redis-pub-sub-in-node-js-application

原文地址https://blog.csdn.net/qiwoo_weekly/article/details/108250534


【开源项目】对Jenkinsfile语法说不,Jenkins Json Build挺你

IM即时通讯antrue 发表了文章 • 0 个评论 • 89 次浏览 • 2020-09-08 10:37 • 来自相关话题

项目背景我所在的组织项目数量众多,使用的语言和框架也很多,比如Java、ReactNative、C# .NET、Android、iOS等,部署环境也是多种多样比如Tomcat、K8S、IIS、客户端应用是局域网内企业证书安装等,我们没有专门的配置管理员或构建部... ...查看全部

项目背景

我所在的组织项目数量众多,使用的语言和框架也很多,比如Java、ReactNative、C# .NET、Android、iOS等,部署环境也是多种多样比如Tomcat、K8S、IIS、客户端应用是局域网内企业证书安装等,我们没有专门的配置管理员或构建部署专员,都是开发人员自己在Jenkins中写构建脚本,每个项目都有自己的构建脚本(Scripted Pipelines),但类型相同的项目比如都是Java或都是.NET项目之间,构建脚本其实都很类似,都是靠几个已存在的构建脚本改写出来的,其实开发人员对编写Jenkins构建脚本了解也不多,另外因为没有规则和约束,更没有代码复用的机制,构建部署工作很混乱和难以管理。

项目解决的问题

在上述情况下我们开发了Jenkins-Json-Build项目,该项目适合于有一些编程经验的人员在不需要了解Jenkins构建脚本如何编写的情况下,通过简单的配置Json文件,就可以轻松完成一个项目的获取源码、单元测试、代码检查、编译构建、部署等步骤,实现一个典型的CI过程,又因为此项目使用了Jenkins共享类库(Shared Libraries)机制,构建脚本复用率得到了大幅度提高,并且开发人员可以方便的扩展更多的功能,满足不同构建部署场景的需要,此项目非常适合那些开发人员自己管理构建部署的团队,通过Jenkins-Json-Build项目组织对构建部署过程进行了统一的管理和监督,又让每个项目有足够的灵活性和自主权满足各自项目构建部署的特殊性。

一个Java项目构建示例

构建服务器上需要安装Java、Maven和Sonar-Scanner(此项可选)

  • JAVA安装

  • Maven安装

  • Sonar-Scanner

构建需要依赖的Jenkins插件

  • JUnit

  • JaCoCo

完善Jenkinsfile 文件内容

因为采用pipeline script from SCM构建方式,所以用Declarative Pipeline方式在Jenkinsfile中编写构建脚本:

@Library('shared-library') _

pipeline {
  agent any
  parameters { //定义构建参数
    choice choices: ['-'], description: '请选择部署方式', name: 'deploy-choice'
  }
  stages {
    stage('初始化') {
      steps {
        script{
          //加载源码仓库根目录下的jenkins-project.json构建配置文件
          runWrapper.loadJSON('/jenkins-project.json')
          runWrapper.runSteps('初始化')
        }
      }
    }
    stage('单元测试') {
      steps {
        script{
          //执行单元测试步骤
          runWrapper.runSteps('单元测试')
        }
      }
    }
    stage('代码检查') {
      steps {
        script{
          //执行代码检查步骤,比如SonarQube
          runWrapper.runSteps('代码检查')
        }
      }
    }
    stage('编译构建') {
      steps {
        script{
          //执行编译步骤
          runWrapper.runSteps('编译构建')
        }
      }
    }
    stage('部署') {
      steps {
        script{
          //根据选择的部署方式执行部署步骤
          runWrapper.runStepForEnv('部署','deploy-choice')
        }
      }
    }
  }
}


上述Jenkinsfile文件可用于所有类型的项目构建,实际使用的时候一般还会用到以下三个Jenkins插件:

  • Agent Server Parameter Plugin 用于选择构建的Agent服务器

  • Custom Checkbox Parameter Plugin 用于选择子项目进行构建,多用于微服务项目

  • Git Parameter 用于选择分支构建

JSON配置文件内容

{
  "初始化": {
    "检查Java环境": {
      "Type": "COMMAND_STDOUT",
      "Success-IndexOf": "java version \"1.8.0_211\"",
      "Script": {
        "输出Java版本": "java -version 2>&1"
      }
    },
    "检查Maven环境": {
      "Type": "COMMAND_STDOUT",
      "Success-IndexOf": "Apache Maven 3.6.3",
      "Script": {
        "输出Maven版本": "mvn -v"
      }
    },
    "检查SonarScanner环境": {
      "Type": "COMMAND_STDOUT",
      "Success-IndexOf": "SonarScanner 4.4.0.2170",
      "Script": {
        "输出SonarScanner版本": "sonar-scanner -v"
      }
    },
    "绑定构建参数": {
      "Type": "BUILD_PARAMETER_DROP_DOWN_MENU",
      "StepsName": "部署",
      "ParamName": "deploy-choice"
    }
  },
  "单元测试": {
    "执行Maven单元测试脚本": {
      "Type": "COMMAND_STATUS",
      "Script": {
        "Maven单元测试": "cd ${PROJECT_PATH};mvn clean test"
      }
    },
    "执行JUnit插件": {
      "Type": "JUNIT_PLUG_IN",
      "JunitReportPath": "**/${PROJECT_DIR}/**/target/**/TEST-*.xml"
    },
    "执行Jacoco插件": {
      "Type": "JACOCO_PLUG_IN",
      "classPattern":"${PROJECT_PATH}/target/classes",
      "InclusionPattern":"${PROJECT_PATH}/**",
      "LineCoverage":"95",
      "InstructionCoverage":"0",
      "MethodCoverage":"100",
      "BranchCoverage":"95",
      "ClassCoverage":"100",
      "ComplexityCoverage":"0"
    }
  },
  "代码检查": {
    "执行SQ代码扫描": {
      "Type": "SONAR_QUBE"
    }
  },
  "编译构建": {
    "执行Maven构建": {
      "Type": "COMMAND_STATUS",
      "Script": {
        "Maven构建": "cd ${PROJECT_PATH};mvn clean package -U -DskipTests"
      }
    }
  },
  "部署": {
    "模拟部署脚本-1": {
      "Type": "COMMAND_STATUS",
      "Script": {
        "拷贝文件": "echo 模拟拷贝文件"
      }
    },
    "模拟部署脚本-2": {
      "Type": "COMMAND_STATUS",
      "Script": {
        "HTTP传输文件": "echo HTTP传输文件"
      }
    }
  }
}

配置说明:

"检查Java环境": {
      "Type": "COMMAND_STDOUT",
      "Success-IndexOf": "java version \"1.8.0_211\"",
      "Script": {
        "输出Java版本": "java -version 2>&1"
      }
   }

该类型的节点不是必须的(但看几年前写的配置文件时很有用,对需要的构建环境一目了然),目的是检查构建服务器是否具备需要的构建环境,在命令的标准输出内未含有Success-IndexOf节点定义的字符串则执行失败,对应的另一个节点名称是Fail-IndexOf,标准输出如果含有Fail-IndexOf定义的字符串则执行失败,两者选择其一使用。

"绑定构建参数": {
      "Type": "BUILD_PARAMETER_DROP_DOWN_MENU",
      "StepsName": "部署",
      "ParamName": "deploy-choice"
    }

将部署节点(Steps)内的具体构建步骤(Step)列表,绑定到名为deploy-choice的下拉菜单构建参数上。

"执行JUnit插件": {
      "Type": "JUNIT_PLUG_IN",
      "JunitReportPath": "**/${PROJECT_DIR}/**/target/**/TEST-*.xml"
    }

使用Jenkins的JUnit插件生成Junit和TestNG的测试报告。

"执行Jacoco插件": {
      "Type": "JACOCO_PLUG_IN",
      "classPattern":"${PROJECT_PATH}/target/classes",
      "InclusionPattern":"${PROJECT_PATH}/**",
      "LineCoverage":"95",
      "InstructionCoverage":"0",
      "MethodCoverage":"100",
      "BranchCoverage":"95",
      "ClassCoverage":"100",
      "ComplexityCoverage":"0"
    }

使用Jenkins的Jacoco插件检查单元测试覆盖度。

"代码检查": {
    "执行SQ代码扫描": {
      "Type": "SONAR_QUBE"
    }
  }

执行SonarQube代码检查,需要在项目根目录下要创建sonar-project.properties配置文件,以Java项目的配置文件为例:

# must be unique in a given SonarQube instance
sonar.projectKey=Jenkins:Test-Java-Build

sonar.projectVersion=1.0

# Path is relative to the sonar-project.properties file. Defaults to .
sonar.sources=src
sonar.sourceEncoding=UTF-8
sonar.java.binaries=./target/classes
"执行Maven构建": {
      "Type": "COMMAND_STATUS",
      "Script": {
        "Maven构建": "cd ${PROJECT_PATH};mvn clean package -U -DskipTests"
      }
    }

该节点就是执行命令,这里具体构建命令是用mvn clean package -U -DskipTests命令完成的。

经过上述配置文件的执行,我们可以很简单的完成所有的构建步骤:

这里篇幅有限,更多内容请到项目仓库查看比如:

  • 构建JS项目

  • 构建ReactNative项目

  • 构建Android项目

  • 构建iOS项目

  • 构建.NET项目

  • 构建多个子项目

  • 构建成功和失败处理

  • 在K8S内创建Pod进行构建

互动环节

如果您对这个项目很感兴趣,欢迎通过以下方式与我交流:

项目地址:https://github.com/gyyx/jenkins-json-build

个人邮箱:sunweisheng@live.cn