当前位置:网站首页>初识WebSocket
初识WebSocket
2022-06-09 21:57:00 【lilly呀】
背景:
最近,在做数魔方系统,里面有一部分人脸图像的采集,是通过websocket方式下发数据的,在此,特地记录一下,方便了解websocket的相关知识。
一、为什么需要websocket呢?
初次接触websocket的人,都会问同样的问题:我们已经有了HTTP协议,为什么还需要另一个协议?它能带来什么好处?
答案很简单,因为HTTP协议有一个缺陷:通信只能由客户端发起。
比如,当我们想了解今天的天气的时候,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP协议做不到服务器主动向客户端推送信息。
而WebSocket协议在2008年诞生,2011年成为国际标准。所有游览器都已经支持了。
它的最大特点是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
二、传统的实现即时通信的方式
ajax轮询
ajax轮询的原理非常简单,让游览器隔个几秒就发送一次请求,询问服务器是否有新信息。
long poll
long poll其实原理跟ajax轮询差不多,都是采用轮询的方式,不过采取的是阻塞模型(一直打电话,没收到就不挂电话),也就是说,客户端发起连接后,如果没消息,就一直不返回Response给客户端。直到有消息才返回,返回完之后,客户端再次建立连接,周而复始。
小结:
ajax轮询,需要服务器有很快的处理速度和资源(速度);
long poll,需要有很高的并发,额就是说同时接待客户的能力。(场地大小)
长连接
在页面里嵌入一个隐藏iframe,将这个隐藏iframe的src属性设为对一个长连接的请求或是采用xhr请求,服务器端就能源源不断地往客户端输入数据。
优点:消息及时到达,不发无用请求;管理起来也相对方便;
缺点:服务器维护一个长连接会增加开销,当客户端越来越多的时候,server压力大。
实例:Gmail聊天
Flash Socket
在也没按中内嵌入一个使用了Socket类的Flash程序JavaScript通过调用此Flash程序提供的Socket接口与服务端接口进行通信,JavaScript在接收到服务端传送的信息后控制页面的显示。
优点:实现真正的即时通信,而不是伪及时。
缺点:客户端必须安装Flash插件,移动端支持不好,IOS系统中没有Flash的存在;非HTTP协议,无法自动穿越防火墙。
实例:网络互动游戏。
三、websocket的方式实现服务端消息推送
websocket是html5规范中的一个部分,它借鉴了socket这种思想,为web应用程序客户端和服务端之间(注意是客户端服务端)提供了一种全双工通信机制。同时,它又是一种新的应用层协议,websocket协议是为了提供web应用程序和服务端全双工通信而专门制定的一种应用层协议,通常它表示为:ws://echo.websocket.org/?encoding=text HTTP/1.1,可以看到除了前面的协议名和http不同之外,它的表示地址就是传统的url地址。
websocket其实是一种新协议,跟HTTP协议基本没有关系,只是为了兼容现有游览器的握手规范而已。
websocket具有以下几个方面的优势:
- 建立在TCP协议之上,服务端的实现比较容易;
- 与HTTP协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用HTTP协议,因此握手时不容易屏蔽,能通过各种HTTP代理服务器;
- 数据格式比较轻量,性能开销小,通信高效;
- 可以发送文本,也可以发送二进制数据;
- 没有同源限制,客户端可以与任意服务器通信;
- 协议标识符是ws(如果加密,则为wss),服务器网址就是url。
四、客户端的简单示例
websocket的用法相当简单。
下面是一个网页脚本的例子,基本上一眼就能明白。
var ws = new WebSocket("wss://echo.websocket.org");
ws.onopen = function(evt) {
console.log("Connection open ...");
ws.send("Hello WebSockets!");
};
ws.onmessage = function(evt) {
console.log( "Received Message: " + evt.data);
ws.close();
};
ws.onclose = function(evt) {
console.log("Connection closed.");
};
五、客户端API
websocket客户端的API如下:
5.1websocket构造函数
websocket对象作为一个构造函数,用于新建websocket实例。
var ws = new WebSocket('ws://localhost:8080');
执行上面语句之后,客户端就会与服务器进行连接。
5.2 webSocket.readyState
readyState属性返回实例对象的当前状态,共有四种。
- CONNECTING:值为0,表示正在连接。
- OPEN:值为1,表示连接成功,可以通信了。
- CLOSING:值为2,表示连接正在关闭。
- CLOSED:值为3,表示连接已经关闭,或者打开连接失败。
下面是一个示例。
switch (ws.readyState) {
case WebSocket.CONNECTING:
// do something
break;
case WebSocket.OPEN:
// do something
break;
case WebSocket.CLOSING:
// do something
break;
case WebSocket.CLOSED:
// do something
break;
default:
// this never happens
break;
}
5.3 webSocket.onopen
实例对象的onopen属性,用于指定连接成功后的回调函数。
ws.onopen = function () {
ws.send('Hello Server!');
}
如果要指定多个回调函数,可以使用addEventListener方法。
ws.addEventListener('open', function (event) {
ws.send('Hello Server!');
});
5.4 webSocket.onopen
实例对象的onclose属性,用于指定连接关闭后的回调函数。
ws.onclose = function(event) {
var code = event.code;
var reason = event.reason;
var wasClean = event.wasClean;
// handle close event
};
ws.addEventListener("close", function(event) {
var code = event.code;
var reason = event.reason;
var wasClean = event.wasClean;
// handle close event
});
5.5 webSocket.onmessage
实例对象的onmessage属性,用于指定收到服务器数据后的回调函数。
ws.onmessage = function(event) {
var data = event.data;
// 处理数据
};
ws.addEventListener("message", function(event) {
var data = event.data;
// 处理数据
});
注意,服务器数据可能是文本,也可能是二进制数据(blob对象或Arraybuffer对象)。
ws.onmessage = function(event){
if(typeof event.data === String) {
console.log("Received data string");
}
if(event.data instanceof ArrayBuffer){
var buffer = event.data;
console.log("Received arraybuffer");
}
}
除了动态判断收到的数据类型,也可以使用binaryType属性,显式指定收到的二进制数据类型。
// 收到的是 blob 数据
ws.binaryType = "blob";
ws.onmessage = function(e) {
console.log(e.data.size);
};
// 收到的是 ArrayBuffer 数据
ws.binaryType = "arraybuffer";
ws.onmessage = function(e) {
console.log(e.data.byteLength);
};
5.6 webSocket.send()
实例对象的send()方法用于向服务器发送数据。
发送文本的例子。
ws.send('your message');
发送Blob对象的例子。
var file = document
.querySelector('input[type="file"]')
.files[0];
ws.send(file);
发送ArrayBuffer对象的例子。
// Sending canvas ImageData as 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];
}
ws.send(binary.buffer);
5.7 webSocket.bufferedAmount
实例对象的bufferedAmount属性,表示还有多少字节的二进制数据没有发送出去。它可以用来判断发送是否结束。
var data = new ArrayBuffer(10000000);
socket.send(data);
if (socket.bufferedAmount === 0) {
// 发送完毕
} else {
// 发送还没结束
}
5.8 webSocket.onerror
实例对象的onerror属性,用于指定报错时的回调函数。
socket.onerror = function(event) {
// handle error event
};
socket.addEventListener("error", function(event) {
// handle error event
});
六、具体运用示例
inits (typeSn) {
let self = this
if (window.WebSocket) {
let websocket = new WebSocket('ws://139.196.147.121:8088/websocket');//测试
websocket.onopen = function() {
let sn = {
"online": typeSn || "450_1_"};
websocket.send(JSON.stringify(sn));
let timer = setInterval(function() {
self.keepalive(websocket)
}, 60000);
};
websocket.onerror = function() {
};
websocket.onclose = function() {
// setTimeout(self.getCustomerFace(),60000)
self.inits();
};
// 消息接收
websocket.onmessage = function(message) {
console.log(message, 1111);
self.showMessage(message);
};
window.onbeforeunload = function() {
websocket.close();
}
} else {
alert("该浏览器不支持WebSocket。<br/>建议使用高版本的浏览器,<br/>如 IE10、火狐 、谷歌 、搜狗等");
}
},

参考博客:
WebSocket 教程 https://www.ruanyifeng.com/blog/2017/05/websocket.html
Websocket(一)——原理及基本属性和方法 https://www.cnblogs.com/cangqinglang/p/8331120.html
边栏推荐
- Digital engineering construction enterprises carry out "safety production month" activities in this way
- Know how to pay attention to the hot 25K problem, self-study software testing, and how much you need to learn to find a job?
- 使用addr2line分析Native Crash
- Bonner photoelectric switch sm912lvqd
- [translation paper] a progressive morphological filter for removing nonground measurements from airport lidar dat
- M-Arch(番外14)GD32L233评测-驱动段码LCD
- 在 4GB 物理内存的机器上,申请 8G 内存会怎么样?
- Systematic goal - Fitness collection
- 后疫情时代裸辞后面试软件测试工程师被拒,写下一些感悟和面试心得
- Do your filial duty to make an old people's fall prevention alarm system for your family
猜你喜欢

Que se passe - t - il si vous appliquez 8G sur une machine avec 4go de mémoire physique?

Digital engineering construction enterprises carry out "safety production month" activities in this way

10个常见触发IO瓶颈的高频业务场景

im即时通讯开发:移动端协议UDP还是TCP?

Industrial Internet + Digital Integrated Management cloud platform for hazardous chemical safety production

【图像重建】基于正则化的图像超分辨重建附matlab代码

目前28岁,从20年开始北漂闯荡到入职软件测试,我成功捧起15K薪资

St link V2 Download: internal command error & error: flash download failed - target DLL has been canceled

元宇宙并非法外之地,该如何保护个人权益?

Do your filial duty to make an old people's fall prevention alarm system for your family
随机推荐
Huawei device configuration hub and spoke
The survey shows that MacOS application developers generally say that their biggest challenge is how the product is discovered by users
Fire tongs Liu Ming ~ a little interview suggestion summarized from the three-year small test of Dai Zhuan
如何实现高效的IM即时通讯长连接自适应心跳保活机制
M-Arch(番外10)GD32L233评测-SPI驱动DS1302
数字化工程施工企业这样开展“安全生产月”活动
86. (leaflet house) leaflet military plotting - collection of linear arrows
NPM and yarn
Actions before purchasing memory modules
FPN-Feature Pyramid Network
Define requestanimationframe to execute once a second
[Luogu p8330] mode (radical divide and conquer)
SQL高级处理
基础查询语句
Erc20 protocol API interface specification
目前28岁,从20年开始北漂闯荡到入职软件测试,我成功捧起15K薪资
设计备忘录解矩阵链(动态规划法)的一些思考
还在怀疑数字藏品么?国家队都开始入局了
The fourth paradigm chenyuqiang: the next generation technology of enterprise intelligent decision-making "reinforcement learning + environmental learning"
Chez scheme environment setup