即时消息技术剖析与实战
袁武林
微博研发中心技术专家
立即订阅
6503 人已学习
课程目录
已完结 24 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 搞懂“实时交互”的IM技术,将会有什么新机遇?
免费
基础篇 (8讲)
01 | 架构与特性:一个完整的IM系统是怎样的?
02 | 消息收发架构:为你的App,加上实时通信功能
03 | 轮询与长连接:如何解决消息的实时到达问题?
04 | ACK机制:如何保证消息的可靠投递?
05 | 消息序号生成器:如何保证你的消息不会乱序?
06 | HttpDNS和TLS:你的消息聊天真的安全吗?
07 | 分布式锁和原子性:你看到的未读消息提醒是真的吗?
08 | 智能心跳机制:解决网络的不确定性
场景篇 (4讲)
09 | 分布式一致性:让你的消息支持多终端漫游
10 | 自动智能扩缩容:直播互动场景中峰值流量的应对
11 | 期中实战:动手写一个简易版的IM系统
12 | 服务高可用:保证核心链路稳定性的流控和熔断机制
进阶篇 (10讲)
13 | HTTP Tunnel:复杂网络下消息通道高可用设计的思考
14 | 分片上传:如何让你的图片、音视频消息发送得更快?
15 | CDN加速:如何让你的图片、视频、语音消息浏览播放不卡?
16 | APNs:聊一聊第三方系统级消息通道的事
17 | Cache:多级缓存架构在消息系统中的应用
18 | Docker容器化:说一说IM系统中模块水平扩展的实现
19 | 端到端Trace:消息收发链路的监控体系搭建
20 | 存储和并发:万人群聊系统设计中的几个难点
21 | 期末实战:为你的简约版IM系统,加上功能
22 | 答疑解惑:不同即时消息场景下架构实现上的异同
结束语 (1讲)
结束语 | 真正的高贵,不是优于别人,而是优于过去的自己
即时消息技术剖析与实战
登录|注册

21 | 期末实战:为你的简约版IM系统,加上功能

袁武林 2019-10-14
你好,我是袁武林。
在期中实战中,我们一起尝试实现了一个简易版的聊天系统,并且为这个聊天系统增加了一些基本功能。比如,用户登录、简单的文本消息收发、消息存储设计、未读数提示、消息自动更新等。
但是期中实战的目的,主要是让你对 IM 系统的基本功能构成有一个直观的了解,所以在功能的实现层面上比较简单。比如针对消息的实时性,期中采用的是基于 HTTP 短轮询的方式来实现。
因此,在期末实战中,我们主要的工作就是针对期中实战里的消息收发来进行功能优化。
比如,我们会采用 WebSocket 的长连接,来替代之前的 HTTP 短轮询方式,并且会加上一些课程中有讲到的相对高级的功能,如应用层心跳、ACK 机制等。
希望通过期末整体技术实现上的升级,你能更深刻地体会到 IM 系统升级前后,对使用方和服务端压力的差异性。相应的示例代码我放在了GitHub里,你可以作为参考来学习和实现。

功能介绍

关于这次期末实战,希望你能够完成的功能主要包括以下几个部分:
支持基于 WebSocket 的长连接。
消息收发均通过长连接进行通信。
支持消息推送的 ACK 机制和重推机制。
支持客户端的心跳机制和双端的 idle 超时断连。
支持客户端断线后的自动重连。

功能实现拆解

取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《即时消息技术剖析与实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(8)

  • 墙角儿的花
    有个大佬给我讲,用websocket在弱网下因为网络阻塞,tcp滑动窗口,不断断网重连,websocket自己又有自己的心跳机制,导致服务端压力很大,云云,我还没搞明白究竟什么意思。难道tcp本身不也是这样?

    作者回复: 网络阻塞和滑动窗口都是底层传输层的事情呀,和上层的websocket没啥关系,如果有由于传输内容大导致拥塞的问题需要解决的是websocket封装的业务内容是否足够精简,是否需要进一步压缩,和websocket本身无关。websocket自带的心跳机制浏览器很多并不自动支持,所以一般都是自己应用层来实现,自带的心跳机制只要服务端过滤掉也并不会影响连接本身的稳定性。所以最好还是通过双端抓包来具体分析,也有可能是由于链路中间的反向代理等服务导致的。

    2019-10-14
    3
  • 墙角儿的花
    回答问题,关闭清除客户端连接和待ACK列表

    作者回复: 👍

    2019-10-14
    2
  • lecy_L
    老师,我现在有个这样的在线教育的场景。实时性要求极高,延迟要在200ms以下,直播是用第三方的通道,鼠标互动等是自己的socket服务。如果采用发布订阅模式的话,队列会成为单点极有可能延迟高,有其他的设计方案参考吗?场景是房间教学,一个房间有几个或者10来个人
    2019-10-15
    1
  • lecy_L
    咨询个问题,望解答。
    网关机记录用户和链接的信息,finnal在jvm里面的。现在我有一个这样的场景,一个房间(类似群聊)有N个用户,按照上面的说法我要怎么链接到同一个服务器(多应用情况),或者是怎么通知其他链接?在线等,急

    作者回复: 直播那一章课程里有讲到哈,简单的话就用redis的发布订阅就可以。所有网关机订阅所有房间消息,各网关机认领本机维护的房间用户信息并下推。

    2019-10-14
    1
    1
  • yangzi
    回答问题:如果多次下推仍然没有成功,关闭客户端连接,将未回执的消息存储为离线消息。

    作者回复: 有点小问题:离线消息建议在消息存储完后就存上,这样离线buffer里的消息是连续的,便于后续检查获取。另外还需要清除 待ack列表中这条消息。

    2019-10-14
    1
  • rachel.li
    老师你好,我电脑redis已经启动,但是项目启动的时候报错启动不了redis。debug查看了错误说creating server tcp..........no such file or directory,然后谷歌了按网上的办法重新按顺序重新连接redis,启动项目还是报那个错,但是我其他项目是正常的。您有什么思路不

    作者回复: 你说的这个是示例代码运行的问题吗?示例代码默认会通过embedded 的方式在jvm里自动启动一个兼容redis协议的模拟redis供使用。如果本机还额外起了redis的话需要看下端口是否存在冲突。

    2019-11-06
  • 铁柱
    ack机制里提到“服务端会在这个连接维度的存储里,初始化一个起始值为 0 的序号(tid)”,但是老师您的代码里实际上所有的channel是公用一个websockethandler,也就是使用同一个对象,那么这个concurrenhashmap实际上是被所有连接共享的吧,这样设计难道不会造成ack消息确认被覆盖吗(eg:channel1中tid为1的ack被channel2中tid为1的ack确认覆盖了)

    作者回复: 嗯,看了一下确实存在这个问题,感谢反馈,最新代码已经修复这个问题啦,把待ack列表放入到channel的attr里面了,避免复用导致混乱的问题。

    2019-10-28
  • joylee109
    老师,你好。websocket 想服务器传送数据的时候, sender_id 是明文传送嘛?现在用户已经登录了网站,认证方式可能是:session ,或者 jwt 方式,或者其他方式。既然用户已经登录,为什么还要在传送数据到后端的时候,将sender_id 明文带上呢?感觉明文传送 sender_id 到后端不安全。

    作者回复: 对于经过认证的用户,实现上可以不需要再带上发送方uid,这里是想网关机不依赖认证信息,实现上网关机从session获取完全没问题。另外这里只是个演示demo,线上的话起码会走tls的wss协议。

    2019-10-14
收起评论
8
返回
顶部