培训视频网站,东莞腾宇科技网站建设,免费个人简历模板,桂林象鼻山景区官网文章目录 一、SSE1.1 什么是SSE1.2 工作原理1.3 特点和适用场景1.4 API用法1.5 代码实现 二、WebSocket2.1 什么是WebSocket2.2 工作原理2.3 特点和适用场景2.4 API用法2.5 代码实现2.6 心跳检测 三、SSE与WebSocket的比较 当涉及到实现实时通信的Web应用程序时#xff0c;两种… 文章目录 一、SSE1.1 什么是SSE1.2 工作原理1.3 特点和适用场景1.4 API用法1.5 代码实现 二、WebSocket2.1 什么是WebSocket2.2 工作原理2.3 特点和适用场景2.4 API用法2.5 代码实现2.6 心跳检测 三、SSE与WebSocket的比较 当涉及到实现实时通信的Web应用程序时两种常见的技术选择是服务器发送事件Server-Sent EventsSSE和WebSocket本文将详细讲讲这两种技术并比较它们的异同点。
一、SSE
1.1 什么是SSE
服务器发送事件SSEServer-Sent Events是一种基于HTTP的单向通信机制用于实现服务器主动向客户端推送数据的技术也被称为“事件流”Event Stream。它基于HTTP协议利用其长链接的特性在客户端与服务器之间建立一条持久化连接并通过这条连接实现服务器向客户端实时数据推送。
1.2 工作原理
它的工作原理如下
建立连接客户端通过发送HTTP请求与服务器建立连接。在请求中客户端指定了接收事件的终点Endpoint。保持连接服务器接收到连接请求后保持连接打开并定期发送事件数据给客户端。事件流服务器使用 “Content-Type: text/event-stream” 头部响应标识SSE连接并使用特定格式的数据事件流发送给客户端。客户端处理事件客户端通过JavaScript的 EventSource 接口监听SSE连接一旦接收到事件就可以处理数据并更新页面。
1.3 特点和适用场景
SSE的特点和适用场景
单向通信SSE是从服务器到客户端的单向通信模型只能由服务器推送数据给客户端。实时更新SSE适用于需要实时更新数据的应用场景如股票行情、新闻推送等。简单易用使用SSE相对简单无需额外的库或框架支持可以直接使用浏览器的原生API进行开发。
当下火热的ChatGPT实现对话消息的流式返回就是基于服务器发送事件SSE技术来实现的。
1.4 API用法
EventSource 对象是 HTML5 新增的一个客户端 API用于通过服务器推送实时更新的数据和通知。在使用 EventSource 对象时可以通过以下方法进行配置和操作: 1.EventSource() 构造函数 EventSource的构造函数接收一个 URL 参数通过该 URL 可以建立起与服务器的连接并开始接收服务器发送的数据【服务器和客户端建立持久性连接的关键】。
const eventSource new EventSource(url, options);url:String 类型表示与服务器建立连接的 URL。必填options:Object 类型表示可选参数。常用的可选参数包括
withCredentialsBoolean 类型表示是否允许发送 Cookie 和 HTTP 认证信息。默认为 false。headersObject 类型表示要发送的请求头信息。retryIntervalNumber 类型表示与服务器失去连接后重新连接的时间间隔。默认为 1000 毫秒。
2.EventSource.onmessage 事件 onmessage监听服务器发送的数据当接收到数据时就触发该事件可以用EventSource的实例对象的监听事件函数来代替使用。 如下
const sse new EventSource(http://localhost:3000/api/sse )
// 第一个参数对应后端nodejs自定义的事件名默认事件名是message
sse.addEventListener(message, (e) {console.log(e.data)
})3. EventSource.onopen 事件 onopen 事件表示 EventSource 对象已经和服务器建立了连接并开始接收来自服务器的数据。当 EventSource 对象建立连接时触发该事件。 4.EventSource.close() 方法 close() 方法用于关闭 EventSource 对象与服务器的连接停止接收服务器发送的数据。 5.EventSource.readyState 属性 readyState 属性表示当前 EventSource 对象的状态它是一个只读属性它的值有以下几个
CONNECTING表示正在和服务器建立连接。OPEN表示已经建立连接正在接收服务器发送的数据。CLOSED表示连接已经被关闭无法再接收服务器发送的数据。 示例
if (eventSource.readyState EventSource.CONNECTING) {console.log(正在连接服务器...);
} else if (eventSource.readyState EventSource.OPEN) {console.log(已经连接上服务器);
} else if (eventSource.readyState EventSource.CLOSED) {console.log(连接已经关闭。);
}1.5 代码实现
下面我们通过代码来体会一下SSE技术以下是一段文本我们基于SSE技术实现node后端读取文本前端流式展示文本内容。
谁让你读了这么多书又知道了双水村以外还有个大世界……
如果从小你就在这个天地里日出而作日落而息那你现在就会和众乡亲抱同一理想
经过几年的辛劳像大哥一样娶个满意的媳妇生个胖儿子加上你的体魄会成为一名出色的庄稼人。
不幸的是你知道的太多了思考的太多了因此才有了这种不能为周围人所理解的苦恼。——《平凡的世界》node后端index.js
const express require(express)
const fs require(fs)
const app express()app.get(/api/sse, (req, res) {// 设置请求的客户端的响应标头参数1必选三位数的http状态码参数2标头对象res.writeHead(200, {Content-Type: text/event-stream, // SSE(事件流)核心代码表示使用SSEAccess-Control-Allow-Origin: * // 解决跨域* 这种方式不安全仅用于测试})const data fs.readFileSync(./index.txt, utf8) // 异步utf8格式读取文件得到的是字符串const arr data.split() // 将字符串分割成数组let current 0// mock SSE 数据let timer setInterval(() { // 定时器实现持久化返回数据if (current arr.length) {clearInterval(timer)return} else {// 返回自定义事件名 默认是messageres.write(id:${current}\n)res.write(event:lol\n) // 定义发送事件名// 向请求的客户端发送响应内容 我的理解就是可以让客户端执行一段js代码res.write(data:${arr[current]}\n\n)}}, 300);
})app.listen(3000, () {console.log(server is running);
})使用node ./index.js运行node服务。
以上代码在node后端实现了localhost:3000的服务器的/api/sse接口通过Content-Type:text/event-stream头部标识SSE连接并将文本内容以300ms返回一个字符的速度发送给客户端。
值得注意的是
res.writeHead()方法实现设置请求的客户端的响应标头和res.writeHead()实现相同功能但wirteHead()可以一次设置多个响应标头。
res.write()方法实现向请求的客户端发送响应内容。在res.end()之前可以多次被执行调用传入模板字符串时我的理解是可以让客户端执行一段js代码。
注意看上述代码中的res.write片段
// 返回自定义事件名 默认是message
res.write(id:${current}\n)
res.write(event:lol\n)
// 向请求的客户端发送响应内容 我的理解就是可以让客户端执行一段js代码
res.write(data:${arr[current]}\n\n)由于使用响应请求头Content-Type:text/event-stream开启事件流EventStream因此可以看到浏览器请求SSE的请求时会有下图的表格上述代码的ideventdata分别对应下图表格的前三列内容\n则表示自动跳转下一个表格单元因此执行第三个res.write()时最后跟两个\n第一个用于跳转时间列的单元格第二个用于跳转下一行第一个单元格。 下面我们再看看前端代码index.html
!DOCTYPE html
html langenheadmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleSSE流式发送/title
/headbodydiv iddata/divscriptdocument.addEventListener(keydown, (e) {// 按下回车键触发sse接口if (e.keyCode 13) {const sse new EventSource(http://localhost:3000/api/sse)sse.addEventListener(open, (e) {console.log(e.target);})// 接收到服务器发送的数据的监听方式1// 后端nodejs自定义了事件名就要把message改成自定义的事件名sse.addEventListener(lol, (e) {document.getElementById(data).innerHTML e.dataconsole.log(e);})// 监听方式2// sse.onmessage (e) {// document.getElementById(data).innerHTML e.data// console.log(e);// }sse.onerror (e) {console.log(e);}}})/script
/body/html以上代码实现了按下回车键后客户端发送http请求与服务器建立连接并实例化EventSource对象与服务器保持持久连接后监听服务器返回数据。
使用LiverServer运行html文件。
最终的实现效果如下
二、WebSocket
2.1 什么是WebSocket
WebSocket 是一种在单个 TCP 连接上进行全双工通信的网络协议。它是 HTML5 中的一种新特性能够实现 Web 应用程序和服务器之间的实时通信比如在线聊天、游戏、数据可视化等。
相较于 HTTP 协议的请求-响应模式使用 WebSocket 可以建立持久连接允许服务器主动向客户端推送数据避免了不必要的轮询请求提高了实时性和效率。同时WebSocket 的连接过程也比较简单可以通过 JavaScript 中的 WebSocket API 进行创建和管理并且可以和现有的 Web 技术如 HTML、CSS 和 JavaScript 无缝集成。
WebSocket 协议是基于握手协议Handshake Protocol的它在建立连接时使用 HTTP/HTTPS 发送一个初始握手请求然后服务器响应该请求建立连接后就可以在连接上进行数据传输了。
总之WebSocket 提供了一种快速、可靠且灵活的方式使 Web 应用程序能够实现实时通信同时也提高了网络性能和用户体验。
为什么要用使用WebSocket
因为http 通信只能由客户端发起,服务器返回查询结果,HTTP 协议做不到服务器主动向客户端推送信息。服务器有连续的状态变化客户端要获知就非常麻烦。
我们只能使用轮询每隔一段时候就发出一个询问了解服务器有没有新的信息。最典型的场景就是聊天室。
轮询的效率低非常浪费资源因为必须不停连接或者 HTTP 连接始终打开;
而WebSocket能做到服务器和客户端相互推送信息。 2.2 工作原理
握手阶段客户端向服务器发送WebSocket握手请求服务器返回握手响应。在这个阶段客户端和服务器协商选择协议和版本。建立连接握手成功后客户端和服务器之间建立持久连接可以进行双向数据传输。双向通信一旦连接建立客户端和服务器都可以主动发送消息给对方。数据可以以文本或二进制格式进行传输。断开连接当任一方决定关闭连接时可以发送关闭帧来终止连接。
2.3 特点和适用场景
双向通信WebSocket支持双向通信客户端和服务器可以互相发送消息。实时互动WebSocket适用于实时互动的应用场景如聊天应用、协作编辑等。复杂性和灵活性相对于SSEWebSocket更为灵活可以处理更复杂的通信需求。它允许自定义消息格式、心跳检测、连接状态管理等。
2.4 API用法
前端的WebSocket对象提供了用于创建和管理WebSocket 连接以及可以通过该连接发送和接收数据的 API。 使用示例
const ws new WebSocket(ws://localhost:8080)node后端不再使用Express建立服务而是安装ws库创建socket服务。
下面我们直接看代码
2.5 代码实现
后端创建socket服务ws.js
// 要先安装ws和它的声明文件types/ws
const ws require(ws)
// 创建 socket 服务 8080端口
const wss new ws.Server({ port: 8080 }, () {console.log(socket服务启动成功8080);
});
// 监听客户端的连接
wss.on(connection, (socket) {// 监听客户端的消息console.log(客户端连接成功);// 监听客户端发送过来的消息socket.on(message, (e) {console.log(e.toString());// 单独给发送消息的客户端发送消息socket.send(e.toString())// 给所有客户端群发消息wss.clients.forEach((client) {client.send(群发消息 e.toString())})})
})以上代码实现了创建8080端口的socket服务并监听客户端发送过来的消息并分别将收到的消息发送给一个客户端以及所有客户端。
前端ws.html:
!DOCTYPE html
html langen
headmeta charsetUTF-8meta nameviewport contentwidthdevice-width, initial-scale1.0titleWebSocket/title
/head
bodydivinput typetext idinputbutton idsend发送/button/divdiv idtxt服务端发给发给客户端的消息:/div/divscript// 建立8080端口的WebSocket连接// webSocket的协议要是用ws://或者wss:// 就跟http://和https://一样const ws new WebSocket(ws://localhost:8080)// 监听open 表示连接成功ws.addEventListener(open, function(event){console.log(连接成功);})let input document.querySelector(#input)let btn document.querySelector(#send)btn.addEventListener(click, function () {// 发送消息 前后端都使用send发送消息if(input.value) {// 给服务器端发送消息ws.send(input.value)input.value }})// 监听服务器端发送过来的消息ws.addEventListener(message, (e) {// 渲染消息到页面document.querySelector(#txt).innerHTML e.data})/script
/body
/html以上代码实现了建立8080端口的WebSocket连接并实现点击btn将输入框的内容发送给服务端最后监听服务端返回的消息实现渲染到页面上。
效果展示 后端运行socket服务前端使用LiveServer(会自动开一个5500的端口)打开html文件可以看到前后端WebSocket连接成功。
这里我们开启两个客户端分别验证服务端单独发送给客户端和群发消息的效果
在左边的客户端的输入框输入你好后点击发送可以得到如下结果 可以看到左右两边都收到了服务端群发的消息左边的客户端比右边的客户端多了一条它发给客户端的消息。这表明WebSocket成功实现了服务端和客户端之间的相互通信并且服务端可以给客户端群发消息。
2.6 心跳检测
参考博客WebSocket心跳检测详解
三、SSE与WebSocket的比较 通信模型SSE是单向通信模型只能由服务器向客户端推送数据而WebSocket是双向通信模型客户端和服务器可以互相发送消息。 连接性SSE使用长轮询或HTTP流技术而WebSocket使用持久连接。SSE需要频繁地发起HTTP请求来获取数据【是这样的吗】而WebSocket只需在握手阶段建立一次连接然后保持连接打开。另外WebSocket没有同源限制客户端可以与任意服务器通信。 实时性WebSocket提供了更低的延迟和更高的实时性因为它支持双向通信可以立即将数据推送给客户端。SSE虽然也可以实现实时性但由于其单向通信模型需要服务器定期发送数据。 浏览器支持WebSocket在现代浏览器中得到广泛支持包括Chrome、Firefox、Safari等。SSE在大多数现代浏览器中也有支持但在某些旧版本浏览器中可能存在兼容性问题。 API复杂性WebSocket提供了更灵活和复杂的API可以处理更高级的通信需求。SSE相对简单使用浏览器的原生 EventSource 接口即可。
选择SSE还是WebSocket取决于您的应用需求。如果您只需要服务器向客户端推送数据并且实时性要求不高SSE是一个简单可行的选择。如果您需要双向通信实时性要求高或需要处理复杂的通信需求WebSocket可能更适合您的应用。 文章转载自: http://www.morning.fbrshjf.com.gov.cn.fbrshjf.com http://www.morning.zxqyd.cn.gov.cn.zxqyd.cn http://www.morning.qywfw.cn.gov.cn.qywfw.cn http://www.morning.ywpcs.cn.gov.cn.ywpcs.cn http://www.morning.fmjzl.cn.gov.cn.fmjzl.cn http://www.morning.nfbxgtj.com.gov.cn.nfbxgtj.com http://www.morning.rppf.cn.gov.cn.rppf.cn http://www.morning.bqqzg.cn.gov.cn.bqqzg.cn http://www.morning.jpbky.cn.gov.cn.jpbky.cn http://www.morning.trpq.cn.gov.cn.trpq.cn http://www.morning.wpqcj.cn.gov.cn.wpqcj.cn http://www.morning.bqyb.cn.gov.cn.bqyb.cn http://www.morning.ptwrz.cn.gov.cn.ptwrz.cn http://www.morning.ysllp.cn.gov.cn.ysllp.cn http://www.morning.ckfyp.cn.gov.cn.ckfyp.cn http://www.morning.fwrr.cn.gov.cn.fwrr.cn http://www.morning.gynlc.cn.gov.cn.gynlc.cn http://www.morning.kqblk.cn.gov.cn.kqblk.cn http://www.morning.ljtwp.cn.gov.cn.ljtwp.cn http://www.morning.bnmrp.cn.gov.cn.bnmrp.cn http://www.morning.yrjkp.cn.gov.cn.yrjkp.cn http://www.morning.qjxxc.cn.gov.cn.qjxxc.cn http://www.morning.dongyinet.cn.gov.cn.dongyinet.cn http://www.morning.srjbs.cn.gov.cn.srjbs.cn http://www.morning.clyhq.cn.gov.cn.clyhq.cn http://www.morning.yysqz.cn.gov.cn.yysqz.cn http://www.morning.pypbz.cn.gov.cn.pypbz.cn http://www.morning.slwqt.cn.gov.cn.slwqt.cn http://www.morning.pxlsh.cn.gov.cn.pxlsh.cn http://www.morning.nlrxh.cn.gov.cn.nlrxh.cn http://www.morning.xcdph.cn.gov.cn.xcdph.cn http://www.morning.dmxzd.cn.gov.cn.dmxzd.cn http://www.morning.yjfmj.cn.gov.cn.yjfmj.cn http://www.morning.skkmz.cn.gov.cn.skkmz.cn http://www.morning.nyqb.cn.gov.cn.nyqb.cn http://www.morning.mhsmj.cn.gov.cn.mhsmj.cn http://www.morning.wfbnp.cn.gov.cn.wfbnp.cn http://www.morning.ypbdr.cn.gov.cn.ypbdr.cn http://www.morning.qlsyf.cn.gov.cn.qlsyf.cn http://www.morning.rxnl.cn.gov.cn.rxnl.cn http://www.morning.qgfhr.cn.gov.cn.qgfhr.cn http://www.morning.fxxmj.cn.gov.cn.fxxmj.cn http://www.morning.ydnxm.cn.gov.cn.ydnxm.cn http://www.morning.phgz.cn.gov.cn.phgz.cn http://www.morning.wmdbn.cn.gov.cn.wmdbn.cn http://www.morning.xknsn.cn.gov.cn.xknsn.cn http://www.morning.gcftl.cn.gov.cn.gcftl.cn http://www.morning.dydqh.cn.gov.cn.dydqh.cn http://www.morning.yxplz.cn.gov.cn.yxplz.cn http://www.morning.cfhwn.cn.gov.cn.cfhwn.cn http://www.morning.rccbt.cn.gov.cn.rccbt.cn http://www.morning.fydsr.cn.gov.cn.fydsr.cn http://www.morning.nhzps.cn.gov.cn.nhzps.cn http://www.morning.kzhxy.cn.gov.cn.kzhxy.cn http://www.morning.ctfwl.cn.gov.cn.ctfwl.cn http://www.morning.rltw.cn.gov.cn.rltw.cn http://www.morning.rjqtq.cn.gov.cn.rjqtq.cn http://www.morning.jxhlx.cn.gov.cn.jxhlx.cn http://www.morning.qgjwx.cn.gov.cn.qgjwx.cn http://www.morning.zlgth.cn.gov.cn.zlgth.cn http://www.morning.mnkhk.cn.gov.cn.mnkhk.cn http://www.morning.kkdbz.cn.gov.cn.kkdbz.cn http://www.morning.gbrdx.cn.gov.cn.gbrdx.cn http://www.morning.plqsz.cn.gov.cn.plqsz.cn http://www.morning.tzzfy.cn.gov.cn.tzzfy.cn http://www.morning.nkkpp.cn.gov.cn.nkkpp.cn http://www.morning.dsmwy.cn.gov.cn.dsmwy.cn http://www.morning.ljxxl.cn.gov.cn.ljxxl.cn http://www.morning.ffcsr.cn.gov.cn.ffcsr.cn http://www.morning.ntqqm.cn.gov.cn.ntqqm.cn http://www.morning.bwkhp.cn.gov.cn.bwkhp.cn http://www.morning.ptqds.cn.gov.cn.ptqds.cn http://www.morning.ntkpc.cn.gov.cn.ntkpc.cn http://www.morning.nhpgm.cn.gov.cn.nhpgm.cn http://www.morning.xsjfk.cn.gov.cn.xsjfk.cn http://www.morning.nyhtf.cn.gov.cn.nyhtf.cn http://www.morning.bmpjp.cn.gov.cn.bmpjp.cn http://www.morning.qswws.cn.gov.cn.qswws.cn http://www.morning.kzpxc.cn.gov.cn.kzpxc.cn http://www.morning.mdjzydr.com.gov.cn.mdjzydr.com