仅接收服务器数据的长链接方案
2023-02-18 16:41:30 时间
在项目中或多或少有一些场景会使用到长链接,除去一些聊天的项目(双向数据交换)外,更多见的如:排行榜定时刷新,大屏数据动态刷新等,往往我们只是从服务器来获取数据进行展示即可,原来除了使用定时器来发送请求获取数据外还能想到的就是WebSocket了,因为WebSocket从0集成的成本相对较大,还需要处理一些状态,所以了解到了EventSource类。仅支持从服务器发送文本数据到客户端,用的也是常规的HTTP协议,最最关键是简单。
EventSource 是服务器推送的一个网络事件接口。一个EventSource实例会对HTTP服务开启一个持久化的连接,以text/event-stream 格式发送事件, 会一直保持开启直到被要求关闭。(摘自MDN)
Server-Sent Events 规范描述了一个内建的类 EventSource,它能保持与服务器的连接,并允许从中接收事件。与 WebSocket 类似,其连接是持久的。
EventSource介绍:
补充:
客户端代码:
封装EventSourceClient:
export default class EventSourceClient {
constructor(url) {
this.url = url;
this.eventSource = null;
}
// 建立连接
connection(openCallback, messageCallback, errorCallback) {
this.eventSource = new EventSource(this.url);
this.eventSource.onopen = openCallback;
this.eventSource.onmessage = messageCallback;
this.eventSource.onerror = function (e) {
if (this.readyState == EventSource.CONNECTING) {
console.log(`Reconnecting (readyState=${this.readyState})...`);
} else {
errorCallback && errorCallback(e)
}
};
}
// 断开连接
disconnect() {
this.eventSource && this.eventSource.close();
}
addAction(action, fn) {
this.eventSource && this.eventSource.addEventListener(action, fn);
}
}
使用EventSourceClient:
<script type="module">
import EventSourceClient from './event-source-client.js'
const url = 'http://localhost:8080/digits'
window.esc = new EventSourceClient(url);
</script>
<script>
function start() {
window.esc.connection((e) => {
console.log('建立连接', e);
}, (e) => {
console.log('接收数据', e.data);
}, (e) => {
console.log('发生错误', e);
})
window.esc.addAction('bye', (e) => {
console.log('自定义动作', e.data);
})
}
function stop() {
window.esc.disconnect();
console.log('关闭连接');
}
</script>
服务端代码:
let http = require('http');
function onDigits(req, res) {
// 设置请求头
res.writeHead(200, {
'Cache-Control': 'no-cache',
// 支持跨域请求
"Access-Control-Allow-Origin": "*",
// 返回类型为text/event-stream
'Content-Type': 'text/event-stream; charset=utf-8',
});
let i = 0;
let timer = setInterval(write, 1000);
write();
function write() {
i++;
if (i == 4) {
res.write('event: bye\ndata: bye-bye\n\n');
clearInterval(timer);
res.end();
return;
}
res.write('data: ' + i + '\n\n');
}
}
function accept(req, res) {
if (req.url == '/digits') {
onDigits(req, res);
}
}
http.createServer(accept).listen(8080);
执行演示:
我是小鑫同学:
- ?熟悉:安卓开发,前端开发。
- ?了解:后端开发,脚本开发。
- ?特长:解决编码中的疑难杂症。
- ?座右铭:积跬步以至千里,积小流以成江海。
相关文章
- 基于SimpleBlobDetector识别骰子点数
- Autodesk Flame 2023 for mac(3D视觉特效剪辑合成软件)中文版v2023.3
- 美团的技术实力怎么样?
- OpenCV趣味应用系列--grabCut人物背景替换
- 25 匹马 5 条赛道,最快需要几轮求出前 3 名?
- 至少要几个砝码,可以称出 1g ~ 40g 重量
- 我知道你不知道,我到底知不知道?
- 人工智能|LightGBM模型详解
- 舞会上有多少顶黑帽?
- 如何自动收集周报并提醒未提交人员?
- 数字货币将为经济社会带来哪些变化?
- 食之无味?App Startup 可能比你想象中要简单
- JDK 自带的服务发现框架 ServiceLoader 好用吗?
- ViewBinding 与 Kotlin 委托双剑合璧
- 数据科学|Pandas 对数值进行分箱操作的 4 种方法
- Autodesk Maya 2023 for Mac(三维动画制作软件) v2023.3中文激活版
- 如何使用并查集解决朋友圈问题?
- 数据科学|数据科学中的信息理论方法
- 金融科技|普惠金融下的智能信贷风控
- 使用单调栈解决 “下一个更大元素” 问题