一种基于 HTTP 的伪双工通信 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
abersheeran
V2EX    程序员

一种基于 HTTP 的伪双工通信

  •  
  •   abersheeran 2021-04-14 13:31:48 +08:00 4069 次点击
    这是一个创建于 1643 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一般提到 Web 的双工通信,第一反应都是 WebSocket,但 WebSocket 与其他 HTTP 业务往往不能很好的融合在一起。而直接使用 HTTP 轮询,HTTP 头又太大了,哪怕上了 HTTP2,也是浪费资源。

    Server-sent events 就是一种很好的基于 HTTP 的单向长连接通信方式。https://developer.mozilla.org/zh-CN/docs/Web/API/Server-sent_events

    比如日志流展示业务,只需要使用 SSE 就行了,完全不需要上 WebSocket 。

    所谓双工通信,就是服务端拥有随时推送消息给客户端且客户端拥有随时推送消息给服务端的能力。使用 SSE 就可以让服务端可以随时推送消息给客户端,而客户端推送消息给服务端,直接 HTTP 请求就行。

    这种伪双工通信的好处就是完全基于 HTTP,负载均衡、反向代理以及客户端的调用逻辑都可以使用现成的生态,不需要再去基于 WebSocket 搞一套代码。

    刷推特看到有人使用 SSE 做日志流推送业务有感而发。所以抛砖出来供大家一观。

    22 条回复    2021-04-14 17:24:32 +08:00
    zhengxiaowai
        1
    zhengxiaowai  
       2021-04-14 13:35:46 +08:00   4
    关键是没什么生态,,SSE 基本没人用。

    WebSocket 天生为 Web 而生和 HTTP 结合的比较好,不太清楚不能很好融合指的是?
    另外 WebSocket 久经考验,比较指的信赖。
    abersheeran
        2
    abersheeran  
    OP
       2021-04-14 13:42:31 +08:00
    @zhengxiaowai 确实,SSE 很少看到有人用,我也是大概一年前才知道有这个东西的。

    WebSocket 和 HTTP 结合的我感觉也一般吧,比如 Serverless 平台实现 WebSocket 超级麻烦。只针对新手而言,配置反代就是个问题了。还有一个,就是 WebSocket 特别容易被滥用。HTTP 也不走了,直接在 WebSocket 上封装一个交互协议出来了。另外就是,WebSocket 那么久经考验的吗……国内大厂好像不怎么用这个啊
    whytheluckystiff
        3
    whytheluckystiff  
       2021-04-14 13:49:41 +08:00   2
    你用过 GitHub 么,GitHub 所有的议题和拉取请求页面都在使用 WebSocket !后边肯定有一个恐怖的集群,我估计是用 socket.io 写的。
    3dwelcome
        4
    3dwelcome  
       2021-04-14 13:50:35 +08:00
    我服务器上的客户端订阅,就是 SSE 单向推送。本质上浏览器就是一个虚拟的 POST 文件上传组件,然后服务器卡住,不马上返回,改为很缓慢缓慢的向客户端渐进式发数据。

    代码确实比 websocket 少,但是单向通讯功能也少,也存在各种小问题(比如时间一长没数据流发送,被各种手机浏览器,直接当成死链接给掐掉)。

    现在逻辑多了,交互环节多了,还是 websocket 双向通讯香。
    abersheeran
        5
    abersheeran  
    OP
       2021-04-14 13:53:02 +08:00
    @whytheluckystiff 这个我知道的。GitHub 那个确实猛。我也猜有一个大集群在提供这个服务。不过我觉得 GitHub 那个,似乎我说的这个方案更合适。因为 GitHub 还有 cli 可以用来发 issue 和 pr 之类的,这样一来就可以共用 HTTP API 了。
    abersheeran
        6
    abersheeran  
    OP
       2021-04-14 13:53:54 +08:00
    @3dwelcome 有 ping 啊。我一般都设定三秒发一次 ping 消息。不会被掐断的。
    abersheeran
        7
    abersheeran  
    OP
       2021-04-14 13:55:28 +08:00
    @3dwelcome 不过确实,合适的场景选择合适的技术。交互环节多,用 WebSocket 也挺好的。
    zhengxiaowai
        8
    zhengxiaowai  
       2021-04-14 13:55:38 +08:00
    @abersheeran 感觉是 Serverless 这种开发模式的问题,Serverless 单纯的开发 HTTP 确实方便一些。

    就目前而言 WebSocket 应该还是主流的双向通信的方向,至少在 H2 未普及之前应该是的。

    其他大厂不知道,估计有历史原因,目前字节都是基于 WebSocket 来做的。
    abersheeran
        9
    abersheeran  
    OP
       2021-04-14 13:56:34 +08:00
    @zhengxiaowai 的确。单是浏览器连接数限制就可以把 SSE 踢出场了。哈哈哈。
    zhengxiaowai
        10
    zhengxiaowai  
       2021-04-14 13:57:09 +08:00
    @abersheeran 另外我记得 sse 还需要高版本浏览器支持,这点就无解
    abersheeran
        11
    abersheeran  
    OP
       2021-04-14 13:58:12 +08:00
    @zhengxiaowai 我看 MDN 上提供的兼容性说明上,主流浏览器不都支持这个吗?
    kastnerorz
        12
    kastnerorz  
       2021-04-14 13:59:21 +08:00
    SSE 一个浏览器只能打开 6 个,可能有很多选型的时候觉得这个不能容忍吧
    whytheluckystiff
        13
    whytheluckystiff  
       2021-04-14 14:00:06 +08:00
    @abersheeran CLI 用户量和之前的 Hub 相差无几,WebUI 的使用数量不知道比 CLI 高到哪里去了. 你看一下国内的 Gitee 或自托管 GitLab,全都是 AJAX 短轮询,他们不用 WebSocket 也不用 SSE. SSE 这东西我之前也只听说过,也从来没有见谁用过。有例子么?或者 demo 什么的.
    abersheeran
        14
    abersheeran  
    OP
       2021-04-14 14:00:13 +08:00
    @kastnerorz 是的。HTTP2 没普及之前,硬伤。
    zhengxiaowai
        15
    zhengxiaowai  
       2021-04-14 14:01:02 +08:00
    @abersheeran 没看见大大的 IE No 么 :-)
    whytheluckystiff
        16
    whytheluckystiff  
       2021-04-14 14:01:40 +08:00
    @kastnerorz 对。我记得 Safari 能同时连接 1200 多个 WebSocket 。
    catchexception
        17
    catchexception  
       2021-04-14 14:27:46 +08:00
    我还以为楼主发明了新的协议!不过分享出来给大家看看也是值得肯定的!
    deviluser
        18
    deviluser  
       2021-04-14 14:58:38 +08:00
    @catchexception 我也以为要讨论点不让播的
    no1xsyzy
        19
    no1xsyzy  
       2021-04-14 15:07:55 +08:00
    SSE 是 S->B 的单工……
    吃过一个大坑,就是 POST 地址和 SSE 地址不能一样
    当时随手写了个匿名聊天室,我 SSE 是 GET /api/messages 然后发消息是 POST /api/messages
    结果一 POST,SSE 就断了……
    abersheeran
        20
    abersheeran  
    OP
       2021-04-14 16:31:22 +08:00
    @whytheluckystiff 公司例子我不清楚。demo 我倒是写过。

    @zhengxiaowai 哈哈哈,IE 被我自动无视了。

    @no1xsyzy 是啊,B->S 这个直接 HTTP 就好了,S->B 走 SSE 。这不就是伪双工了吗。
    zhengxiaowai
        21
    zhengxiaowai  
       2021-04-14 17:20:41 +08:00
    @abersheeran 毕竟 IE 11 还算是个人。。。
    abersheeran
        22
    abersheeran  
    OP
       2021-04-14 17:24:32 +08:00
    @zhengxiaowai 微软都在推 Edge,我觉得 IE 已经不算了……
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     921 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 21:37 PVG 05:37 LAX 14:37 JFK 17:37
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86