WebSocket系列之基础知识入门篇

概述

本文是WebSocket系列的第一篇,主要介绍WebSocket相关的基础协议知识和API。因为WebSocket的相关介绍在MDN中分布较乱,初学者不太容易入门,所以经过本文将相关基础知识和使用方法进行一个概括和总结。javascript

本文主要内容以下:html

  • WebSocket基础概念介绍
  • WebSocket协议初读
  • WebSocket 相关API浅析
  • WebSocket在线上项目中的使用

经过本文,你可以了解到WebSocket相关基础知识,同时了解到WebSocket在线上环境中是如何使用的。java

WebSocket介绍

WebSockets 是一个能够建立和服务器间进行双向会话的高级技术。经过这个API你能够向服务器发送消息并接受基于事件驱动的响应,这样就不用向服务器轮询获取数据了。web

上面是MDN中关于WebSocket的说明。其中双向会话指的是客户端和服务端都可以经过WebSocket来进行数据的互相传递,即服务端能够给客户端推送数据,客户端也能够经过WebSocket来传递数据。服务器

为何要使用WebSocket

在不使用WebSocket时,若是咱们须要创建一条长链接,有如下几种方法:websocket

  • 轮询
  • 长轮询(经常使用)
  • SSE(Server Send Event)

下面,咱们对这几个都进行简单的介绍。网络

轮询

轮询是最先在客户端用来模拟长链接的一种方式。他经过客户端定时想服务端发送HTTP请求来模拟客户端向服务端发送数据,而服务端的数据则是在客户端发送HTTP请求后跟随返回。socket

这种方案可以让客户端的数据几乎实时的到达,可是缺点也显而易见:服务端的数据须要在客户端的请求回来后才能带回。若是HTTP请求的间隔过短,则会致使大量的网络开销;若是间隔太长,这将致使数据传递的不及时。函数

长轮询

长轮询是在轮询的基础上改进的一种方式。在客户端发送HTTP请求且服务端收到请求时,服务端会先维持这个请求不返回。在特定的时间内(通常为30秒,由于一般HTTP判断超时时间为30秒),若是服务端没有数据,则回应这个请求;服务端有数据须要发送时,则当即经过HTTP请求的响应将数据传递给客户端。客户端收到响应后,当即发起下一次的HTTP请求。性能

这种方案可以解决轮询中带来的服务端数据不能及时传递的问题,可是带来的网络花销大的问题仍然没法解决。

SSE(Server Send Event)

SSE是一个新的协议,做用为服务端想客户端推送数据。他经过自定义的SSE协议来实现单项的数据推送。SSE的缺点是数据只能从服务端像客户端传递,而数据不能经过客户端向服务端传递。

WebSocket可以解决上述问题

WebSocket可以有效的解决如下问题:

  1. 带宽问题:WebSocket相对于HTTP来讲协议头更加小,同时按需传递。
  2. 数据实时性问题:WebSocket相对于轮询和长轮询来讲,可以实时传递数据,延迟更小。
  3. 状态问题:相较于HTTP的无状态请求,WebSocket在创建链接后可以维持特定的状态。

其余的优势能够参考维基百科

WebSocket协议

了解了为何须要使用WebSocket,下面让咱们来了解下WebSocket协议相关的内容。

WebSocket协议是经过HTTP协议升级而来。只须要在HTTP协议基础上增长两次握手,便可创建WebSocket链接(若是是须要经过SSL加密,则还须要进行SSL握手过程),握手的部分详情能够见WebSocket文档,下面咱们简单介绍如下Header相关字段。

请求Header

请求Header以下:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
复制代码

其中:

  • Host: server.example.com:表示将要链接的WebSocket地址。
  • Connection: Upgrade:须要升级HTTP链接。
  • Upgrade: websocket:将HTTP链接升级至WebSocket链接。
  • Sec-WebSocket-Key:dGhlIHNhbXBsZSBub25jZQ==:客户端生成的WebSocket链接密钥。
  • Sec-WebSocket-Protocol: chat, superchat:指定哪些协议是客户端能够接受的。
  • Sec-WebSocket-Version: 13:WebSocket版本号。

响应Header

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat
复制代码

其中:

  • Upgrade: websocket:确认将HTTP链接升级至WebSocket链接。
  • Connection: Upgrade:确认升级HTTP链接。
  • Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo:服务端根据客户端的链接密钥生成的服务端密钥。
  • Sec-WebSocket-Protocol: chat:选择的WebSocket协议。

WebSocket API介绍

对WebSocket的协议有了一个初步的了解,下面让咱们看下,在具体的使用场景中,如何使用WebSocket。

WebSocket的API很少,下面咱们就根据使用的顺序:

  • 创建链接
  • 收到消息
  • 发送消息
  • 关闭链接

来逐一进行介绍,具体的MDN资料能够见此处

创建链接

WebSocket经过初始化实例来创建链接,经过open事件回调函数来确认链接创建成功,具体示例以下:

const webSocket = new WebSocket('ws://server.example.com');

webSocket.addEventListener('open', (event) => {
    // 创建链接成功
});
复制代码

在WebSocket创建ws链接时,url能够是域名或者IP地址;可是当创建的链接是wss(加密WebSocket)时,url必须是域名,由于须要配置相应的证书,而证书是针对域名的。

收到消息

WebSocket经过message事件来接收消息。

socket.addEventListener('message', function (event) {
    console.log('Message from server', event.data);
});
复制代码

WebSocket能够传递StringArrayBufferBlob三种数据类型,所以在收到消息时多是其中的任意一种。其中,StringArrayBuffer使用的最多。

  • 若是是String类型,直接经过字符串处理函数便可进行相关转换,如JSON等格式。

  • 若是是二进制ArrayBuffer类型,则须要使用DataView来进行处理,相关的内容将在本系列第二篇中进行介绍。

发送消息

WebSocket经过send方法来发送消息。

webSocket.send(data);
复制代码

示例中的data字段,也有多是收到消息所说的StringArrayBufferBlob三种数据类型之一。其中,Blob做为一种类文件数据类型,再此不进行过多介绍。咱们使用最多的就是StringArrayBuffer

  • String类型只须要传递一个字符串给send方法做为参数便可。
  • ArrayBuffer类型则须要传递一个ArrayBuffer对象做为参数,相关的内容也将在本系列第二篇中进行介绍。

关闭链接

被动关闭

当服务端主动关闭WebSocket链接时,会经过WebSocket向客户端发送一个close数据包,WebSocket的close事件会触发。

webSocket.addEventListener('close', (closeEvent) => {
    
});
复制代码

注:当网络断开时,WebSocket链接并不会被动关闭,由于没有收到关闭的数据包。

主动关闭

客户端能够经过WebSocket提供的close方法来主动关闭长链接。

webSocket.close();
复制代码

目前该方法有两个参数(在某些版本中不支持,详情见MDN文档):

  • 第一个参数表示关闭链接的状态号,默认为1000,表示正常关闭。
  • 第二个参数为关闭缘由,是一个不长于123字节的UTF-8文本。

总结

本文主要是介绍了一下WebSocket相关的基础知识。

经过WebSocket的长链接,客户端和服务端能够进行大量的数据传输而不会带来相关的性能问题,这给Web端带来了极大的功能加强。目前Web端可使用WebSocket来进行IM相关功能开发,或者实时协做等须要与服务端进行大量数据交互的功能,而且不须要像以前同样使用长轮询的Hack方式来实现。

具体的使用方式和线上的使用问题,将会在本系列后几篇博客中进行介绍。

相关文章
相关标签/搜索