[go]websocket
- http的特点
- 半双工: 同一个时刻,只能单向传数据(request/response).
- 服务器不能主动给客户端推消息
![[go]websocket [go]websocket](https://cdn.ancii.com/article/image/v1/sw/wV/kP/PkwwVsGDmjDG9swnOi7SkjVAsMQAarn73E9S3mmSmcDJTVmfy3HFINBNyriUvLjHo1xEfetoSBaxtTJk4UGb4Q.png)
- 轮询(polling)
不断的建立http连接,严重浪费了服务器端和客户端的资源. 人越多,服务器压力越大.
- server.js
let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.get("/clock", function (req, res) {
res.end(new Date().toLocaleTimeString());
});
app.listen(8080);- client
<body>
<div id="clock"></div>
<script>
setInterval(function () {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:8080/clock', true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
document.querySelector('#clock').innerHTML = xhr.responseText;
}
};
xhr.send();
}, 1000);
</script>
</body>
- 访问http://localhost:8080/clock- 长轮询(long polling)(comet)
当一次请求完成后, 在发起进行下一次![[go]websocket [go]websocket](https://cdn.ancii.com/article/image/v1/sw/wV/kP/PkwwVsGDmjDG9swnOi7SkjVAsMQAarn73E9S3mmSmcDJTVmfy3HFINBNyriUvLjHyMw5CnWbjRIUFilrO43xkQ.png)
- client
<body>
<div id="clock"></div>
<script>
setInterval(function () {
let xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:8080/clock', true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
document.querySelector('#clock').innerHTML = xhr.responseText;
}
};
xhr.send();
}, 1000);
</script>
</body>- server.js
let express = require('express');
let app = express();
app.use(express.static(__dirname));
app.get("/clock", function (req, res) {
//优化: 当时间为每隔5的倍数才返回.
let $timer = setInterval(function () {
let date = new Date();
let seconds = date.getSeconds();
if (seconds % 5 === 0) {
res.end(new Date().toLocaleTimeString());
clearInterval($timer)
}
}, 1000);
});
app.listen(8080);- iframe流
打开浏览器会主动请求iframe页
iframe可以调用parent父类的方法
缺点: server不断开连接.浏览器一直转圈.
- server.js
const express = require('express');
const app = express();
app.use(express.static(__dirname));
app.get('/clock', function (req, res) {
res.header("Content-Type", "text/html");
setInterval(function () {
res.write(`
<script type="text/javascript">
parent.setTime("${new Date().toLocaleTimeString()}");
</script>
`);
}, 1000);
});
app.listen(8080);- client
<body>
<div id="clock"></div>
<iframe src="/clock" style="display:none"></iframe>
<script>
function setTime(ts) {
document.querySelector('#clock').innerHTML = ts;
}
</script>
</body>- 长连接(SSE)
SSE的简单模型是:
一个客户端去从服务器端订阅一条流,
之后服务端可以发送消息给客户端直到服务端或者客户端关闭该“流”,
所以eventsource也叫作"server-sent-event`
MIME格式为text/event-stream
必须编码成utf-8的格式
消息的每个字段使用"\n"来做分割,最后用\n\n表示结束
常用的消息key
Event: 事件类型,消息名称要和前端对应,如定义的event: xxx, 则前端可以用onxxx对应
Data: 发送的数据
ID: 每一条事件流的ID
不支持跨域- server
let express = require('express');
let app = express();
app.use(express.static(__dirname));
let sendCount = 1;
app.get('/eventSource', function (req, res) {
res.header('Content-Type', 'text/event-stream',);
setInterval(() => {
res.write(`id:${sendCount++}\nevent:message\ndata:${new Date().toLocaleTimeString()}\n\n`);
}, 1000)
});
app.listen(8080);- client
<body>
<div id="clock"></div>
<script>
var eventSource = new EventSource('/eventSource');
eventSource.onmessage = function (e) {
document.querySelector('#clock').innerHTML =e.data
};
eventSource.onerror = function (err) {
console.log(err);
}
</script>
</body>- WebSocket
- server.js
const path = require('path');
let app = express();
let server = require('http').createServer(app);
app.get('/', function (req, res) {
res.sendFile(path.resolve(__dirname, 'index.html'));
});
app.listen(3000);
//-----------------------------------------------
let WebSocketServer = require('ws').Server;
let wsServer = new WebSocketServer({ port: 8888 });
wsServer.on('connection', function (socket) {
console.log('连接成功');
socket.on('message', function (message) {
console.log('接收到客户端消息:' + message);
socket.send('服务器回应:' + message);
});
});- client
<script>
let ws = new WebSocket('ws://localhost:8888');
ws.onopen = function () {
console.log('客户端连接成功');
ws.send('hello');
}
ws.onmessage = function (event) {
console.log('收到服务器的响应 ' + event.data);
}
</script> 相关推荐
柳木木的IT 2020-11-04
joynet00 2020-09-23
蓝色深海 2020-08-16
取个好名字真难 2020-08-06
wenf00 2020-09-14
wuychn 2020-08-16
darylove 2020-06-26
shufen0 2020-06-20
Lovexinyang 2020-06-14
WangBowen 2020-06-14
firejq 2020-06-14
hjhmpl 2020-06-14
水痕 2020-06-07
guozewei0 2020-06-06
woniyu 2020-06-02
取个好名字真难 2020-06-01
guozewei0 2020-05-28
woniyu 2020-05-26