当前位置:网站首页>浅谈WebSocket
浅谈WebSocket
2022-07-28 12:49:00 【Maic】
WebSocket是一种基于
http的通信协议,服务端可以主动推送信息给客户端,客户端也可以向服务端发送请求,WebSocket允许服务端与客户端进行全双工通信。
特点
- 基于
tcp协议之上,服务端实现比较容易 - 默认端口是
80(ws)或者443(wss),握手阶段采用的http协议 - 数据格式比较轻量,性能开销小,通信高效
- 可以发送文本或者二进制数据
- 没有同源限制,客户端可以向任意服务器发送信息
- 协议标识符是
ws,如果加密,那么是wss
实现客户端与服务端通信
新建一个html文件客户端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>websocket</title>
</head>
<body>
<h3>hello websocket</h3>
<input type="number" id="textContent" />
<button id="handleSend">发送</button>
<button id="auto-send">开启服务端向客户端发消息模式</button>
<hr />
<div id="app"></div>
</body>
</html>
在html中引入下面一段js
// index.js
const sendDom = document.getElementById('send');
const appDom = document.getElementById('app');
const autoDom = document.getElementById('auto-send');
const inputContent = document.getElementById('textContent');
const socketPath = 'ws://192.168.31.40:3000';
let timer = null;
let num = 0;
const result = [];
// 建立连接
const ws = new WebSocket(socketPath);
const sendMyNum = (isSetInterval = false, to = 'client', val) => {
const setNum = () => {
num = val || Math.ceil(Math.random() * 10);
ws.send(
JSON.stringify({
clientText: `client:hello,我是 ${num}号`,
num,
to
})
);
};
if (isSetInterval) {
timer = setInterval(() => {
setNum();
}, 1000);
} else {
setNum();
}
};
const renderHtml = (data) => {
const { serverText, clientText } = JSON.parse(data);
appDom.innerHTML = '';
result.push({
serverText,
clientText
});
console.log(result);
if (result.length > 0) {
let str = '';
result.forEach((v) => {
str += `<ul>
<li>${v.clientText}</li>
<li>${v.serverText}</li>
</ul>`;
});
appDom.innerHTML = str;
}
};
// 发送数据
ws.onopen = function () {
console.log('websocket connection start');
sendMyNum(false);
};
// 接收服务端发送的消息
ws.onmessage = function (evt) {
console.log(`receive:${evt.data}`);
if (evt.data) {
renderHtml(evt.data);
// 接收数据后关闭定时器
clearInterval(timer);
// sendMyNum(true)
}
};
// 关闭连接
ws.onclose = function () {
console.log('关闭了');
};
// 手动向客户端发送消息
handleSend.onclick = function () {
const val = inputContent.value;
if (val === '') {
alert('请输入你的编号');
return;
}
sendMyNum(false, 'client', val);
};
// 自动开启向客户端发送消息
autoDom.onclick = function () {
sendMyNum(true, 'server');
};
新建一个server目录,创建服务端代码,主要依赖`nodejs-websocket`[1]这个库是服务端websocket代码。
var ws = require("nodejs-websocket");
var http = require('http');
const fs = require('fs');
const path = require('path');
const PORT = 8080;
var server = http.createServer(function (request, response) {
response.statusCode = 200;
response.setHeader('Content-Type', 'text/html');
fs.readFile(path.resolve(__dirname, '../', 'index.html'), (err, data) => {
if (err !== null) {
response.end('404');
return;
}
response.end(data);
})
});
server.listen(PORT, function (evt) {
console.log((new Date()) + ' Server is listening on port 8080');
});
// websocket
const tcp = ws.createServer(function (connection) {
console.log("New connection")
connection.on("text", function (data) {
const { clientText, num, to } = JSON.parse(data);
if (to === 'server') {
connection.sendText(JSON.stringify({
serverText: `server:${num}号,恭喜你,你太幸运了,你已经被清华录取了`,
clientText: `${num}号`
}));
} else {
if (num > 6) {
connection.sendText(JSON.stringify({
clientText,
serverText: `server:${num}号,你非常优秀, ${num}号,你已经成功被录取了北京大学`,
}))
} else {
connection.sendText(JSON.stringify({
serverText: `server: ${num}号,非常遗憾,${num}号,你落榜了,再接再厉`,
clientText,
}));
};
}
});
connection.sendText(JSON.stringify({
serverText: `server:hello,我们已经建立连接了`,
clientText: `client:你好`
}))
connection.on("close", function (code, reason) {
console.log("Connection closed");
console.log(code, reason);
});
}).listen(3000);
tcp.on('error', (err) => {
console.log(err);
})
我们可以执行命令node server.js,打开浏览器http://localhost:8080/
打开network,ws下面可以看到有客户端向服务端发送的消息,也有服务端向客户端发送的两条信息。
我们看到请求头的一些信息
我们可以看到请求头里
General
Request URL: ws://192.168.31.40:3000/
Request Method: GET
Status Code: 101 Switching Protocols
Request Headers
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: no-cache
Connection: Upgrade
Host: 192.168.31.40:3000
Origin: http://localhost:8080
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: Mk8Au85XqQTn+vuDsfr/kw==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36
当输入数字,向服务端发送消息时,服务端会返回对应信息。通常来讲,服务端会不定时的向客户端推送信息,客户端拿到推送信息进行一系列的页面状态展示等。
通过以上的例子,我们基础的了解到websocket的使用
总结
WebSocket其实需要客户端对WebSocket处理主要是这三个步骤
- 建立连接、断开连接
- 发送数据,接收数据
- 处理错误
- 本文 示例代码[2]
更多WebSocket可以参考`websocket`[3]
参考资料
[1]nodejs-websocket: https://www.npmjs.com/package/nodejs-websocket
[2]示例代码: https://github.com/maicFir/lessonNote/tree/master/node/websocket
[3]websocket: https://www.wangdoc.com/webapi/websocket.html
边栏推荐
- Volcanic stone investment Zhang Suyang: hard technology, the relatively certain answer in the next 10 years
- Three men "running away" from high positions in the mobile phone factory
- 数据库系统原理与应用教程(058)—— MySQL 练习题(二):单选题
- C语言:顺序存储结构的快速排序
- 基于神经网络的帧内预测和变换核选择
- 30天刷题计划(四)
- Org.apache.ibatis.exceptions.toomanyresultsexception
- 性能超群!牛津&上海AI Lab&港大&商汤&清华强强联手,提出用于引用图像分割的语言感知视觉Transformer!代码已开源...
- Analyzing the principle of DNS resolution in kubernetes cluster
- 严格模式——let和const——箭头函数——解构赋值——字符串模板symbol——Set和Map——生成器函数
猜你喜欢

半波整流点亮LED

Use non recursive method to realize layer traversal, preorder traversal, middle order traversal and post order traversal in binary tree

【ECMAScript6】Promise

30 day question brushing training (I)

30天刷题训练(一)

Jar package

Humiliation, resistance, reversal, 30 years, China should win Microsoft once

Countdown 2 days! 2022 China Computing Conference: Mobile cloud invites you to meet with computing network for innovative development

SAP ui5 fileuploader control realizes local file upload, and trial version of cross domain access error encountered when receiving server-side response

算法---不同路径(Kotlin)
随机推荐
111. The sap ui5 fileuploader control realizes local file upload and encounters a cross domain access error when receiving the response from the server
拒绝服务 DDoS 攻击
Excellent performance! Oxford, Shanghai, AI Lab, Hong Kong University, Shangtang, and Tsinghua have joined forces to propose a language aware visual transformer for reference image segmentation! Open
SQL每日一练(牛客新题库)——第4天:高级操作符
Lyscript get previous and next instructions
Li Kou sword finger offer 51. reverse order pairs in the array
Denial of service DDoS Attacks
R language uses LM function to build linear regression model and subset function to specify subset of data set to build regression model (use floor function and length function to select the former pa
使用 IPtables 进行 DDoS 保护
Today's sleep quality record 75 points
Product Manager: job responsibility table
30天刷题训练(一)
国产API管理工具Eolink太好用了,打造高效的研发利器
The domestic API management tool eolink is very easy to use, creating an efficient research and development tool
在 Kubernetes 中部署应用交付服务(第 1 部分)
R语言使用lm函数构建线性回归模型、使用subset函数指定对于数据集的子集构建回归模型(使用floor函数和length函数选择数据前部分构建回归模型)
Children's programming electronic society graphical programming level examination scratch Level 2 real problem analysis (judgment question) June 2022
剖析 kubernetes 集群内部 DNS 解析原理
严格模式——let和const——箭头函数——解构赋值——字符串模板symbol——Set和Map——生成器函数
[C language] the difference between structure pointer and structure variable as formal parameters