HTML5的Websocket(理论篇 I)
HTML5的Websocket(理论篇 I)
** 先请来TA的邻居:**
http:无状态、基于tcp请求/响应模式的应用层协议 (A:哎呀,上次你请我吃饭了么? B:我想想, 上次请你吃了么) tcp:面向连接、保证高可靠性(数据无丢失、数据无失序、数据无错误、数据无重复到达) 传输层协议。(看啊,大阅兵,如此规整有秩序)
为什么要引入Websocket:
RFC开篇介绍:本协议的目的是为了解决基于浏览器的程序需要拉取资源时必须发起多个HTTP请求和长时间的轮询的问题。
long poll(长轮询): 客户端发送一个request后,服务器拿到这个连接,如果有消息,才返回response给客户端。没有消息,就一直不返回response。之后客户端再次发送request, 重复上次的动作。
从上可以看出,http协议的特点是服务器不能主动联系客户端,只能由客户端发起。它的被动性预示了在完成双向通信时需要不停的连接或连接一直打开,这就需要服务器快速的处理速度或高并发的能力,是非常消耗资源的。
这个时候,Websocket出现了。
Websocket是什么:
RFC中写到:WebSocket协议使在控制环境下运行不受信任代码的客户端和能够选择与那些代码通信的远程主机之间能够双向通信。
对,划重点:双向通信
Websocket在连接之后,客户端可以主动发送消息给服务器,服务器也可以主动向客户端推送消息。比如:预订车票信息,除了我们发请求询问车票如何,当然更希望如果有新消息,可以直接通知我们。
其特点:
(1)握手阶段采用 HTTP 协议,默认端口是80和443
(2)建立在TCP协议基础之上,和http协议同属于应用层
(4)可以发送文本,也可以发送二进制数据
(5)没有同源限制,客户端可以与任意服务器通信
(6)协议标识符是ws(如果加密,为wss),如ws://localhost:8023
简单来说,Websocket协议分为两部分:握手和数据传输。
Websocket API:
这里是指客户端 API。
WebSocket 构造函数
通过调用WebSocket构造函数来创建一个WebSocket实例对象,建立客户端与服务器的连接。
const ws = new WebSocket('ws://localhost:8023');
Websocket事件
WebSocket 是纯事件驱动,通过监听事件可以处理到来的数据和改变的连接状态。服务端发送数据后,消息和事件会异步到达。
open:
服务端响应WebSocket连接请求,就会触发open事件。onopen是响应的回调函数。
// 连接请求open事件处理:
ws.onopen = e => {
console.log('Connection success');
ws.send(`Hello ${e}`);
};
如果要指定多个回调函数,可以使用addEventListener方法。
ws.addEventListener('open', e => {
ws.send(`Hello ${e}`);
});
当open事件触发时,意味着握手阶段已结束。服务端已经处理了连接的请求,可以准备收发数据。
Message:
收到服务器数据,会触发消息事件,onmessage是响应的回调函数。如下:
// 接受文本消息的事件处理:
ws.onmessage = e => {
const data = e.data;
if (typeof data === "string") {
console.log("Received string message ",data);
} else if (data instanceof Blob) {
console.log("Received blob message ", data);
}
};
服务器数据可能是文本,也可能是二进制数据,有Blob和ArrayBuffer两种类型,在读取到数据之前需要决定好数据的类型。
Error
发生错误会触发error事件, onerror是响应的回调函数, 会导致连接关闭。
//异常处理
ws.onerror = e => {
console.log("WebSocket Error: " , e);
handleErrors(e);
};
Close
当连接关闭时触发close事件,对应onclose方法,连接关闭之后,服务端和客户端就不能再通信。
WebSocket 规范中定义了ping 帧 和pong 帧,可以用来做心跳重连,网络状态查询等,但是目前 浏览器只会自动发送pong帧,而不会发ping 帧。(有兴趣可详查ping和pong帧)
//关闭连接处理
ws.onclose = e => {
const code = e.code;
const reason = e.reason;
console.log("Connection close", code, reason);
};
WebSocket 方法:
WebSocket 对象有两个方法:send 和 close
send:
客户端和服务器建立连接后,可以调用send方法去发送消息。
//发送一个文本消息
ws.send("this is websocket");
在open事件的回调中调用send()方法传送数据:
const ws = new WebSocket('ws://localhost:8023');
ws.onopen = e => {
console.log('Connection success');
ws.send(`Hello ${e}`);
};
如果想通过响应其他事件发送消息,可通过判断当前的Websocket的readyState属性。接下来会说到readyState.
close
close方法用来关闭连接。调用close方法后,将不能发送数据。close方法可以传入两个可选的参数,code 和reason, 以告诉服务端为什么终止连接。
ws.close(); //1000是状态码,代表正常结束。
ws.close(1000, "Closing normally");
WebSocket 属性
- readyState:
readyState值表示连接状态,是只读属性。它有以下四个值:
WebSocket.CONNECTING :连接正在进行,但还没有建立 WebSocket.OPEN :连接已经建立,可以发送消息 WebSocket.CLOSING :连接正在进行关闭握手 WebSocket.CLOSED :连接已经关闭或不能打开
除了在open事件回调中调用send方法,可通过判断readyState值来发送消息。
function bindEventHandler(data) {
if (ws.readyState === WebSocket.OPEN) {
ws.send(data);
} else {
//do something
}
}
bufferedAmount:
当客户端传输大量数据时,浏览器会缓存将要流出的数据,bufferedAmount属性可判断有多少字节的二进制数据没有发送出去,发送是否结束。
ws.onopen = function () {
setInterval( function() {
//缓存未满的时候发送
if (ws.bufferedAmount < 1024 * 5) {
ws.send(data);
}
}, 2000);
};
protocol:
protocol代表客户端使用的WebSocket协议。当握手协议未成功,这个属性是空。
** 接下来,我们说说握手阶段过程。**
当我们创建Websocket实例对象与服务器建立连接时,
const ws = new WebSocket('ws://localhost:8023');
首先客户端向服务器发起一个握手请求,其请求报文的内容如下:
GET /game HTTP/1.1
Host: 10.242.17.102:8023
Cache-Control: no-cache
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Protocol: game
Sec-WebSocket-Version: 10
Origin: http://192.168.185.16
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
从请求头中可以看出,其实是一个基于http的握手请求。与通常的http请求不同的是,增加了一些头信息。
- Upgrade字段: 通知服务器,现在要使用一个升级版协议 - Websocket。
- Sec-WebSocket-Key: 是一个Base64编码的值,这个是浏览器随机生成,通知服务器,需要验证下是否可以进行Websocket通信
- Sec_WebSocket-Protocol: 是用户自定义的字符串,用来标识服务所需要的协议
- Sec-WebSocket-Version: 通知服务器所使用的协议版本
服务器响应:
当服务器返回以下内容,就表示已经接受客户端请求啦,可以建立Websocket通信啦。
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: SIEylb7zRYJAEgiqJXaOW3V+ZWQ=
- 101 状态码,表示要转换协议啦
- Upgrde: 通知客户端将要升级成Websocket协议
- Sec-WebSocket-Accept: 经过服务器确认,并且加密过后的 Sec-WebSocket-Key。用来证明客户端和服务器之间能进行通信了。
至此,客户端和服务器握手成功建立了Websocket连接,通信不再使用http数据帧,而采用Websocket独立的数据帧。
以上是Websocket协议的基础理论篇I, 欢迎小伙伴儿们接力(理论篇II, 实战篇神马的), 一起学习一起积累~
如果你喜欢我们的文章,关注我们的公众号和我们互动吧。
HTML5的Websocket(理论篇 I)的更多相关文章
- 认识WebSocket理论篇
本文转自http://www.ibm.com/developerworks/cn/java/j-lo-WebSocket/ HTML5作为下一代WEB标准,拥有许多引人注目的新特性,如Canvas.本 ...
- 认识HTML5的WebSocket
在HTML5规范中,我最喜欢的Web技术就是正迅速变得流行的WebSocket API.WebSocket提供了一个受欢迎的技术,以替代我们过去几年一直在用的Ajax技术.这个新的API提供了一个方法 ...
- RabbitMQ学习总结 第一篇:理论篇
目录 RabbitMQ学习总结 第一篇:理论篇 RabbitMQ学习总结 第二篇:快速入门HelloWorld RabbitMQ学习总结 第三篇:工作队列Work Queue RabbitMQ学习总结 ...
- HTML5之WebSocket
在HTML5规范中,我最喜欢的Web技术就是正迅速变得流行的WebSocket API.WebSocket提供了一个受欢迎的技术,以替代我们过去几年一直在用的Ajax技术.这个新的API提供了一个方法 ...
- 【PHPsocket编程专题(理论篇)】初步理解TCP/IP、Http、Socket.md
前言 我们平时说的最多的socket是什么呢,实际上socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API).那TCP/IP又是什么呢?TCP/IP是ISO/OS ...
- Lucene核心--构建Lucene搜索(上篇,理论篇)
2.1构建Lucene搜索 2.1.1 Lucene内容模型 一个文档(document)就是Lucene建立索引和搜索的原子单元,它由一个或者多个字段(field)组成,字段才是Lucene的真实内 ...
- 游戏UI框架设计(一) : 架构设计理论篇
游戏UI框架设计(一) ---架构设计理论篇 前几天(2017年2月)看到一篇文章,国内王健林.马云等大咖们看好的未来十大最有"钱途"产业中,排名第一的就是"泛娱乐&qu ...
- HTML5 的WebSocket
认识HTML5的WebSocket
- 使用Html5下WebSocket搭建简易聊天室
一.Html5WebSocket介绍 WebSocket protocol 是HTML5一种新的协议(protocol).它是实现了浏览器与服务器全双工通信(full-duplex). 现在,很多网站 ...
随机推荐
- linux各类压缩解压命令大全
01-.tar格式解包:[*******]$ tar xvf FileName.tar 打包:[*******]$ tar cvf FileName.tar DirName(注:tar是打包,不是压缩 ...
- xml是什么,为什么要用xml
XML概念 众所周知,xml常用语数据存储和传输,文件后缀为 .xml: 它是可扩展标记语言(Extensible Markup Language,简称XML),是一种标记语言. 标记,指计算机所能理 ...
- Azure ARM (16) 基于角色的访问控制 (Role Based Access Control, RBAC) - 使用默认的Role
<Windows Azure Platform 系列文章目录> 今天上午刚刚和客户沟通过,趁热打铁写一篇Blog. 熟悉Microsoft Azure平台的读者都知道,在老的Classic ...
- python 库之lxml安装 坑一个
error: command 'C:\\Users\\Admin\\AppData\\Local\\Programs\\Common\\Microsoft\\Visual C++ for Python ...
- http_load压力测试windows版使用方法及结果分析
工具下载: https://pan.baidu.com/s/1gftN13H 配置说明:解压后将cygwin1.dll 放置到 C:\Windows\system目录下,将http_load.exe ...
- Tomcat的四种基于HTTP协议的Connector性能比较
Tomcat从5.5版本开始,支持以下四种Connector的配置分别为: <Connector port="8081" protocol="org.apache. ...
- 1042 数字0-9的数量 1050 循环数组最大子段和 1062 序列中最大的数 1067 Bash游戏 V2 1092 回文字符串
1042 数字0-9的数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 给出一段区间a-b,统计这个区间内0-9出现的次数. 比如 10-19,1出现11次 ...
- GBDT(MART)概念简介
GBDT(Gradient Boosting Decision Tree) 又叫 MART(Multiple Additive Regression Tree),是一种用于回归的机器学习算法,该算法由 ...
- tcpip第三章
1,ip协议不可靠.无连接特性介绍 不可靠:计算机A往计算机B发送数据报1,若途径的路由器缓存已满,或者ttl(time to live 生存周期)到了,则路由器直接丢弃数据包1,并产生icmp数据包 ...
- I/P/B/SI/SP帧和PTS/DTS的关系
I frame:帧内编码帧 又称intra picture,I 帧通常是每个 GOP(MPEG 所使用的一种视频压缩技术)的第一个帧,经过适度地压缩,做为随机访问的参考点,可以当成图象.I帧可以看成是 ...