当前位置: 首页 > news >正文

websocket的那些事 - 初识

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

简介 

     WebSocket是一种在单个TCP连接上进行全双工通讯的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并由RFC7936补充规范。WebSocket API也被W3C定为标准。

       WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

出现背景

在websocket出现之前,实现服务器向客户端推送信息,都是基于HTTP请求,实现技术有以下几种:

轮询方式:客户端定时向服务端发送ajax请求,服务器接收到请求后马上返回消息并关闭连接。
优点:后端程序编写比较容易。
缺点:TCP的建立和关闭操作浪费时间和带宽,请求中有大半是无用,浪费带宽和服务器资源。
实例:适于小型应用。

长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求。
优点:在无消息的情况下不会频繁的请求,耗费资源小。
缺点:服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。
实例:WebQQ、Hi网页版、Facebook IM。

长连接:在页面里嵌入一个隐蔵iframe,将这个隐蔵iframe的src属性设为对一个长连接的请求或是采用xhr请求,服务器端就能源源不断地往客户端输入数据。
优点:消息即时到达,不发无用请求;管理起来也相对方便。
缺点:服务器维护一个长连接会增加开销,当客户端越来越多的时候,server压力大!
实例:Gmail聊天

Flash Socket:在页面中内嵌入一个使用了Socket类的 Flash 程序JavaScript通过调用此Flash程序提供的Socket接口与服务器端的Socket接口进行通信,JavaScript在收到服务器端传送的信息后控制页面的显示。
优点:实现真正的即时通信,而不是伪即时。
缺点:客户端必须安装Flash插件,移动端支持不好,IOS系统中没有flash的存在;非HTTP协议,无法自动穿越防火墙。
实例:网络互动游戏。

        在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

Websocket使用ws或wss的统一资源标志符,类似于HTTPS,其中wss表示在TLS之上的Websocket。如:

ws://example.com/wsapi
wss://secure.example.com/

Websocket使用和 HTTP 相同的 TCP 端口,可以绕过大多数防火墙的限制。默认情况下,Websocket协议使用80端口;运行在TLS之上时,默认使用443端口。

优点

  • 较少的控制开销。在连接创建后,服务器和客户端之间交换数据时,用于协议控制的数据包头部相对较小。在不包含扩展的情况下,对于服务器到客户端的内容,此头部大小只有2至10字节(和数据包长度有关);对于客户端到服务器的内容,此头部还需要加上额外的4字节的掩码。相对于HTTP请求每次都要携带完整的头部,此项开销显著减少了。
  • 更强的实时性。由于协议是全双工的,所以服务器可以随时主动给客户端下发数据。相对于HTTP请求需要等待客户端发起请求服务端才能响应,延迟明显更少;即使是和Comet等类似的长轮询比较,其也能在短时间内更多次地传递数据。
  • 保持连接状态。于HTTP不同的是,Websocket需要先创建连接,这就使得其成为一种有状态的协议,之后通信时可以省略部分状态信息。而HTTP请求可能需要在每个请求都携带状态信息(如身份认证等)。
  • 更好的二进制支持。Websocket定义了二进制帧,相对HTTP,可以更轻松地处理二进制内容。
  • 可以支持扩展。Websocket定义了扩展,用户可以扩展协议、实现部分自定义的子协议。如部分浏览器支持压缩等。
  • 更好的压缩效果。相对于HTTP压缩,Websocket在适当的扩展支持下,可以沿用之前内容的上下文,在传递类似的数据时,可以显著地提高压缩率。

握手协议

WebSocket 是独立的、创建在 TCP 上的协议。

Websocket 通过 HTTP/1.1 协议的101状态码进行握手。

为了创建Websocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”(handshaking),交互如下图所示:

095509_0lyZ_875122.png

交互请求头实例

一个典型的Websocket握手请求如下:

客户端请求

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: http://example.com
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13

服务器回应

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
Sec-WebSocket-Location: ws://example.com/

字段说明

  • Connection必须设置Upgrade,表示客户端希望连接升级。
  • Upgrade字段必须设置Websocket,表示希望升级到Websocket协议。
  • Sec-WebSocket-Key是随机的字符串,服务器端会用这些数据来构造出一个SHA-1的信息摘要。把“Sec-WebSocket-Key”加上一个特殊字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”,然后计算SHA-1摘要,之后进行BASE-64编码,将结果做为“Sec-WebSocket-Accept”头的值,返回给客户端。如此操作,可以尽量避免普通HTTP请求被误认为Websocket协议。
  • Sec-WebSocket-Version 表示支持的Websocket版本。RFC6455要求使用的版本是13,之前草案的版本均应当弃用。
  • Origin字段是可选的,通常用来表示在浏览器中发起此Websocket连接所在的页面,类似于Referer。但是,与Referer不同的是,Origin只包含了协议和主机名称。
  • 其他一些定义在HTTP协议中的字段,如Cookie等,也可以在Websocket中使用。

支持浏览器

实现websocket的协议,浏览器扮演着一个很重要的角色。所有最新的浏览器支持最新规范(RFC 6455)的WebSocket协议。一个详细的测试报告列出了这些浏览器支持的Websocket版本。

浏览器支持现状

协议发布日期IEFirefox(个人电脑)Firefox (Android)Chrome(个人电脑,手机)Safari(Mac, iOS)Opera(个人电脑,手机)Android浏览器
hixie-752010年2月4日   45.0.0  
hixie-76
hybi-00
2010年5月10日,
2010年5月23日
 4.0(已禁用) 65.0.111.00(已禁用) 
7 hybi-072011年4月22日 6[4]1     
8 hybi-102011年7月11日 7[5]1714[6]   
13 RFC 64552011年12月10[7]111116[8]612.10[9]4.4[10]

参考资料

WebSocket
https://zh.wikipedia.org/wiki/WebSocket

java WebSocket开发入门WebSocket

https://www.jianshu.com/p/d79bf8174196

WebSocket 教程

http://www.ruanyifeng.com/blog/2017/05/websocket.html

 

 

 

 

转载于:https://my.oschina.net/u/875122/blog/1791525

相关文章:

  • Easyui Tab使用
  • 通过DataWorks数据集成归档日志服务数据至MaxCompute进行离线分析
  • 分享 | 关于人工智能算法建模稳定性那些事儿
  • 金三银四,2019大厂Android高级工程师面试题整理
  • 函数的命名空间、作用域、闭包函数
  • 内核常见锁的机制与实现分析2
  • int,char指针探究
  • 安卓平台Flutter启动过程全解析
  • (4.10~4.16)
  • 高精度练习 - P1604 B进制星球
  • 小组第四次冲刺
  • 设计模式入门----设计模式的7大原则与23种设计模式概述(转载)
  • Jenkins手把手图文教程[基于Jenkins 2.164.1]
  • Kubernetes如何通过Device Plugins来使用NVIDIA GPU
  • 极乐技术周报(第二十三期)
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • __proto__ 和 prototype的关系
  • emacs初体验
  • gcc介绍及安装
  • Idea+maven+scala构建包并在spark on yarn 运行
  • Iterator 和 for...of 循环
  • JavaScript的使用你知道几种?(上)
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • LeetCode算法系列_0891_子序列宽度之和
  • PhantomJS 安装
  • Redis学习笔记 - pipline(流水线、管道)
  • Sublime text 3 3103 注册码
  • ubuntu 下nginx安装 并支持https协议
  • vue-router 实现分析
  • Vue官网教程学习过程中值得记录的一些事情
  • 创建一个Struts2项目maven 方式
  • 当SetTimeout遇到了字符串
  • 翻译--Thinking in React
  • 缓存与缓冲
  • 讲清楚之javascript作用域
  • 排序算法学习笔记
  • 如何在GitHub上创建个人博客
  • 深度学习入门:10门免费线上课程推荐
  • 移动端唤起键盘时取消position:fixed定位
  • 正则学习笔记
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • ​马来语翻译中文去哪比较好?
  • (0)Nginx 功能特性
  • (LeetCode C++)盛最多水的容器
  • (超详细)语音信号处理之特征提取
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (附源码)ssm基于web技术的医务志愿者管理系统 毕业设计 100910
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (一)Linux+Windows下安装ffmpeg
  • (转)ObjectiveC 深浅拷贝学习
  • (状压dp)uva 10817 Headmaster's Headache
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)