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

2015-02-13 16:03:25 +08:00
 c742435

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

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

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


@dingyaguang117 long polling不是实时,在polling因为有数据完成后到下一次polling开始前的这段时间会造成非实时
ipconfiger
2015-02-13 18:13:23 +08:00
@otakustay 你基本上没有理解什么是long polling
ipconfiger
2015-02-13 18:14:58 +08:00
long polling 的数据能够实时,但是客户端状态不是实时的,如果需要密集ping状态又不想加大服务端负载,就还是长链接比较划算
vzch
2015-02-13 18:15:34 +08:00
WebSockets 只需要一次握手
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
2015-02-13 18:27:09 +08:00
@lincanbin
@kofj
@dingyaguang117
@ss098
@pi1ot
最终结论是:
我描述的问题是,传统的长连接已经能够实现实时下行通讯,是否可以使用另一条连接进行实时上行通讯,从而实现全双工?
结论是,无论长连接还是我描述的“上行长连接”,都属于http协议没有规定的中间地带。服务器和浏览器的行为是不能完全确定的。但是,通常来说浏览器被设计为“即使未完全下载页面也能渲染页面的一部分”,所以下行可以使用长连接。
而对上行来说,有两点阻碍:1.常见浏览器的js中没有一个类库能够实现发送一个不完整的请求并实时追加它。
2.传统的http服务器对不完整的请求的处理不能预期。(估计nodejs可以)大部分http服务器在未获取完整的request之前可能不会处理请求。
zhujinliang
2015-02-13 18:44:17 +08:00
长链接可以做到实时,我实际做的是用一条长链接接收消息,发送消息时另起一个POST请求,就是两条HTTP请求。服务器是node.js

某些楼层对实时的理解太苛刻了,你说Facetime是不是实时的,但实际上也是一个一个封包发过去的,每个封包中间还有一定的时间间隔
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
2015-02-13 19:30:37 +08:00
websocket不好吗? 有什么问题呢?
lincanbin
2015-02-13 19:41:14 +08:00
@dingyaguang117 长连接如何实现双向通讯?
laoyuan
2015-02-13 19:41:30 +08:00
两条的结果不是 2 = 1 + 1 ,而是2 * 2 = 4,在两端还要分别通信
ipconfiger
2015-02-13 20:10:59 +08:00
@otakustay 你要是实际做过消息系统的话就会知道,“实时”这个概念没有你所以为的这么及时。换个简单的例子来说,比如APNS,自己试试,TCP长连接的“实时”
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
2015-02-14 00:01:03 +08:00
这完全不是实时。。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/170762

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX