聊聊 WebSocket,还有 HTTP
还记得曾经风靡一时的 QQ 秀聊天室吗?那时,还在上初、高中的我们,QQ 是最常用的聊天交友工具;而 QQ 秀聊天室的出现打破了只能按条件查找好友的局限性,大家可以随意进入聊天室房间,进行在线聊天。怀念那个穿着最酷炫的 QQ 秀的我在聊天室闪亮登场,质朴的问出一句:“有 GG/MM 吗?”

WebSocket 的诞生
随着互联网的发展,网上出现了各种聊天室软件,各种新奇的玩法,却再也找不到当年那种纯真的感觉了。当然了,无论是曾经的聊天室,还是如今的视频弹幕,吸引人的地方就在于实时沟通交流。要实现类似实时交互的应用场景,需要低延迟、高及时的技术。
曾经,很多网站为了实现上述场景,所用的技术都是轮询。即每隔一段时间(如每 1 秒),由浏览器对服务器发出 HTTP 请求,询问服务器有没有新的信息,然后由服务器返回最新的数据给客户端。这种传统的轮询模式存在很明显的缺点,即浏览器需要不断的向服务器发出请求,然而 HTTP 请求包含较长的请求头,真正有效的数据可能只占一小部分,这样显然会浪费一部分带宽资源。那有没有更好的方法呢?
WebSocket 应运而生。WebSocket 协议诞生于 2008 年,在 2011 年成为国际标准,并且 WebSocket 同样是 HTML 5 规范的组成部分之一。WebSocket 是一种全新的协议,它将 TCP 的 Socket(套接字)应用在了 web page 上,从而使通信双方建立起一个保持在活动状态连接通道,并且属于全双工(双方同时进行双向通信)。WebSocket 协议更好的节省了服务器资源和带宽,并且能够更实时地进行通讯。
相比 HTTP 协议,WebSocket 究竟有哪些不同呢?
HTTP vs WebSocket

HTTP 协议是半双工协议,也就是说在同一时间点只能处理一个方向的数据传输,属于单向传输。在客户端向服务器发起连接之前,服务器并不知道有这个连接。发起一个请求,得到一个响应,通信便结束了,客户端和服务器也“忘记了彼此”。不过现在可以通过 Cookie 使客户端保持某种状态,以便服务器可以识别客户端。

而 WebSocket 协议是全双工的,服务器可以随时主动给客户端下发数据,可以双向发送或接受信息,属于双向传输。WebSocket 可以通过客户端和服务器的握手建立连接,并且连接一直保持“打开”状态,不仅仅是一个请求 + 一个响应。首先,客户端会先发起请求建立连接,若服务器接受了此请求,则将建立双向通信。然后,服务器和客户端就可以进行信息交互了,直到客户端或服务器发送消息将其关闭为止。

当然,WebSocket 和 HTTP 也是有联系的。因为 WebSocket 需要先通过 HTTP 协议的 101 状态码建立连接。为了创建 WebSocket 连接,需要通过浏览器发起请求,等待服务器进行回应,这个过程通常称为“握手”(Handshaking)。
一个典型的 WebSocket 握手请求如下:
客户端请求:
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: localhost.com
Origin: http://localhost.com
Sec-WebSocket-Key: aN3cRrW/n8NuIgdhy2VJFX==
Sec-WebSocket-Version: 13
服务器回应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: pFDoeB2FAdLlXgESz0UT2v7hp0s=
Sec-WebSocket-Location: ws://localhost.com/
字段说明:
Connection 字段必须为 Upgrade,表示客户端希望连接升级。
Upgrade 字段必须为 WebSocket,表示希望升级到 WebSocket 协议。
Sec-WebSocket-Key 的值是随机字符串,服务器端会用这些数据来构造出一个SHA-1的信息摘要。把“Sec-WebSocket-Key”加上一个特殊字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然后计算 SHA-1 ,再进行 Base64 编码,将结果做为“Sec-WebSocket-Accept”头的值,并返回给客户端。这样可以尽量避免普通 HTTP 请求被误认为 WebSocket 协议。
Sec-WebSocket-Version 字段表示支持的 WebSocket 版本。RFC6455 要求使用的版本是13,之前草案的版本均应当弃用。
其他一些定义在 HTTP 协议中的字段,如 Cookie 等,也可以在 WebSocket 中使用。
WebSocket 使用 ws 或 wss 的统一标识符,类似于 HTTP/HTTPS。其中 wss 表示使用了 TLS 的 WebSocket。例如:
ws://localhost.com/api
wss://securelocalhost.com/api
WebSocket 与 HTTP/HTTPS 使用相同的 TCP 端口。默认情况下,WebSocket 协议使用 80 端口;运行在 TLS 之上时,默认使用 443 端口。
WebSocket 的优势
作为“后起之秀”,到如今的广泛应用,毋庸置疑 WebSocket 拥有很多优点:
- 较少的资源浪费
在连接创建后,服务器和客户端之间交互时,传输的数据包头部相对较小。相对于 HTTP 请求每次都要携带完整的头部,资源浪费显著减少了。
- 更强的实时性
由于 WebSocket 协议是全双工的,所以服务器可以随时主动给客户端传输数据。相对于 HTTP 请求需要等待客户端发起请求服务端才能响应,延迟明显更少。

- 保持长连接
与 HTTP 不同的是,WebSocket 需要先创建连接,这就使得其成为了一种有状态的协议。而 HTTP 请求可能需要在每个请求都携带状态信息(如身份认证等)。
- 更好的二进制支持
WebSocket 定义了二进制帧,相对 HTTP,可以更轻松地处理二进制内容。
- 更好的压缩效果
相对于 HTTP 压缩,WebSocket 在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,显著地提高压缩率。
不同的业务场景如何选择
相比较 WebSocket 和 HTTP,可以说 HTTP 请求比 WebSocket 更简单,但是也有局限性。在不同的使用场景可以选择更合适的协议。
目前互联网上大多数网站都是直接加载网页,除了单击加载新页面之外,交互工作都很少。在这种场景下没有必要保持长连接,使用 WebSocket 会显得过于“笨重”。一般的网页都会使用静态资源,例如 Image 图片,Javascript 或 CSS 文件等。为了加载更快,这些静态资源都需要进行缓存,而且它们可能并不来自同一个域名,这时当然使用 HTTP 更为轻便快捷。
HTTP 协议的每个请求都需要发送一次请求头,而 WebSocket 仅在初始请求建立连接中携带头信息(当然了,传递消息中也会有一些开销,但都是比较小的)。因此,如果想持续发送多个消息,使用 Websocket 会更节省资源。如果要开发一个客户端和服务器持续交互的程序,那么 WebSockets 将是最佳选择。例如:
- 社交、聊天
社交聊天工具,网站在线咨询窗口等,这一类聊天应用的特点是低延迟,高及时。其采用 WebSocket 协议,实现了实时沟通交流,以高效的方式满足沟通的需求。
- 弹幕
看视频,弹幕少不了,精彩的点评、搞笑的段子,网友之间的实时互动,有时对于一个视频来说,弹幕才是精华。而发弹幕需要实时显示,通过 WebSocket 协议可将本地客户端发送的弹幕信息通过服务端全部推送至其他用户的客户端并进行实时展示。
- 在线教育
在线教育近几年发展迅速,不用出门即可和老师、同学实时沟通、交流。老师布置作业、学生互动、咨询老师问题等等都可实时在线进行,此类实时交互都可由 WebSocket 协议支撑完成。
- 位置信息更新的应用
当前移动设备中实时的位置定位、实时的网络数据更新,使用 HTTP 协议显得有些笨拙,借用 WebSocket 可以让数据实时更新更快。
又拍云 WebSocket 服务产品,突破传统 CDN 厂商只能加速 HTTP/HTTPS 协议的局限,将 WebSocket 协议与 CDN 相融合,并结合自身多年 CDN 行业技术经验,采用多种优化技术,为使用 WS/WSS 协议进行通信的客户提供了优质的加速服务,能有效降低延迟,提升效率。快来抢先体验!
推荐阅读
聊聊 WebSocket,还有 HTTP的更多相关文章
- 简单聊聊WebSocket
一.概述 上一篇文章<浅析一次HTTP请求>我们分析了简单的一次 HTTP 请求具体是怎么样完成的,分析了 HTTP 协议的数据结构,如何连接,如何断开,又是如何多路复用的,那么今天我们来 ...
- 从构建分布式秒杀系统聊聊WebSocket推送通知
秒杀架构到后期,我们采用了消息队列的形式实现抢购逻辑,那么之前抛出过这样一个问题:消息队列异步处理完每个用户请求后,如何通知给相应用户秒杀成功? 场景映射 首先,我们举一个生活中比较常见的例子:我们去 ...
- 聊聊OkHttp实现WebSocket细节,包括鉴权和长连接保活及其原理!
一.序 OkHttp 应该算是 Android 中使用最广泛的网络库了,我们通常会利用它来实现 HTTP 请求,但是实际上它还可以支持 WebSocket,并且使用起来还非常的便捷. 那本文就来聊聊, ...
- 补习系列(20)-大话 WebSocket 与 "尬聊"的实现
目录 一.聊聊 WebSocket 二.Stomp 是个什么鬼 三.SpringBoot 整合 WebSocket A. 引入依赖 B. WebSocket 配置 C. 控制器 D. 前端实现 四.参 ...
- 补习系列(20)-大话 WebSocket 与 "尬聊"的实现
目录 一.聊聊 WebSocket 二.Stomp 是个什么鬼 三.SpringBoot 整合 WebSocket A. 引入依赖 B. WebSocket 配置 C. 控制器 D. 前端实现 四.参 ...
- 使用 Socket.IO 开发聊天室
前言 Socket.IO 是一个用来实现实时双向通信的框架,其本质是基于 WebSocket 技术. 我们首先来聊聊 WebSocket 技术,先设想这么一个场景: · 用户小A,打开了某个网站的充值 ...
- 当我谈 HTTP 时,我谈些什么?
当我们打开网站时也许不会去留意网站前面的HTTP是怎么来的.但是它毫无疑问在网络中有着举足轻重的地位.本文从起源到发展,详说HTTP从1到3的演变. 说在前面 本文不致力于讲完 HTTP 的全部内容, ...
- 【白话科普】10s 从零看懂 H5
最近大家有没有发现,很多微信公众号的动态内容变多了?我们常常可以看到,公众号内容中有很多动态图片甚至动画,还可以通过手指滑动切换页面,或者有一些小的点击互动. 这种看起来有点高级的小作品,其实是都是& ...
- 聊聊分布式下的WebSocket解决方案
前言 最近王子自己搭建了个项目,项目本身很简单,但是里面有使用WebSocket进行消息提醒的功能,大体情况是这样的. 发布消息者在系统中发送消息,实时的把消息推送给对应的一个部门下的所有人. 这里面 ...
随机推荐
- 是谁收购了被谷歌私藏7年之久的Zagat?
国内餐饮行业的风口似乎总是执着于"价格"上,无论是天天搞特价的外卖,还是优惠不停歇的团购网站,都将"价格"当做了竞争的杀手锏.即使是网红奶茶.甜品之类的,也是将 ...
- ltp压力测试结果分析脚本
最近工作性质发生了改变,在做操作系统方面的测试.接手的第一个任务是做ltp stress.测试内核稳定性. 做完之后会结果进行统计分析.因为统计的内容比较多,都是通过shell命令行进行操作.于是编写 ...
- javaWeb简单登录实现验证数据库
用户登录案例需求: 1.编写login.html登录页面 username & password 两个输入框 2.使用Druid数据库连接池技术,操作mysql,day14数据库中user表 ...
- 通过zxing生成二维码
二维码现在随处可见,在日常的开发中,也会经常涉及到二维码的生成,特别是开发一些活动或者推广方面的功能时,二维码甚至成为必备功能点.本文介绍通过 google 的 zxing 包生成带 logo 的二维 ...
- PHP RFI 的小tip
有关PHP include的帖子网上已经很多了,wooyun的知识库里面也有一篇总结的很好的文章,传送门:http://drops.wooyun.org/tips/3827,今晚在看书的时候看到RFI ...
- Go基础学习(二)
数组[array] 数组定义[定义后长度不可变] 12 symbol := [...]string{USD: "$", EUR: "€", GBP: " ...
- [开源福利] Arithmetic Generator
Arithmetic Generator Built with ❤︎ by Simon Ma ✨ A powerful arithmetic generator
- [置顶]
Python 使用itchat 对微信好友数据进行简单分析
人生苦短,我用Python! Python 热度一直很高,我感觉这就是得益于拥有大量的包资源,极大的方便了开发人员的需求. 最近在一个微信公众号上看到一个调用微信 API 可以对微信好友进行简单数据分 ...
- Pandorabox固件路由器上申请Let's Encrypt证书,为内网里的多个web服务提供SSL支持
对于家中宽带有公网IP的用户,有时我们需要将路由器内部网络的某些web服务通过端口转发暴露到外网(例如NAS远程访问),但HTTP是明文传输,有被监听的风险:如果在NAS上使用自签名证书,再端口转发, ...
- 使用Navicat或者其他数据库工具连接阿里云EDS(数据库服务器)实例过程详解
使用Navicat或者其他数据库工具连接阿里云EDS(数据库服务器)实例过程详解 背景:这几天从阿里云上面购买了云服务器,最垃圾的那种,还送oss和EDS数据库服务器,只不过EDS数据库服务器只有一个 ...