HTML5 WebSocket 协议
1. 概述
1.1 说明
WebSocket:是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。
WebSocket原理是使用JavaScript调用浏览器的API发出一个WebSocket请求至服务器,经过一次握手,和服务器建立了TCP通讯,因为它本质上是一个TCP连接,所以数据传输过程中稳定性强,数据传输量比较小。
1.2 属性值
objSocket.readyState:只读属性readyState表示WebSocket连接状态,状态值分别为0,1,2,3。
0:表示连接尚未建立(connecting)。
1:表示连接已建立,可以进行通信(open)。
2:表示连接正在进行关闭(closing)。
3:表示连接已经关闭或者连接不能打开(closed)。
objSocket.bufferedAmount:只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。
1.3 事件
open:objSocket.onopen;连接建立时触发,即握手成功触发的事件。
message:objSocket.onmessage;客户端接收服务端数据时触发。
error:objSocket.onerror;通信发生错误时触发。
close:objSocket.onclose;连接关闭时触发。
1.4 方法
objSocket.send():使用连接发送数据。
objSocket.close():关闭连接。
2. WebSocket实例
2.1 webSocket使用
2.1.1 说明
WebSocket构造函数:用于创建一个WebSocket实例,执行后,客户端就会与服务端连接;var objSocket= new WebSocket('ws://localhost:8888/Demo'); 。
WebSocket.readyState:readyState属性返回实例对象的当前状态;if(objSocket.readyState ==WebSocket.CONNECTING){}; 。
WebSocket.onopen:用于制定连接成功后的回调函数; objSocket.onopen = function(evt) { console.log("Connection open ..."); objSocket.send("Hello WebSockets!"); }; 或者 objSocket.addEventListener('open', function (event) { objSocket.send('Hello Server!'); });
WebSocket.onclose:用于制定连接关闭后的回调函数; objSocket.onclose = function(event) { var code = event.code; var reason = event.reason; var wasClean = event.wasClean; }; 或者使用监听【objSocket.addEventListener('close',function(event){});】。
WebSocket.onmessage:用于指定收到服务器数据后的回调函数; objSocket.onmessage = function(event) { var data = event.data; }; 或者使用监听【objSocket.addEventListener('message',function(event){console.log(event.data)});】。其中服务器数据有可能是文本,也有可能是二进制数据,可使用(typeof event.data == String) 或 (event.data instanceof ArrayBuffer)进行判断数据类型。
WebSocket.onerror:用于指定报错时的回调函数; objSocket.onerror = function(event) {}; 或者 objSocket.addEventListener("error", function(event) {}); 。
var wsServer = 'ws://localhost:8888/Demo';
var objSocket= new WebSocket(wsServer);
objSocket.onopen = function (evt) { onOpen(evt) };
objSocket.onclose = function (evt) { onClose(evt) };
objSocket.onmessage = function (evt) { onMessage(evt) };
objSocket.onerror = function (evt) { onError(evt) };
function onOpen(evt) {
//可多个websocket访问(订阅),使用objSocket.send(订阅访问参数)进行发送
console.log("Connected to WebSocket server.");
}
function onClose(evt) {
console.log("Disconnected");
}
function onMessage(evt) {
//websocket返回数据信息处理(可处理open中send的多个订阅访问)
console.log('Retrieved data from server: ' + evt.data);
}
function onError(evt) {
console.log('Error occured: ' + evt.data);
}
WebSocket.send():send方法用于向服务器发送数据,可发送文本/Blob/ArrayBuffer数据。在发送订阅时若使用到json对象参数,需进行JSON.stringify()格式化参数。
//******************发送文本****************************
objSocket.send("Hello WebSockets!");
//******************发送Blob数据************************
var file = document.querySelector('input[type="file"]').files[0];
objSocket.send(file);
//******************发送ArrayBuffer********************
var img = canvas_context.getImageData(0, 0, 400, 320);
var binary = new Uint8Array(img.data.length);
for (var i = 0; i < img.data.length; i++) {
binary[i] = img.data[i];
}
objSocket.send(binary.buffer);
WebSocket.bufferedAmount:表示还有多少字节的二进制数据没有发送出去,可以用来判断发送是否结束。
var data = new ArrayBuffer(10000000);
objSocket.send(data); if (objSocket.bufferedAmount === 0) {
// 发送完毕
} else {
// 发送还没结束
}
2.2 webSocket握手
2.2.1 说明
建立一个websocket连接,客户端浏览器首先要向服务器发起一个HTTP请求,这个请求和通常的HTTP请求不同,包含了一些附加头信息,其中附加同信息"Upgrade:WebSocket"表明这是一个申请协议升级的HTTP请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务端的WebSocket连接建立,双方通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接 。
WebSocket使用ws或wss的统一资源标识符,类似https,其中wss表示在TLS之上的websocket。如:
ws://webapi.dev.example/wss/
wss://webapi.dev.example/wss/
websocket使用和HTTP相同的TCP端口,可以绕过大多数防火墙的限制。默认情况下,websocket协议使用80端口,运行在TLS之上时,默认使用443端口。
2.2.2 详解
websocket握手请求示例如下:
客户端请求:
GET / HTTP/1.1
Upgrade: websocket 说明:必须设置为Websocket,表示希望升级到Websocket协议
Connection: Upgrade 说明:必须设置为Upgrade,表示客户端希望升级连接
Host: example.com
Origin: http://example.com 说明:此项为可选,表示在浏览器中发起此websocket连接所在的页面,只包含协议和主机名称。
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ== 说明:随机的字符串,服务器会用这些数据来构造一个SHA-1的信息摘要。
把"Sec-WebSocket-Key"加上一个特殊字符串"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",然后计算SHA-1摘要,之后进行BASE-64编码,将结果作为"Sec-WebSocket-Accept"头的值返回给客户端,
如此操作,可以尽量避免普通HTTP请求被误认为Websocket协议。
Sec-WebSocket-Version: 13 说明:标志支持的websocket版本
服务器回应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
Sec-WebSocket-Location: ws://example.com/
2.3 webSocket 心跳
2.3.1 说明
在使用websocket过程中,可能会出现网络断开的情况(如信号不好或者网络临时关闭等),此时websocket连接已经断开,而浏览器不会执行websocket的onclose方法,我们无法知道连接是否已经断开,也就无法进行重新连接操作。故为了解决此问题,需使用websocket心跳进行检测websocket连接。
2.3.2 实例(vue文件)
依赖模块为 websocket ,页面引入使用 let W3CWebSocket = require('websocket').w3cwebsocket ;
export default {
data(){
return{
objWS: null,//WebSocket实例
wsUrl: "wss://xxx.xxx.xx",//WebSocket地址
lockReconnect: false,//避免WebSocket重复连接
heartJson: JSON.stringify({"method":"server.ping","params":[], "id":1}),//WebSocket心跳订阅
heartCheck: this.socketHeartCheck()//心跳检测对象
}
},
mounted: function() {
this.$nextTick(() => {
this.socketDisconnect();
this.createWebSocket(this.$data.wsUrl);
});
},
methods:{
// region WebSocket相关基础配置(创建/心跳/关闭等方法集合)
/**
* WebSocket连接断开
**/
socketDisconnect:function() {
let self = this;
if (window.onbeforeunload) {
window.onbeforeunload = function() {
self.$data.objWS.close();
self.$data.socketSubscribe =false;
};
} if (window.onunload) {
window.onunload = function() {
self.$data.objWS.close();
self.$data.socketSubscribe =false;
};
}
},
/**
* WebSocket心跳检测
**/
socketHeartCheck:function(){
let rootThis = this;
let socketHeart = {
timeout: 10000,
timeoutObj: null,
serverTimeoutObj: null,//多个订阅时此对象相关需删除
reset: function () {
clearTimeout(this.timeoutObj);
clearTimeout(this.serverTimeoutObj);
return this;
},
start: function () {
let self = this;
this.timeoutObj = setTimeout(function () {
rootThis.$data.objWS.send(rootThis.$data.heartJson);
self.serverTimeoutObj = setTimeout(function () {
rootThis.$data.objWS.close();
}, self.timeout)
},self.timeout)
}
};
return socketHeart;
},
/**
* 创建WebSocket
*/
createWebSocket:function (url) {
this.$data.objWS = new WebSocket(url);
this.handleWebSocket();
},
/**
* WebSocket相关连接操作
**/
handleWebSocket: function(){
let self =this;
self.$data.objWS.onopen = function (evt) {
self.$data.heartCheck.reset().start();
self.socketOpenSubscribe(evt);
};
self.$data.objWS.onclose = function (evt) {
self.socketClose(evt);
};
self.$data.objWS.onmessage = function (evt) {
self.socketMessage(evt);
};
self.$data.objWS.onerror = function (evt) {
self.socketError(evt)
};
},
/**
*关闭WebSocket连接
* @param evt
*/
socketClose:function (evt) {
this.socketReConnect(this.$data.wsUrl);
},
/**
* WebSocket连接错误
* @param evt
*/
socketError:function (evt) {
this.socketReConnect(this.$data.wsUrl);
},
/**
* WebSocket重新连接
* @param url
*/
socketReConnect:function (url) {
let self = this;
if (self.$data.lockReconnect) return;
self.$data.lockReconnect = true;
setTimeout(function () { //没连接上会一直重连,设置延迟避免请求过多
self.createWebSocket(url);
self.$data.lockReconnect = false;
}, 2000);
},
/**
* WebSocket订阅
* @param evt
*/
socketOpenSubscribe:function (evt) {
//使用send发送WebSocket访问订阅
},
/**
* WebSocket服务端返回信息
* @param evt
*/
socketMessage:function (evt) {
//evt.data获取数据信息
}
},
beforeDestroy: function() {
this.socketDisconnect();
}
}
HTML5 WebSocket 协议的更多相关文章
- HTML5 直播协议之 WebSocket 和 MSE
当前为了满足比较火热的移动 Web 端直播需求, 一系列的 HTML5 直播技术迅速的发展了起来. 常见的可用于 HTML5 的直播技术有 HLS, WebSocket 与 WebRTC. 今天我要向 ...
- HTML5新协议介绍 WebSocket
WebSocket protocol 是HTML5一种新的协议(protocol).它是实现了浏览器与服务器全双工通信(full-duplex). 现在,很多网站为了实现即时通讯(real-time) ...
- 五分钟学会HTML5的WebSocket协议
1.背景 很多网站为了实现推送技术,所用的技术都是Ajax轮询.轮询是在特定的的时间间隔由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器.这种传统的模式带来很明显的缺点 ...
- HTML5通讯协议——WebSocket
1.导入maven依赖 <!-- websocket --> <dependency> <groupId>org.springframework</group ...
- Demo源码放送:打通B/S与C/S !让HTML5 WebSocket与.NET Socket公用同一个服务端!
随着HTML5 WebSocket技术的日益成熟与普及,我们可以借助WebSocket来更加方便地打通BS与CS -- 因为B/S中的WebSocket可以直接连接到C/S的服务端,并进行双向通信.如 ...
- Websocket 协议解析
WebSocket protocol 是HTML5一种新的协议.它是实现了浏览器与服务器全双工通信(full-duplex). 现 很多网站为了实现即时通讯,所用的技术都是轮询(po ...
- WebSocket协议开发
一直以来,网络在很大程度上都是围绕着HTTP的请求/响应模式而构建的.客户端加载一个网页,然后直到用户点击下一页之前,什么都不会发生.在2005年左右,Ajax开始让网络变得更加动态了.但所有的HTT ...
- Websocket协议的学习、调研和实现
本文章同时发在 cpper.info. 1. websocket是什么 Websocket是html5提出的一个协议规范,参考rfc6455. websocket约定了一个通信的规范,通过一个握手的机 ...
- 打通B/S与C/S !让HTML5 WebSocket与.NET Socket公用同一个服务端!
随着HTML5 WebSocket技术的日益成熟与普及,我们可以借助WebSocket来更加方便地打通BS与CS -- 因为B/S中的WebSocket可以直接连接到C/S的服务端,并进行双向通信.如 ...
随机推荐
- 数据结构Java实现02----单向链表的插入和删除
文本主要内容: 链表结构 单链表代码实现 单链表的效率分析 一.链表结构: (物理存储结构上不连续,逻辑上连续:大小不固定) 概念: 链式存储结构是基于指针实现的.我们把一个数据 ...
- request.setCharacterEncoding()、response.setCharacterEncoding()的区别
request.setCharacterEncoding()是你设置获得数据的编码方式.response.setCharacterEncoding()是你响应时设置的编码.response.setCo ...
- c# c/s 框架读取的配置文件时是app.exe.config
c# c/s 框架读取的配置文件时是app.exe.config, 一般在bin中间中俄debug中或者Release中
- 将本地时间转换成 UTC 时间,0时区时间
// 将时间戳转换成日期格式: function timestampToTime(timestamp) { var date = new Date(timestamp);//时间戳为10位需*1000 ...
- vue框架导入百度地图API接口的方法
百度请求API接口:
- Python 21 Django 实用小案例1
实用案例 验证码与验证 KindEditor 组合搜索的实现 单例模式 beautifulsoup4 验证码与验证 需要安装Pillow模块 pip stall pillow ...
- mysql案例~mysql主从复制延迟概总
浅谈mysql主从复制延迟 1 概念解读 需要知道以下几点 1 mysql的主从同步上是异步复制,从库是串行化执行 2 mysql 5.7的并行复制能加速从库重做的速度,进一步缓解 主从同步的延迟问题 ...
- j假设程序需要要一个int烈血的刀变量来保存1英里所包含的步数(5280)为该变量编写一条声明语句。
j假设程序需要要一个int烈血的刀变量来保存1英里所包含的步数(5280)为该变量编写一条声明语句. final intFT_PER_MILE =5280
- Java对象的浅拷贝和深拷贝&&String类型的赋值
Java中的数据类型分为基本数据类型和引用数据类型.对于这两种数据类型,在进行赋值操作.方法传参或返回值时,会有值传递和引用(地址)传递的差别. 浅拷贝(Shallow Copy): ①对于数据类型是 ...
- Javascript - ExtJs - 数据
数据(ExtJs Data) Ext.data命名空间 有关数据存储.读取的类都定义在Ext.data命名空间中.Ext的gridPanel.combobox的数据源都是来自Ext.data提供的类. ...