V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
c742435
V2EX  ›  问与答

用两条 HTTP 请求就可以实现双向实时通讯吧?为什么还需要 WebSocket

  •  
  •   c742435 · 2015-02-13 16:03:25 +08:00 · 6809 次点击
    这是一个创建于 3558 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我一点都不懂前端我就是问问

    20 条回复    2015-02-14 00:01:03 +08:00
    lincanbin
        1
    lincanbin  
       2015-02-13 16:06:57 +08:00
    你说的HTTP请求实现实时通讯是指高密度轮询?
    你得多高的密度才能做到实时?
    kofj
        2
    kofj  
       2015-02-13 16:11:49 +08:00
    半双工和双工的区别.
    c742435
        3
    c742435  
    OP
       2015-02-13 16:16:16 +08:00
    @lincanbin
    @kofj
    是否可以用js构建一个http请求,js源源不断的向其中灌入数据,然后一直不完成这个请求;
    之后服务端在请求没有全部接受完毕的时候就对其进行处理?
    dingyaguang117
        4
    dingyaguang117  
       2015-02-13 16:40:28 +08:00
    其实long polling 就可以了把~ 一条HTTP请求
    ss098
        5
    ss098  
       2015-02-13 16:44:55 +08:00 via Android
    使用 HTTP 请求需要考虑服务器的承受能力,少量的请求密集度通常可以模拟出效果,但一旦密集会导致服务器无力处理。

    WebSocket 很大程度上解决了性能问题,这是一个较为重要的原因。
    pi1ot
        6
    pi1ot  
       2015-02-13 16:51:01 +08:00
    传统的HTTP长连接只是单向的数据传输,另外这种方式对HTTP服务的资源占用也比较大,影响单机负载容量。
    otakustay
        7
    otakustay  
       2015-02-13 18:12:18 +08:00
    1. 现有的比较普及的JS无法在一个HTTP请求数据全部传输完毕前执行回调,所以不存在“源源不断”这种玩法
    2. 既然要2个HTTP请求实现这么麻烦的玩法,为啥不直接来个WebSocket


    @dingyaguang117 long polling不是实时,在polling因为有数据完成后到下一次polling开始前的这段时间会造成非实时
    ipconfiger
        8
    ipconfiger  
       2015-02-13 18:13:23 +08:00
    @otakustay 你基本上没有理解什么是long polling
    ipconfiger
        9
    ipconfiger  
       2015-02-13 18:14:58 +08:00
    long polling 的数据能够实时,但是客户端状态不是实时的,如果需要密集ping状态又不想加大服务端负载,就还是长链接比较划算
    vzch
        10
    vzch  
       2015-02-13 18:15:34 +08:00 via iPhone
    WebSockets 只需要一次握手
    otakustay
        11
    otakustay  
       2015-02-13 18:19:18 +08:00
    @ipconfiger
    我先随便copy一个不那么权威的解释,但我认为基本是对的:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求

    在这个过程中,有“响应信息并关闭链接”,以及“客户处理完后再向服务器发送新的请求 -> 服务器继续hold住”,在“关闭”到“新请求”这个过程中产生的信息并不能实时推送客户端,这就是long polling的非实时性,服务器需要等下一个HTTP链接建立上以后才能“立刻”把消息再推过去,但再努力“立刻”都有了建立HTTP链接这个过程的延时

    任何polling都无法做到全实时,哪怕用N条polling线,依旧有可能短时间内出现N+1条信息导致最后一条的非实时

    当然如果你理解的实时是不那么实时的,那就long polling吧……
    c742435
        12
    c742435  
    OP
       2015-02-13 18:27:09 +08:00
    @lincanbin
    @kofj
    @dingyaguang117
    @ss098
    @pi1ot
    最终结论是:
    我描述的问题是,传统的长连接已经能够实现实时下行通讯,是否可以使用另一条连接进行实时上行通讯,从而实现全双工?
    结论是,无论长连接还是我描述的“上行长连接”,都属于http协议没有规定的中间地带。服务器和浏览器的行为是不能完全确定的。但是,通常来说浏览器被设计为“即使未完全下载页面也能渲染页面的一部分”,所以下行可以使用长连接。
    而对上行来说,有两点阻碍:1.常见浏览器的js中没有一个类库能够实现发送一个不完整的请求并实时追加它。
    2.传统的http服务器对不完整的请求的处理不能预期。(估计nodejs可以)大部分http服务器在未获取完整的request之前可能不会处理请求。
    zhujinliang
        13
    zhujinliang  
       2015-02-13 18:44:17 +08:00
    长链接可以做到实时,我实际做的是用一条长链接接收消息,发送消息时另起一个POST请求,就是两条HTTP请求。服务器是node.js

    某些楼层对实时的理解太苛刻了,你说Facetime是不是实时的,但实际上也是一个一个封包发过去的,每个封包中间还有一定的时间间隔
    pi1ot
        14
    pi1ot  
       2015-02-13 18:55:05 +08:00
    @c742435 你描述的不是什么新概念,十年前各大门户流行的文本聊天室都是这么干的:

    1、server到client就是一个不中断的http连接,循环输出大家都在聊什么,你看到的就是不断的滚屏
    2、client到server做不到你说的效果,apache不会把一个还未结束的request转给cgi处理,所以都是用别的办法
    3、无论哪种,server和client两边实际上分别是两个独立的进程在收和发,同步和通信都很麻烦
    4、在当时环境下这些限制再加上一个长连接就是一个进程的资源消耗,应用范围有限

    至于现在,有比长连接丰富得多的解决方案,没必要再折腾这个了。
    yakczh
        15
    yakczh  
       2015-02-13 19:30:37 +08:00
    websocket不好吗? 有什么问题呢?
    lincanbin
        16
    lincanbin  
       2015-02-13 19:41:14 +08:00 via Android
    @dingyaguang117 长连接如何实现双向通讯?
    laoyuan
        17
    laoyuan  
       2015-02-13 19:41:30 +08:00
    两条的结果不是 2 = 1 + 1 ,而是2 * 2 = 4,在两端还要分别通信
    ipconfiger
        18
    ipconfiger  
       2015-02-13 20:10:59 +08:00
    @otakustay 你要是实际做过消息系统的话就会知道,“实时”这个概念没有你所以为的这么及时。换个简单的例子来说,比如APNS,自己试试,TCP长连接的“实时”
    breeswish
        19
    breeswish  
       2015-02-13 20:19:11 +08:00
    两条长连接确实可以,也可以实时性很高,websocket 优势在于:

    - 开销低:websocket 每一帧的额外数据少
    - 不会占用浏览器的同域名并发策略限制:如 Chrome 对于非 websocket,同一个 host 至多允许 6 个连接,意味着如果维持双向长连接,用户至多开三个标签页,第四个标签页会直接被阻塞(因为请求页面本身也是一个请求),而 websocket 并发连接数则大得多了,Chrome 上是 30(WebSocket 是双向的,所以可以支持同时 30 个标签页,并且第 31 个标签页只是无法建立 websocket,访问普通资源还是可以访问的),Firefox 上是 200(http://stackoverflow.com/questions/20945080/maximum-number-of-connections-using-websocket)
    jedihy
        20
    jedihy  
       2015-02-14 00:01:03 +08:00
    这完全不是实时。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2707 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 09:29 · PVG 17:29 · LAX 01:29 · JFK 04:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.