菜单

HTML5的Websocket(理论篇 I)

2019年2月17日 - Bootstrap

Websocket API:

此处是指客户端 API。

从上可以看出,http协议的特色是服务器不可以主动联系客户端,只好由客户端发起。它的被动性预示了在成就双向通讯时索要不停的总是或三番五次一直打开,那就须要服务器快速的处理速度或高并发的能力,是相当消功耗源的。

WebSocket 属性

readyState值表示连接意况,是只读属性。它有以下两个值:

WebSocket.CONNECTING :连接正在展开,但还未曾创制
WebSocket.OPEN :连接已经建立,可以发送新闻
WebSocket.CLOSING :连接正在举办关闭握手
WebSocket.CLOSED :连接已经关门或不能够开拓

除外在open事件回调中调用send方法,可经过判断readyState值来发送消息。

JavaScript

function bindEventHandler(data) { if (ws.readyState === WebSocket.OPEN)
{ ws.send(data); } else { //do something } }

1
2
3
4
5
6
7
function bindEventHandler(data) {
    if (ws.readyState === WebSocket.OPEN) {
        ws.send(data);
    } else {
        //do something
    }
}
JavaScript

ws.onopen = function () { setInterval( function() {
//缓存未满的时候发送 if (ws.bufferedAmount < 1024 \* 5) {
ws.send(data); } }, 2000); };

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f447934b7a325701025-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b7a325701025-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f447934b7a325701025-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b7a325701025-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f447934b7a325701025-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b7a325701025-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f447934b7a325701025-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b7a325701025-8">
8
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f447934b7a325701025-1" class="crayon-line">
ws.onopen = function () {
</div>
<div id="crayon-5b8f447934b7a325701025-2" class="crayon-line crayon-striped-line">
    setInterval( function() {
</div>
<div id="crayon-5b8f447934b7a325701025-3" class="crayon-line">
        //缓存未满的时候发送
</div>
<div id="crayon-5b8f447934b7a325701025-4" class="crayon-line crayon-striped-line">
        if (ws.bufferedAmount &lt; 1024 * 5) {
</div>
<div id="crayon-5b8f447934b7a325701025-5" class="crayon-line">
            ws.send(data);
</div>
<div id="crayon-5b8f447934b7a325701025-6" class="crayon-line crayon-striped-line">
        }
</div>
<div id="crayon-5b8f447934b7a325701025-7" class="crayon-line">
    }, 2000);
</div>
<div id="crayon-5b8f447934b7a325701025-8" class="crayon-line crayon-striped-line">
};
</div>
</div></td>
</tr>
</tbody>
</table>

接下去,我们说说握手阶段进度。

当大家创制Websocket实例对象与服务器建立连接时,

JavaScript

const ws = new WebSocket(‘ws://localhost:8023’);

1
const ws = new WebSocket(‘ws://localhost:8023’);

第叁客户端向服务器发起1个抓手请求,其请求报文的始末如下:

JavaScript

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

1
2
3
4
5
6
7
8
9
10
11
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请求例外的是,增加了一部分头消息。

服务器响应:

当服务器再次来到以下内容,就代表早已接受客户端请求啦,可以创设Websocket通讯啦。

JavaScript

HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade
Sec-WebSocket-Accept: SIEylb7zRYJAEgiqJXaOW3V+ZWQ=

1
2
3
4
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: SIEylb7zRYJAEgiqJXaOW3V+ZWQ=

图片 1

从那之后,客户端和服务器握手成功建立了Websocket连接,通讯不再使用http数据帧,而采纳Websocket独立的数据帧。


如上是Websocket商谈的基础理论篇I, 欢迎小伙伴儿们陆续(理论篇II,
实战篇神马的), 一起学习共同积累


1 赞 4 收藏
评论

图片 2

图片 3

Websocket是什么:

PRADOFC中写到:WebSocket协议使在控制环境下运作不受信任代码的客户端和可以挑选与这几个代码通讯的长距离主机之间可以双向通讯。

对,划重点:双向通信

Websocket在一连之后,客户端能够积极发送消息给服务器,服务器也得以当仁不让向客户端推送音讯。比如:预定车票音讯,除了大家发请求询问车票怎么样,当然更愿意倘诺有新新闻,可以从来通告大家。

其特点:

(1)握手阶段拔取 HTTP 协议,暗中同意端口是80和443

(2)建立在TCP协议基础之上,和http协议同属于应用层

(4)可以发送文书,也得以发送二进制数据

(5)没有同源限制,客户端可以与自由服务器通讯

(6)协议标识符是ws(假如加密,为wss),如ws://localhost:8023

粗略的话,Websocket探究分成两片段:握手和数量传输。

图片 4

Websocket是什么:

哈弗FC中写到:WebSocket协议使在控制环境下运营不受信任代码的客户端和力所能及拔取与那2个代码通信的中远距离主机之间可以双向通讯。

对,划重点:双向通讯

Websocket在连年之后,客户端能够主动发送消息给服务器,服务器也得以主动向客户端推送音讯。比如:预定车票音讯,除了大家发请求询问车票怎样,当然更期待倘若有新新闻,能够一向公告大家。

其特点:

(1)握手阶段采取 HTTP 协议,暗中认同端口是80和443

(2)建立在TCP协议基础之上,和http协议同属于应用层

(4)能够发送文书,也得以发送二进制数据

(5)没有同源限制,客户端可以与人身自由服务器通讯

(6)协议标识符是ws(倘诺加密,为wss),如ws://localhost:8023

简易的话,Websocket协议分成两局地:握手和多少传输。

图片 5

Websocket事件

WebSocket 是纯事件驱动,通过监听事件可以处理到来的数量和改变的接连情形。服务端发送数据后,音信和事件会异步到达。

JavaScript

// 连接请求open事件处理: ws.onopen = e =&gt; {
console.log('Connection success'); ws.send(\`Hello ${e}\`); };

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f447934b5b531196143-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b5b531196143-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f447934b5b531196143-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b5b531196143-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f447934b5b531196143-5">
5
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f447934b5b531196143-1" class="crayon-line">
 // 连接请求open事件处理:
</div>
<div id="crayon-5b8f447934b5b531196143-2" class="crayon-line crayon-striped-line">
     ws.onopen = e =&gt; {
</div>
<div id="crayon-5b8f447934b5b531196143-3" class="crayon-line">
         console.log('Connection success');
</div>
<div id="crayon-5b8f447934b5b531196143-4" class="crayon-line crayon-striped-line">
         ws.send(`Hello ${e}`);
</div>
<div id="crayon-5b8f447934b5b531196143-5" class="crayon-line">
     };
</div>
</div></td>
</tr>
</tbody>
</table>

如若要内定多少个回调函数,可以运用add伊芙ntListener方法。

JavaScript

ws.addEventListener(‘open’, e => { ws.send(`Hello ${e}`); });

1
2
3
ws.addEventListener(‘open’, e => {
  ws.send(`Hello ${e}`);
});

当open事件触发时,意味着握手阶段已截止。服务端已经处理了三番五次的乞请,可以准备收发数据。

JavaScript

// 接受文本消息的事件处理: ws.onmessage = e =&gt; { 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); } };

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f447934b62129912854-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b62129912854-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f447934b62129912854-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b62129912854-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f447934b62129912854-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b62129912854-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f447934b62129912854-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b62129912854-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f447934b62129912854-9">
9
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f447934b62129912854-1" class="crayon-line">
// 接受文本消息的事件处理:
</div>
<div id="crayon-5b8f447934b62129912854-2" class="crayon-line crayon-striped-line">
ws.onmessage = e =&gt; {
</div>
<div id="crayon-5b8f447934b62129912854-3" class="crayon-line">
    const data = e.data;
</div>
<div id="crayon-5b8f447934b62129912854-4" class="crayon-line crayon-striped-line">
    if (typeof data === &quot;string&quot;) {
</div>
<div id="crayon-5b8f447934b62129912854-5" class="crayon-line">
        console.log(&quot;Received string message &quot;,data);
</div>
<div id="crayon-5b8f447934b62129912854-6" class="crayon-line crayon-striped-line">
    } else if (data instanceof Blob) {
</div>
<div id="crayon-5b8f447934b62129912854-7" class="crayon-line">
        console.log(&quot;Received blob message &quot;, data);
</div>
<div id="crayon-5b8f447934b62129912854-8" class="crayon-line crayon-striped-line">
    }
</div>
<div id="crayon-5b8f447934b62129912854-9" class="crayon-line">
};
</div>
</div></td>
</tr>
</tbody>
</table>

服务器数据或者是文本,也或者是二进制数据,有Blob和ArrayBuffer两系列型,在读取到多少以前要求控制好数据的种类。

JavaScript

//异常处理 ws.onerror = e =&gt; { console.log("WebSocket Error: " ,
e); handleErrors(e); };

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f447934b66862080563-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b66862080563-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f447934b66862080563-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b66862080563-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f447934b66862080563-5">
5
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f447934b66862080563-1" class="crayon-line">
//异常处理
</div>
<div id="crayon-5b8f447934b66862080563-2" class="crayon-line crayon-striped-line">
ws.onerror = e =&gt; {
</div>
<div id="crayon-5b8f447934b66862080563-3" class="crayon-line">
    console.log(&quot;WebSocket Error: &quot; , e);
</div>
<div id="crayon-5b8f447934b66862080563-4" class="crayon-line crayon-striped-line">
    handleErrors(e);
</div>
<div id="crayon-5b8f447934b66862080563-5" class="crayon-line">
};
</div>
</div></td>
</tr>
</tbody>
</table>

WebSocket 规范中定义了ping 帧 和pong
帧,可以用来做心跳重连,网络状态查询等,可是当前
浏览器只会自动发送pong帧,而不会发ping 帧。(有趣味可详查ping和pong帧)

JavaScript

//关闭连接处理 ws.onclose = e => { const code = e.code; const reason
= e.reason; console.log(“Connection close”, code, reason); };

1
2
3
4
5
6
//关闭连接处理
ws.onclose = e => {
    const code = e.code;
    const reason = e.reason;
    console.log("Connection close", code, reason);
};

先请来TA的邻居:

http:无状态、基于tcp伸手/响应格局的应用层切磋(A:哎哎,上次您请作者吃饭了么? B:作者思想, 上次请你吃了么)
tcp:面向连接、保证高可相信性(数据无遗失、数据无失序、数据无不当、数据无重复到达)
传输层商讨。(看呀,大阅兵,如此规整有秩序)

干什么要引入Websocket:

HighlanderFC开篇介绍:本协议的目标是为了缓解基于浏览器的次序要求拉取财富时必须发起多少个HTTP请求和长日子的轮询的标题。

WebSocket 构造函数

通过调用WebSocket构造函数来成立2个WebSocket实例对象,建立客户端与服务器的连接。

JavaScript

const ws = new WebSocket(‘ws://localhost:8023’);

1
const ws = new WebSocket(‘ws://localhost:8023’);

WebSocket 方法:

WebSocket 对象有多少个法子:send 和 close

JavaScript

//发送一个文本消息 ws.send("this is websocket");

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5a72977999e3b847111158-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e3b847111158-2">
2
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5a72977999e3b847111158-1" class="crayon-line">
//发送一个文本消息
</div>
<div id="crayon-5a72977999e3b847111158-2" class="crayon-line crayon-striped-line">
ws.send(&quot;this is websocket&quot;);
</div>
</div></td>
</tr>
</tbody>
</table>

在open事件的回调中调用send()方法传送数据:

JavaScript

const ws = new WebSocket(‘ws://localhost:8023’); ws.onopen = e => {
console.log(‘Connection success’); ws.send(`Hello ${e}`); };

1
2
3
4
5
const ws = new WebSocket(‘ws://localhost:8023’);
ws.onopen = e => {
    console.log(‘Connection success’);
    ws.send(`Hello ${e}`);
};

假设想经过响应其余事件发送音讯,可透过判断当前的Websocket的readyState属性。接下来会说到readyState.

JavaScript

ws.close(); //1000是状态码,代表正常结束。 ws.close(1000, "Closing
normally");

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5a72977999e42958089470-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e42958089470-2">
2
</div>
<div class="crayon-num" data-line="crayon-5a72977999e42958089470-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e42958089470-4">
4
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5a72977999e42958089470-1" class="crayon-line">
ws.close();
</div>
<div id="crayon-5a72977999e42958089470-2" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5a72977999e42958089470-3" class="crayon-line">
//1000是状态码,代表正常结束。
</div>
<div id="crayon-5a72977999e42958089470-4" class="crayon-line crayon-striped-line">
ws.close(1000, &quot;Closing normally&quot;);
</div>
</div></td>
</tr>
</tbody>
</table>

WebSocket 方法:

WebSocket 对象有多少个主意:send 和 close

JavaScript

//发送一个文本消息 ws.send("this is websocket");

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f447934b6d916593124-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b6d916593124-2">
2
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f447934b6d916593124-1" class="crayon-line">
//发送一个文本消息
</div>
<div id="crayon-5b8f447934b6d916593124-2" class="crayon-line crayon-striped-line">
ws.send(&quot;this is websocket&quot;);
</div>
</div></td>
</tr>
</tbody>
</table>

在open事件的回调中调用send()方法传送数据:

JavaScript

const ws = new WebSocket(‘ws://localhost:8023’); ws.onopen = e => {
console.log(‘Connection success’); ws.send(`Hello ${e}`); };

1
2
3
4
5
const ws = new WebSocket(‘ws://localhost:8023’);
ws.onopen = e => {
    console.log(‘Connection success’);
    ws.send(`Hello ${e}`);
};

一旦想透过响应其余事件发送音信,可通过判断当前的Websocket的readyState属性。接下来会说到readyState.

JavaScript

ws.close(); //1000是状态码,代表正常结束。 ws.close(1000, "Closing
normally");

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f447934b73487491254-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b73487491254-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f447934b73487491254-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f447934b73487491254-4">
4
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f447934b73487491254-1" class="crayon-line">
ws.close();
</div>
<div id="crayon-5b8f447934b73487491254-2" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5b8f447934b73487491254-3" class="crayon-line">
//1000是状态码,代表正常结束。
</div>
<div id="crayon-5b8f447934b73487491254-4" class="crayon-line crayon-striped-line">
ws.close(1000, &quot;Closing normally&quot;);
</div>
</div></td>
</tr>
</tbody>
</table>

初稿出处:
走走前端   

HTML5的Websocket(理论篇 I)

2017/10/28 · HTML5 ·
websocket

初稿出处:
走走前端   

先请来TA的邻居:

http:无状态、基于tcp伸手/响应格局的应用层合计
(A:哎哎,上次你请自身吃饭了么? B:小编心想, 上次请您吃了么)
tcp:面向连接、有限协理高可信性(数据无遗失、数据无失序、数据无不当、数据无重复到达)
传输层商讨。(看呀,大阅兵,如此规整有秩序)

为啥要引入Websocket:

君越FC开篇介绍:本协议的目的是为着消除基于浏览器的先后要求拉取能源时务必发起七个HTTP请求和长日子的轮询的题材。

long poll(长轮询):
客户端发送2个request后,服务器得到这些延续,假设有消息,才回到response给客户端。没有音讯,就平素不回来response。之后客户端再次发送request,
重复上次的动作。

图片 6

从上可以看来,http协议的性状是服务器不可以主动互换客户端,只好由客户端发起。它的被动性预示了在落成双向通讯时须求不停的连天或一而再一贯打开,那就须要服务器火速的处理速度或高并发的能力,是可怜消耗财富的。

这一个时候,Websocket出现了。

本条时候,Websocket出现了。

WebSocket 构造函数

透过调用WebSocket构造函数来创制3个WebSocket实例对象,建立客户端与服务器的连天。

JavaScript

const ws = new WebSocket(‘ws://localhost:8023’);

1
const ws = new WebSocket(‘ws://localhost:8023’);

long poll(长轮询):
客户端发送3个request后,服务器得到这么些连续,倘诺有音讯,才回去response给客户端。没有音信,就径直不回去response。之后客户端再次发送request,
重复上次的动作。

Websocket事件

WebSocket 是纯事件驱动,通过监听事件可以处理到来的数额和转移的连天情形。服务端发送数据后,新闻和事件会异步到达。

JavaScript

// 连接请求open事件处理: ws.onopen = e =&gt; {
console.log('Connection success'); ws.send(\`Hello ${e}\`); };

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5a72977999e26474564720-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e26474564720-2">
2
</div>
<div class="crayon-num" data-line="crayon-5a72977999e26474564720-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e26474564720-4">
4
</div>
<div class="crayon-num" data-line="crayon-5a72977999e26474564720-5">
5
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5a72977999e26474564720-1" class="crayon-line">
 // 连接请求open事件处理:
</div>
<div id="crayon-5a72977999e26474564720-2" class="crayon-line crayon-striped-line">
     ws.onopen = e =&gt; {
</div>
<div id="crayon-5a72977999e26474564720-3" class="crayon-line">
         console.log('Connection success');
</div>
<div id="crayon-5a72977999e26474564720-4" class="crayon-line crayon-striped-line">
         ws.send(`Hello ${e}`);
</div>
<div id="crayon-5a72977999e26474564720-5" class="crayon-line">
     };
</div>
</div></td>
</tr>
</tbody>
</table>

假定要钦定多少个回调函数,可以接纳add伊芙ntListener方法。

JavaScript

ws.addEventListener(‘open’, e => { ws.send(`Hello ${e}`); });

1
2
3
ws.addEventListener(‘open’, e => {
  ws.send(`Hello ${e}`);
});

当open事件触发时,意味着握手阶段已了结。服务端已经处理了连年的伸手,可以准备收发数据。

JavaScript

// 接受文本消息的事件处理: ws.onmessage = e =&gt; { 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); } };

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5a72977999e30543698552-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e30543698552-2">
2
</div>
<div class="crayon-num" data-line="crayon-5a72977999e30543698552-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e30543698552-4">
4
</div>
<div class="crayon-num" data-line="crayon-5a72977999e30543698552-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e30543698552-6">
6
</div>
<div class="crayon-num" data-line="crayon-5a72977999e30543698552-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e30543698552-8">
8
</div>
<div class="crayon-num" data-line="crayon-5a72977999e30543698552-9">
9
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5a72977999e30543698552-1" class="crayon-line">
// 接受文本消息的事件处理:
</div>
<div id="crayon-5a72977999e30543698552-2" class="crayon-line crayon-striped-line">
ws.onmessage = e =&gt; {
</div>
<div id="crayon-5a72977999e30543698552-3" class="crayon-line">
    const data = e.data;
</div>
<div id="crayon-5a72977999e30543698552-4" class="crayon-line crayon-striped-line">
    if (typeof data === &quot;string&quot;) {
</div>
<div id="crayon-5a72977999e30543698552-5" class="crayon-line">
        console.log(&quot;Received string message &quot;,data);
</div>
<div id="crayon-5a72977999e30543698552-6" class="crayon-line crayon-striped-line">
    } else if (data instanceof Blob) {
</div>
<div id="crayon-5a72977999e30543698552-7" class="crayon-line">
        console.log(&quot;Received blob message &quot;, data);
</div>
<div id="crayon-5a72977999e30543698552-8" class="crayon-line crayon-striped-line">
    }
</div>
<div id="crayon-5a72977999e30543698552-9" class="crayon-line">
};
</div>
</div></td>
</tr>
</tbody>
</table>

服务器数据只怕是文本,也大概是二进制数据,有Blob和ArrayBuffer两序列型,在读取到多少从前需求控制好数据的类型。

JavaScript

//异常处理 ws.onerror = e =&gt; { console.log("WebSocket Error: " ,
e); handleErrors(e); };

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5a72977999e34725915317-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e34725915317-2">
2
</div>
<div class="crayon-num" data-line="crayon-5a72977999e34725915317-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e34725915317-4">
4
</div>
<div class="crayon-num" data-line="crayon-5a72977999e34725915317-5">
5
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5a72977999e34725915317-1" class="crayon-line">
//异常处理
</div>
<div id="crayon-5a72977999e34725915317-2" class="crayon-line crayon-striped-line">
ws.onerror = e =&gt; {
</div>
<div id="crayon-5a72977999e34725915317-3" class="crayon-line">
    console.log(&quot;WebSocket Error: &quot; , e);
</div>
<div id="crayon-5a72977999e34725915317-4" class="crayon-line crayon-striped-line">
    handleErrors(e);
</div>
<div id="crayon-5a72977999e34725915317-5" class="crayon-line">
};
</div>
</div></td>
</tr>
</tbody>
</table>

WebSocket 规范中定义了ping 帧 和pong
帧,可以用来做心跳重连,互联网状态查询等,不过方今浏览器只会自行发送pong帧,而不会发ping 帧。(有趣味可详查ping和pong帧)

JavaScript

//关闭连接处理 ws.onclose = e => { const code = e.code; const reason
= e.reason; console.log(“Connection close”, code, reason); };

1
2
3
4
5
6
//关闭连接处理
ws.onclose = e => {
    const code = e.code;
    const reason = e.reason;
    console.log("Connection close", code, reason);
};

Websocket API:

那里是指客户端 API。

WebSocket 属性

readyState值表示连接情形,是只读属性。它有以下多个值:

WebSocket.CONNECTING :连接正在开展,但还并未创制
WebSocket.OPEN :连接已经确立,可以发送新闻
WebSocket.CLOSING :连接正在举行倒闭握手
WebSocket.CLOSED :连接已经关门或不可以开拓

除却在open事件回调中调用send方法,可经过判断readyState值来发送消息。

JavaScript

function bindEventHandler(data) { if (ws.readyState === WebSocket.OPEN)
{ ws.send(data); } else { //do something } }

1
2
3
4
5
6
7
function bindEventHandler(data) {
    if (ws.readyState === WebSocket.OPEN) {
        ws.send(data);
    } else {
        //do something
    }
}
JavaScript

ws.onopen = function () { setInterval( function() {
//缓存未满的时候发送 if (ws.bufferedAmount &lt; 1024 \* 5) {
ws.send(data); } }, 2000); };

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5a72977999e48105878083-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e48105878083-2">
2
</div>
<div class="crayon-num" data-line="crayon-5a72977999e48105878083-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e48105878083-4">
4
</div>
<div class="crayon-num" data-line="crayon-5a72977999e48105878083-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e48105878083-6">
6
</div>
<div class="crayon-num" data-line="crayon-5a72977999e48105878083-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5a72977999e48105878083-8">
8
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5a72977999e48105878083-1" class="crayon-line">
ws.onopen = function () {
</div>
<div id="crayon-5a72977999e48105878083-2" class="crayon-line crayon-striped-line">
    setInterval( function() {
</div>
<div id="crayon-5a72977999e48105878083-3" class="crayon-line">
        //缓存未满的时候发送
</div>
<div id="crayon-5a72977999e48105878083-4" class="crayon-line crayon-striped-line">
        if (ws.bufferedAmount &lt; 1024 * 5) {
</div>
<div id="crayon-5a72977999e48105878083-5" class="crayon-line">
            ws.send(data);
</div>
<div id="crayon-5a72977999e48105878083-6" class="crayon-line crayon-striped-line">
        }
</div>
<div id="crayon-5a72977999e48105878083-7" class="crayon-line">
    }, 2000);
</div>
<div id="crayon-5a72977999e48105878083-8" class="crayon-line crayon-striped-line">
};
</div>
</div></td>
</tr>
</tbody>
</table>

接下去,我们说说握手阶段进度。

当大家创设Websocket实例对象与服务器建立连接时,

JavaScript

const ws = new WebSocket(‘ws://localhost:8023’);

1
const ws = new WebSocket(‘ws://localhost:8023’);

首先客户端向服务器发起2个抓手请求,其请求报文的始末如下:

JavaScript

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

1
2
3
4
5
6
7
8
9
10
11
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请求例外的是,扩充了部分头新闻。

服务器响应:

当服务器重返以下内容,就象征早已接受客户端请求啦,可以创建Websocket通信啦。

JavaScript

HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade
Sec-WebSocket-Accept: SIEylb7zRYJAEgiqJXaOW3V+ZWQ=

1
2
3
4
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: SIEylb7zRYJAEgiqJXaOW3V+ZWQ=

图片 7

由来,客户端和服务器握手成功建立了Websocket连接,通讯不再选取http数据帧,而使用Websocket独立的数据帧。


以上是Websocket协和的基础理论篇I, 欢迎小伙伴儿们交叉(理论篇II,
实战篇神马的), 一起念书共同积累


1 赞 3 收藏
评论

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图