webSocket是什么
WebSocket是一种先进的网络技术,它提供了一种在单个TCP连接上进行全双工通信的能力。传统的基于HTTP的通信是单向的,即客户端发起请求,服务器响应请求,然后连接关闭。但是,WebSocket允许服务器和客户端之间建立长时间的连接,双方可以通过该连接进行双向数据传输,而不需要客户端重新发起HTTP请求。
主要特点和优势:
全双工通信:WebSocket允许服务器和客户端之间实时、双向的数据传输,使得实时性要求较高的应用(如聊天应用、在线游戏等)可以更高效地工作。
低延迟:相比传统的HTTP轮询方式,WebSocket可以减少通信的延迟,因为不需要在每次通信中都重新建立连接。
更少的通信开销:由于WebSocket在连接建立后可以保持打开状态,不需要在每次通信中发送HTTP头部信息,从而减少了通信开销。
跨域支持:与HTTP不同,WebSocket可以跨域进行通信,这意味着可以在不同域名的服务器之间建立WebSocket连接。
安全性:WebSocket可以通过TLS/SSL进行加密,确保数据传输的安全性。
使用场景:
实时聊天应用:WebSocket使得聊天应用程序能够实时地发送消息并接收响应,而无需轮询服务器。
在线游戏:多人在线游戏通常需要实时的双向通信,WebSocket能够提供这种功能,以支持游戏状态同步和实时动作响应。
实时数据更新:例如股票市场报价、天气预报等需要实时更新的应用可以使用WebSocket来推送数据。
协作应用:多人协作编辑、协同绘图等需要多方实时互动的应用可以受益于WebSocket的实时通信能力。
总结来说,WebSocket是一种强大的通信协议,它可以长时间保持连接状态,只需要验证一次信息就可以长时间多次的交换信息,
webSocket的工作流程
在页面中使用webSocket连接到服务器,服务器验证后开启连接,此时页面和服务器之间可以随意发送信息,同时,服务器可以和多个页面同时连接,这表示它可以实现广播效果,将数据发送给所有页面,
以上是webSocket的页面和服务端连接,和多个页面的通信模型
webSocket对象
WebSocket
对象提供了用于创建和管理 WebSocket 连接,以及可以通过该连接发送和接收数据的 API
WebSocket
构造函数
WebSocket(url[, protocols])
// 返回一个 WebSocket 对象。
url
通信的服务地址
protocols 可选
一个协议字符串或者一个包含协议字符串的数组。
WebSocket
常量
WebSocket
实例属性
- WebSocket.binaryType 使用二进制的数据类型连接。
- WebSocket.bufferedAmount 只读 未发送至服务器的字节数。
- WebSocket.extensions 只读 服务器选择的扩展。
- WebSocket.onclose 用于指定连接关闭后的回调函数。
- WebSocket.onerror 用于指定连接失败后的回调函数。
- WebSocket.onmessage 用于指定当从服务器接受到信息时的回调函数。
- WebSocket.onopen 用于指定连接成功后的回调函数。
- WebSocket.protocol 只读 服务器选择的下属协议。
- WebSocket.readyState 只读 当前的链接状态。
- WebSocket.url 只读 WebSocket 的绝对路径。
主要的方法
关闭连接
WebSocket.close(code,reason);
code 可选
一个数字状态码,它解释了连接关闭的原因。如果没有传这个参数,默认使用 1005,状态码不能小于1000
reason 可选
一个人类可读的字符串,它解释了连接关闭的原因。这个 UTF-8 编码的字符串不能超过 123 个字节。
发送数据
WebSocket.send(data);
data : 用于传输至服务器的数据。
data必须是以下类型之一:
String
文本字符串。字符串将以 UTF-8 格式添加到缓冲区,并且 bufferedAmount 将加上该字符串以 UTF-8 格式编码时的字节数的值。
ArrayBuffer
你可以使用类型化数组对象发送底层二进制数据;其二进制数据内存将被缓存于缓冲区,bufferedAmount 将加上所需字节数的值。
Blob
Blob 类型将队列 blob 中的原始数据以二进制中传输。 bufferedAmount 将加上原始数据的字节数的值。
ArrayBufferView
你可以以二进制帧的形式发送任何 JavaScript 类数组对象 ;其二进制数据内容将被队列于缓冲区中。值 bufferedAmount 将加上必要字节数的值。
也就是说只能传输,字符串和二进制文件数据,有关二进制文件类型可以参考:
js二进制数据,文件---ArrayBuffer,二进制数组_js arraybuffer()-CSDN博客
js二进制数据,文件---blob对象_js 输出 blob-CSDN博客
主要事件
一共有 4 个事件:
open
—— 连接已建立,message
—— 接收到数据,error
—— WebSocket 错误,close
—— 连接已关闭。
当链接状态改变时,会触发对应的事件
使用nodejs本地服务模拟webSocket服务,实现页面实时通信
新建3个文件,
index.html : 通信的页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<textarea name="" cols="30" rows="10" id="text"></textarea>
<input type="file" name="" id="file">
<script>
</script>
<script src="webSocket.js"></script>
</body>
</html>
webSocket.js:页面通信的逻辑
const socket = new WebSocket('ws://localhost:5000');
const text = document.getElementById('text');
const file = document.getElementById('file');
file.onchange = (e) => {
const file = e.target.files[0];
const blob = new Blob([file], { type: 'image/jpeg' });
socket.send(blob);
}
window.onkeydown = (e) => {
// console.log(e.keyCode)
if (e.keyCode === 13) {//回车
e.preventDefault();
if (socket.readyState === WebSocket.OPEN) {
socket.send(text.value);
}
}
}
socket.onopen = function (event) {
console.log(socket);
console.log('连接到服务器');
socket.send('Hello, 服务器!');
}
socket.onmessage = function (event) {
// console.log(event)
console.log('收到消息: ', event.data);
let p = document.createElement('p');
p.innerText = event.data;
document.body.appendChild(p);
}
socket.onclose = function (event) {
console.log('连接已关闭');
}
server.js:启动本地webSocket服务
实现webSocket本地服务需要先安装ws包
npm install ws
// 启动一个支持websocket的nodejs服务
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 5000 });
wss.on('connection', function (ws) {
ws.on('message', function (message) {
// 广播消息到所有客户端,除开发送端ws
wss.clients.forEach(function (client) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send("来自其他页面的消息:"+message);
}
});
console.log('received: %s', message);
ws.send('服务器收到消息:' + message);
});
ws.send('你已连接到WebSocket服务器');
});
console.log('WebSocket服务正在监听5000端口 http://localhost:5000...');
结果展示
先启动server.js :
node server.js
然后打开两个页面
在文本框中输入文字,按下回车发送到server.js本地服务,之后server.js会广播给其他连接的页面,(这里我将广播给其他页面的信息也发送给了原页面)
服务器收到消息 是本页面发送的内容,来自其他页面的消息 是其他页面发送的内容
这样就实现了两个页面的实时通信