全栈工程师修炼指南
熊燚(四火)
Oracle 首席软件工程师
32206 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 46 讲
全栈回顾 (1讲)
加餐 (1讲)
全栈工程师修炼指南
15
15
1.0x
00:00/00:00
登录|注册

03 | 换个角度解决问题:服务端推送技术

总结思考
服务端推送技术
Pull 和 Poll
Pull 模型的问题
服务端推送技术

该思维导图由 AI 生成,仅供参考

你好,我是四火。
今天我们继续和 HTTP“过不去”。在上一讲,我们讲到了 HTTP 在安全传输方面的局限,并介绍了怎样使用经过 TLS 加密的 HTTPS 连接来解决这样的弊端。
今天,我要给你讲讲传统 HTTP 的另一个在交互模式上的局限,就是只能由客户端主动发起消息传递,而服务端只能被动响应消息的局限,并介绍它的解决办法。

Pull 模型的问题

让我们来思考这样一个场景,假设你设计了一款网页版的即时聊天工具,现在你使用浏览器打开了聊天页面,正在和朋友愉快地聊天。这时有朋友给你发送了一条消息,可是由于 HTTP 本身机制的限制,服务端无法主动推送消息,告知浏览器上的聊天页面“你有一条消息”,进而影响到了消息的即时送达。那么,这个问题怎么解决?
你可能会立即想到轮询(Poll),比如浏览器每隔十秒钟去问一下服务端是不是有新消息不就完了嘛。这看起来是个好思路,但明显存在这样两个问题:
消息还是不够即时。换言之,假如正好在某次询问之后服务器收到了消息,那么这条消息的获取延迟可能达到至少十秒。
大量的请求 - 响应,带宽和服务器资源浪费。如果你开着聊天工具页面一个小时,除了这一条消息,却没有进一步的聊天行为,于是按照每十秒发送一次请求计算,一共发起了 360 次请求,而其中居然只有 1 次返回了聊天消息是有实际意义的。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了服务端推送技术,针对传统HTTP交互模式的局限性进行了详细讨论。首先分析了Pull模型的问题,指出了轮询方式存在的延迟和资源浪费问题。接着介绍了Pull和Poll的区别,以及Push相对于Pull的优势。然后详细讨论了两种服务端推送技术:Comet和WebSocket。Comet采用长轮询方式实现服务端推送,但存在一定的弊端;而WebSocket则是一种全双工协议,具备高效性和实时性,且不受同源限制。文章通过实例和技术细节展示了WebSocket的使用方法和协议升级过程。此外,还提到了其他推送技术,如SSE、HTTP/2、WebRTC等,为读者提供了更多拓展阅读的可能性。通过学习本文,读者可以全面了解服务端推送技术的原理和应用,为其在实际项目中的应用提供了有益的参考。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《全栈工程师修炼指南》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(20)

  • 最新
  • 精选
  • LiYanbin
    感谢回答!我的表述有误,其实我是想知道,服务器推送技术,像websock这种技术,其实就是服务器和客户端建立一条连接,建立连接可以基于TCP也可以基于UDP,但是却很少见到基于UDP的上层应用协议。 如果说是因为TCP可靠性,时序性,保活这些特性才选择TCP,那这些特性转移到应用层这一层来维护也非不可。 那究竟是何原因导致在服务器推送技术领域中,没有广泛应用的基于UDP的上层应用协议呢?

    作者回复: 我是这样认为的: 就像你说的,比如可靠性,保序性,拥塞控制等等,完全是可以放到应用层来做的。 但是,对应用层来说,它们关心的内容,不需要,也不应该包括这些传输方面的基本特性,或者说,已经有传输层的TCP把这些事做好了。而协议的设计者,关心他/她设计的协议想解决的问题,这些传输方面的特性,拿来用就可以了,而不需要再实现一遍。 往大了说,软件分层的目的最大目的,就是解耦。解耦之后“谁”做“什么事”就是每一层的职责,7层/5层模型里的传输层也一样。

    2020-01-09
    2
    2
  • Geek_02f3e8
    老师讲的非常详细,我还想额外补充一个日常使用webcosket时需要注意的点。 websocket在解除跨域限制的同时,也产生了新的安全问题:在upgrade到ws协议时,服务端对于origin字段校验的缺失可能会导致websocket跨域劫持的安全问题。 攻击者诱导受害者点击包含一段以ws协议发送指定恶意内容的js的钓鱼页面,即可以受害者身份发送该ws数据,这是一个类似HTTP CSRF的问题:CSWH(Cross-site websocket-hijacking)。

    作者回复: 赞

    2020-09-01
    1
  • LiYanbin
    对于服务端推送技术,之前有考虑过,有一个疑问,为何客户端和服务器端为何不直接通过UDP进行通信呢?换句话说,为何在服务器推送技术中没有一种 比较被广泛应用的+基于UDP的 应用层协议呢?

    作者回复: 其实基于 UDP 的应用层协议也有一些,常听说的比如有 DHCP。之所以我们平时接触的不多,主要还是由它们的特点所决定的,你可以看一下 https://en.wikipedia.org/wiki/User_Datagram_Protocol#Comparison_of_UDP_and_TCP 比如其中提到的可靠性和有序性就是我们一般应用层的基本通信要求。 另外一个,HTTP/3 也会使用 UDP 代替 TCP,主要原因还是在物理设备改进,传输质量提升了以后,出于性能的考虑。可以参见:https://thenewstack.io/http-3-replaces-tcp-with-udp-to-boost-network-speed-reliability/

    2020-01-06
    1
  • 学不动了
    老师你好,我有个疑问,是关于comet: 客户端必须在服务端结束当次传输后才能向服务端发送消息,服务端会采用分块传输,也就是"我说完你再说",客户端这时候有新的请求就只能等着才能发送?要是长时间不结束客户端的请求就没法发送了嘛?

    作者回复: 好问题,是这样的,HTTP/1.1 Comet 的一个局限性就在这里,也就是说,传输是单工的,从协议的角度来说,服务端的响应分多次返回,因此这个过程中,返回并没有传输完,那么对于该次 HTTP 连接来说,客户端也就无法发送新的请求。 当然,除了升级到 HTTP/2 或者采用其他技术以外,对于这个问题本身,还是有一些改进办法的,你可以思考一下。:)

    2019-09-29
    2
    1
  • jxs1211
    请问今天的课堂实例如果要自己用代码来实现,前后段代码是否有相关的实例代码可以做参考?

    作者回复: 你可以自己尝试实现一个最简单的 Comet: 客户端,你甚至都不用写 JavaScript,一个普通的 get 请求即可——浏览器直接访问某一个服务端暴露的接口(URL)。 服务端则是往响应中写数据,使用按块传输,返回类型设置为 plain/text,随便写一点数据并 flush,然后 sleep 10 秒,再写一点并 flush,再 sleep 10 秒,如是多次,这样可以模拟多次返回。 这样,你会看到浏览器一直在加载,页面十秒十秒地新增新的内容。

    2019-09-22
    1
  • Chocolate
    第一个问题,我们的后台系统里的二维码扫码登录用的就是 Pull 的形式,每隔一段时间就去轮询有没有扫码,有没有确认登录,对于后台这类系统是可以满足需求的;在调度系统里的状态实时推送里用到了 WebSocket 技术,可以实时反馈任务的执行情况。 第二个问题,Push 模型的优势是高效性和实时性,Pull 模型的优点除了无状态外,优势可能是实现起来更方便,不用引入新的框架

    作者回复: 对于大多数分布式的系统来说,Pull 确实要比 Push 实现起来方便一些,但是也不绝对。至于你说的“是否引入新的框架”这个描述比较模糊,两种方式和是否引入框架没有必然联系。

    2019-09-16
    2
    1
  • 四喜
    老师讲得真好。 提问🙋,Comet这种假PUSH方式,由客户端发起的HTTP请求服务器不释放,但是会受超时限制吧?

    作者回复: 非常好的问题! 是的,完全正确。你可以考虑这样几点: 1. 客户端和服务端,还有网关等中间节点,都要商定好一个最大的超时时间。并且,业务端配置的超时时间要稍短于其它,以留足余量。 2. 服务端即便没有消息需要推送,也要定期返回一个无业务意义的消息,以避免超时发生。 3. 客户端如果在若干个推送周期后,可以结束连接,休息一段时间,再重新连接。

    2019-09-16
    1
  • 记忆犹存
    Push 的模型 优点:响应及时 缺点: a.如果客户端接收不及时,造成数据包堆积; b. 需要客户端做流控处理; Pull模型 优点: a. 提取消息方便 b. 传输失败不用重试 缺点:实时性差

    作者回复: 感谢分享! 对于 Push 模型,你说的内容都是正确的,就提一点,对于你提到的数据包堆积和流控的问题,可以引入第三方的消息队列服务来协调消息发布者和订阅者,来缓解你说的问题。 对于 Pull 模型,“传输失败不用重试”这个不对,因为是不是重试并非 Push 或 Pull 的区别,二者都可以重试,也都可以不重试,取决于设计。其它正确。 当然,这是一个开放性问题,还有其它的优缺点,你也可以看看其他人的答复。

    2019-09-16
    1
  • 💢 星星💢
    老师我看不懂英文资料,是不是多看看就会有感觉了?有没有啥秘诀。。。

    作者回复: 最佳实践那一章的最后一篇特别放送,我会讲一讲程序员怎么学英语。可以期待一下。

    2019-11-15
  • liansng
    Location: wss://echo.websocket.org Message: Rock it with HTML5 WebSocket 这个的操作方式我没太看懂,老师可以帮忙解释一下吗?

    作者回复: 这是你打开 https://www.websocket.org/echo.html 的时候,它已经默认帮你填好的内容

    2019-10-22
收起评论
显示
设置
留言
20
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部