WebSocket 网络通讯协议介绍

1、WebSocket是什么?

WebSocket 是一种网络通讯协议。RFC6455定义了它的通讯标准。javascript

WebSocket 是 HTML5 开始提供的一种在单个 TCP 链接上进行全双工通信的协议。html

2、为何须要WebSocket?

咱们知道,传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如 浏览器)主动发起,服务端进行处理后返回response结果,而服务端很难主动向客户端发送数据;这种客户端是主动方,服务端是被动方的传统Web模式 对于信息变化不频繁的Web应用来讲形成的麻烦较小,而对于涉及实时信息的Web应用却带来了很大的不便。vue

  所以,随着HTML5的诞生,一种新的通讯协议应运而生---WebSocket,他最大的特色就是服务端能够主动向客户端推送消息,客户端也能够主动向服务端发送消息,实现了真正的平等。java

举个例子:如带有即时通讯、实时数据、订阅推送等功能的应用。在WebSocket规范提出以前,开发人员若要实现这些实时性较强的功能,常常会使用折衷的解决方法:ajax轮询(最原始的实现实时Web应用的解决方案)web

ajax轮询的原理:ajax轮询的原理很是简单,让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。明显地,这种方法会致使过多没必要要的请求,浪费流量和服务器资源。
场景再现:
客户端:有没有新信息(Request)
服务端:没有(Response)
客户端:有没有新信息(Request)
服务端:没有。。(Response)
客户端:有没有新信息(Request)
服务端:你好烦啊,没有啊。。(Response)
客户端:有没有新消息(Request)
服务端:有啦,给你。(Response)
客户端:有没有新消息(Request)
服务端:。。。。。没。。。。没。。。没有(Response) ---- loopajax

websocket的原理:当服务器完成协议升级后(HTTP->Websocket),服务端就能够主动推送信息给客户端啦。
场景再现:
客户端:我要创建Websocket协议,须要的服务:chat,Websocket协议版本:17(HTTP Request)
服务端:确认,已升级为Websocket协议(HTTP Protocols Switched)
客户端:麻烦你有信息的时候推送给我噢。。
服务端:好的,有的时候会告诉你的。
服务端:balabalabalabala
服务端:哈哈哈哈哈啊哈哈哈哈
服务端:笑死我了哈哈哈哈哈哈哈浏览器

3、WebSocket其余特色以下:

(1)创建在 TCP 协议之上,服务器端的实现比较容易。服务器

(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,而且握手阶段采用 HTTP 协议,所以握手时不容易屏蔽,能经过各类 HTTP 代理服务器。websocket

(3)数据格式比较轻量,性能开销小,通讯高效。网络

(4)能够发送文本,也能够发送二进制数据。

(5)没有同源限制,客户端能够与任意服务器通讯。

(6)协议标识符是ws(若是加密,则为wss),服务器网址就是 URL。

4、建立WebSocket对象

浏览器经过 JavaScript 向服务器发出创建 WebSocket 链接的请求,链接创建之后,客户端和服务器端就能够经过 TCP 链接直接交换数据。当你获取 WebSocket 链接后,你能够经过 send() 方法来向服务器发送数据,并经过 onmessage 事件来接收服务器返回的数据。

// url, 指定链接的 URL
// protocol 是可选的,指定可接受的子协议。
let Socket = new WebSocket(url, [protocol] );
复制代码

5、WebSocket属性

假设咱们建立了一个Socket对象

属性 描述
Socket.readyState

只读属性 readyState 表示链接状态,能够是如下值:

0 - 表示链接还没有创建。

1 - 表示链接已创建,能够进行通讯。

2 - 表示链接正在进行关闭。

3 - 表示链接已经关闭或者链接不能打开。

Socket.bufferedAmount 只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,可是尚未发出的 UTF-8 文本字节数。

6、WebSocket事件

假设咱们建立了一个Socket对象

事件 事件处理程序 描述
open Socket.onopen 链接创建时触发
message Socket.onmessage 客户端接收服务端数据时触发
error Socket.onerror 通讯发生错误时触发
close Socket.onclose 链接关闭时触发

7、WebSocket方法

假设咱们建立了一个Socket对象

方法 描述
Socket.send()

使用链接发送数据

Socket.close()

关闭链接

8、WebSocket实例

【1】原生JavaScript实现WebSocket链接

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <style> </style> <body> <input id="text" type="text" /> <button onclick="send()">发送消息</button> <button onclick="closeWebSocket()">关闭WebSocket链接</button> <div id="message"></div> <script> let websocket = null; //判断当前浏览器是否支持WebSocket if ('WebSocket' in window) { websocket = new WebSocket("ws://localhost:8080/websocket"); } else { alert('当前浏览器不支持websocket!') } //链接发生错误的回调方法 websocket.onerror = function () { console.log("WebSocket链接发生错误"); }; //链接成功创建的回调方法 websocket.onopen = function () { console.log("WebSocket链接成功"); } //接收到消息的回调方法 websocket.onmessage = function (event) { document.getElementById('message').innerHTML += event.data + '<br/>'; } //链接关闭的回调方法 websocket.onclose = function () { console.log("WebSocket链接关闭"); } //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket链接,防止链接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = function () { closeWebSocket(); } //关闭WebSocket链接 function closeWebSocket() { websocket.close(); } //发送消息 function send() { let message = document.getElementById('text').value; websocket.send(message); } </script> </body> </html>复制代码

【2】在vue项目中实现WebSocket链接

<template> <div> <el-input v-model="params" clearable/> <el-button type="primary" @click="send">发消息</el-button> </div> </template> <script> export default { data() { return { params: '', path: "ws://localhost:8080/websocket", socket: "" } }, mounted() { // 初始化 this.init() }, destroyed() { // 销毁监听 this.socket.onclose = this.close }, methods: { init: function () { if (typeof (WebSocket) === "undefined") { console.log("您的浏览器不支持socket") } else { // 实例化socket this.socket = new WebSocket(this.path) // 监听socket链接成功回调 this.socket.onopen = this.open // 监听socket链接失败回调 this.socket.onerror = this.error // 监听后台返回的socket消息 this.socket.onmessage = this.getMessage } }, open: function () { console.log("socket链接成功") }, error: function () { console.log("链接错误") }, getMessage: function (msg) { console.log(msg.data) }, send: function () { this.socket.send(params) }, close: function () { console.log("socket已经关闭") } } } </script>复制代码
相关文章
相关标签/搜索