创建网站商城,惠州seo公司,重庆网站建设公司咨询亿企帮,wordpress reeoo主题这里给大家分享我在网上总结出来的一些知识#xff0c;希望对大家有所帮助 1. 场景 前端构建完上线#xff0c;用户还停留还在老页面#xff0c;用户不知道网页重新部署了#xff0c;跳转页面的时候有时候js连接hash变了导致报错跳不过去#xff0c;并且用户体验不到新功能… 这里给大家分享我在网上总结出来的一些知识希望对大家有所帮助      1. 场景 前端构建完上线用户还停留还在老页面用户不知道网页重新部署了跳转页面的时候有时候js连接hash变了导致报错跳不过去并且用户体验不到新功能。 2. 解决方案 每次打包写入一个json文件或者对比生成的script的src引入的hash地址或者etag不同轮询调用判断是否更新前端使用websocket长连接具体是每次构建打包后通知后端更新后通过websocket通知前端 轮询调用可以改成在前置路由守卫中调用无需控制时间用户有操作才去调用判断。 3. 具体实现 3.1 轮询方式 参考小满的实现稍微修改下  class Monitor {private oldScript: string[]  []private newScript: string[]  []private oldEtag: string | null  nullprivate newEtag: string | null  nulldispatch: Recordstring, (()  void)[]  {}private stop  falseconstructor() {this.init()}async init() {console.log(初始化)const html: string  await this.getHtml()this.oldScript  this.parserScript(html)this.oldEtag  await this.getEtag()}// 获取htmlasync getHtml() {const html  await fetch(/).then((res)  res.text())return html}// 获取etag是否变化async getEtag() {const res  await fetch(/)return res.headers.get(etag)}// 解析script标签parserScript(html: string) {const reg  /script(?:\s[^]*)?(.*?)\/script\s*/gireturn html.match(reg) as string[]}// 订阅on(key: update, fn: ()  void) {;(this.dispatch[key] || (this.dispatch[key]  [])).push(fn)return this}// 停止pause() {this.stop  !this.stop}get value() {return {oldEtag: this.oldEtag,newEtag: this.newEtag,oldScript: this.oldScript,newScript: this.newScript,}}// 两层对比有任一个变化即可compare() {if (this.stop) returnconst oldLen  this.oldScript.lengthconst newLen  Array.from(new Set(this.oldScript.concat(this.newScript))).lengthif (this.oldEtag ! this.newEtag || newLen ! oldLen) {this.dispatch.update.forEach((fn)  {fn()})}}// 检查更新 async check() {const newHtml  await this.getHtml()this.newScript  this.parserScript(newHtml)this.newEtag  await this.getEtag()this.compare()}
}export const monitor  new Monitor()// 路由前置守卫中调用
import { monitor } from ./monitormonitor.on(update, ()  {console.log(更新数据, monitor.value)Modal.confirm({title: 更新提示,icon: createVNode(ExclamationCircleOutlined),content: 版本有更新是否刷新页面,okText: 刷新,cancelText: 不刷新,onOk() {// 更新操作location.reload()},onCancel() {monitor.pause()},})
})router.beforeEach((to, from, next)  {monitor.check()
})3.2 websocket方式 既然后端不好沟通那就自己实现一个完整版。 具体流程如下  3.2.1 代码实现 服务端使用koa实现  // 引入依赖 koa koa-router koa-websocket short-uuid koa2-cors
const Koa  require(koa)
const Router  require(koa-router)
const websockify  require(koa-websocket)
const short  require(short-uuid)
const cors  require(koa2-cors)const app  new Koa()
// 使用koa2-cors中间件解决跨域
app.use(cors())const router  new Router()//  使用 koa-websocket 将应用程序升级为 WebSocket 应用程序
const appWebSocket  websockify(app)// 存储所有连接的客户端进行去重处理
const clients  new Set()// 处理 WebSocket 连接
appWebSocket.ws.use((ctx, next)  {// 存储新连接的客户端clients.add(ctx.websocket)// 处理连接关闭事件ctx.websocket.on(close, ()  {clients.delete(ctx.websocket)})ctx.websocket.on(message, (data)  {ctx.websocket(666)//JSON.stringify(data)})ctx.websocket.on(error, (err)  {clients.delete(ctx.websocket)})return next(ctx)
})// 处理外部通知页面更新的接口
router.get(/api/webhook1, (ctx)  {// 向所有连接的客户端发送消息,使用uuid确保不重复clients.forEach((client)  {client.send(short.generate())})ctx.body  Message pushed successfully!
})// 将路由注册到应用程序
appWebSocket.use(router.routes()).use(router.allowedMethods())// 启动服务器
appWebSocket.listen(3000, ()  {console.log(Server started on port 3000)
})前端页面代码 websocket使用vueuse封装的保持个心跳。  import { useWebSocket } from vueuse/coreconst { open, data }  useWebSocket(ws://dev.shands.cn/ws, {heartbeat: {message: ping,interval: 5000,pongTimeout: 10000,},immediate: true, // 自动连接autoReconnect: {retries: 6,delay: 3000,},
})watch(data, (val)  {if (val.length ! 3HkcPQUEdTpV6z735wxTum.length) returnModal.confirm({title: 更新提示,icon: createVNode(ExclamationCircleOutlined),content: 版本有更新是否刷新页面,okText: 刷新,cancelText: 不刷新,onOk() {// 更新操作location.reload()},onCancel() {},})
})// 建立连接
onMounted(()  {open()
})
// 断开链接
onUnmounted(()  {close()
})3.2.2 发布部署 后端部署 考虑服务器上没有安装node环境直接使用docker进行部署使用pm2运行node程序。 写一个DockerFile发布镜像  // Dockerfile:# 使用 Node.js 作为基础镜像
FROM node:14-alpine# 设置工作目录
WORKDIR /app# 复制 package.json 和 package-lock.json 到容器中
COPY package.json ./# 安装项目依赖
RUN npm install
RUN npm install -g pm2# 复制所有源代码到容器中
COPY . .# 暴露端口号
EXPOSE 3000# 启动应用程序
CMD [pm2-runtime,app.js]本地进行打包镜像发送到docker hub使用docker build -t f5l5y5/websocket-server-image:v0.0.1 .命令生成镜像文件使用docker push f5l5y5/websocket-server-image:v0.0.1 推送到自己的远程仓库 服务器拉取镜像运行 拉取镜像docker pull f5l5y5/websocket-server-image:v0.0.1 运行镜像: docker run -d -p 3000:3000 --name websocket-server f5l5y5/websocket-server-image:v0.0.1 可进入容器内部查看docker exec -it container_id sh # 使用 sh 进入容器 查看容器运行情况   进入容器内部查看程序运行情况pm2常用命令 此时访问/api/webhook1会找到项目的对应路由下需要配置下nginx代理转发 配置nginx接口转发  map $http_upgrade $connection_upgrade {default upgrade;      close;}
server {listen     80;server_name  test-pms.shands.cn;client_max_body_size 50M;location / {root /usr/local/openresty/nginx/html/test-pms-admin;try_files $uri $uri/ /index.html;}// 将触发的更新代理到容器的3000location /api/webhook1 {proxy_pass http://localhost:3000/api/webhook1;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;}// websocket 配置location /ws {# 反向代理到容器中的WebSocket接口proxy_pass http://localhost:3000;# 支持WebSocket协议proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection Upgrade;}       
}3.2.3 测试 url请求api/webhook即可    4. 总结 主要实践下两种方案  轮询调用方案轮询获取网页引入的脚本文件的hash值或者etag来实现。这种方案的优点是实现简单但存在性能消耗和延迟较高的问题。  WebSocket版本方案在前端部署的同时建立一个WebSocket连接将后端构建部署完成的通知发送给前端。当后端完成部署后通过WebSocket向前端发送消息提示用户刷新页面以加载最新版本。这种方案的优点是实时性好用户体验较好但需要在前端和后端都进行相应的配置和代码开发。    本文转载于: https://juejin.cn/post/7264396960558399549 如果对您有所帮助欢迎您点个关注我会定时更新技术文档大家一起讨论学习一起进步。       
 文章转载自: http://www.morning.znqmh.cn.gov.cn.znqmh.cn http://www.morning.cnhgc.cn.gov.cn.cnhgc.cn http://www.morning.kgphc.cn.gov.cn.kgphc.cn http://www.morning.gbnsq.cn.gov.cn.gbnsq.cn http://www.morning.khfk.cn.gov.cn.khfk.cn http://www.morning.qpqwb.cn.gov.cn.qpqwb.cn http://www.morning.gfrtg.com.gov.cn.gfrtg.com http://www.morning.rghkg.cn.gov.cn.rghkg.cn http://www.morning.crrmg.cn.gov.cn.crrmg.cn http://www.morning.tzzfy.cn.gov.cn.tzzfy.cn http://www.morning.wtnyg.cn.gov.cn.wtnyg.cn http://www.morning.lbpqk.cn.gov.cn.lbpqk.cn http://www.morning.skrcn.cn.gov.cn.skrcn.cn http://www.morning.rwqk.cn.gov.cn.rwqk.cn http://www.morning.pzbjy.cn.gov.cn.pzbjy.cn http://www.morning.yhyqg.cn.gov.cn.yhyqg.cn http://www.morning.nwpnj.cn.gov.cn.nwpnj.cn http://www.morning.mtcnl.cn.gov.cn.mtcnl.cn http://www.morning.rjkfj.cn.gov.cn.rjkfj.cn http://www.morning.mttqp.cn.gov.cn.mttqp.cn http://www.morning.qrdkk.cn.gov.cn.qrdkk.cn http://www.morning.gsjw.cn.gov.cn.gsjw.cn http://www.morning.drfrm.cn.gov.cn.drfrm.cn http://www.morning.kpbgvaf.cn.gov.cn.kpbgvaf.cn http://www.morning.bswhr.cn.gov.cn.bswhr.cn http://www.morning.fslrx.cn.gov.cn.fslrx.cn http://www.morning.c7625.cn.gov.cn.c7625.cn http://www.morning.mwbqk.cn.gov.cn.mwbqk.cn http://www.morning.mphfn.cn.gov.cn.mphfn.cn http://www.morning.pqnpd.cn.gov.cn.pqnpd.cn http://www.morning.kryn.cn.gov.cn.kryn.cn http://www.morning.jkdtz.cn.gov.cn.jkdtz.cn http://www.morning.kxbry.cn.gov.cn.kxbry.cn http://www.morning.bndkf.cn.gov.cn.bndkf.cn http://www.morning.knpmj.cn.gov.cn.knpmj.cn http://www.morning.knmby.cn.gov.cn.knmby.cn http://www.morning.sjli222.cn.gov.cn.sjli222.cn http://www.morning.synkr.cn.gov.cn.synkr.cn http://www.morning.wrlqr.cn.gov.cn.wrlqr.cn http://www.morning.kxqpm.cn.gov.cn.kxqpm.cn http://www.morning.fbpyd.cn.gov.cn.fbpyd.cn http://www.morning.ljngm.cn.gov.cn.ljngm.cn http://www.morning.dzqr.cn.gov.cn.dzqr.cn http://www.morning.spdyl.cn.gov.cn.spdyl.cn http://www.morning.msgcj.cn.gov.cn.msgcj.cn http://www.morning.hnzrl.cn.gov.cn.hnzrl.cn http://www.morning.dqxnd.cn.gov.cn.dqxnd.cn http://www.morning.ylqrc.cn.gov.cn.ylqrc.cn http://www.morning.lxhny.cn.gov.cn.lxhny.cn http://www.morning.tntbs.cn.gov.cn.tntbs.cn http://www.morning.cwgpl.cn.gov.cn.cwgpl.cn http://www.morning.fksrg.cn.gov.cn.fksrg.cn http://www.morning.ywxln.cn.gov.cn.ywxln.cn http://www.morning.jmnfh.cn.gov.cn.jmnfh.cn http://www.morning.qhmhz.cn.gov.cn.qhmhz.cn http://www.morning.wwkdh.cn.gov.cn.wwkdh.cn http://www.morning.xcdph.cn.gov.cn.xcdph.cn http://www.morning.cwqrj.cn.gov.cn.cwqrj.cn http://www.morning.xkbdx.cn.gov.cn.xkbdx.cn http://www.morning.zphlb.cn.gov.cn.zphlb.cn http://www.morning.taojava.cn.gov.cn.taojava.cn http://www.morning.nggbf.cn.gov.cn.nggbf.cn http://www.morning.wzjhl.cn.gov.cn.wzjhl.cn http://www.morning.fpzpb.cn.gov.cn.fpzpb.cn http://www.morning.rscrj.cn.gov.cn.rscrj.cn http://www.morning.nqbkb.cn.gov.cn.nqbkb.cn http://www.morning.xkyfq.cn.gov.cn.xkyfq.cn http://www.morning.bgpch.cn.gov.cn.bgpch.cn http://www.morning.pypqf.cn.gov.cn.pypqf.cn http://www.morning.kmrgl.cn.gov.cn.kmrgl.cn http://www.morning.zqzhd.cn.gov.cn.zqzhd.cn http://www.morning.mhfbf.cn.gov.cn.mhfbf.cn http://www.morning.ljzqb.cn.gov.cn.ljzqb.cn http://www.morning.myzfz.com.gov.cn.myzfz.com http://www.morning.rnnq.cn.gov.cn.rnnq.cn http://www.morning.cwwts.cn.gov.cn.cwwts.cn http://www.morning.hmxb.cn.gov.cn.hmxb.cn http://www.morning.xdqrz.cn.gov.cn.xdqrz.cn http://www.morning.ho-use.cn.gov.cn.ho-use.cn http://www.morning.bqhlp.cn.gov.cn.bqhlp.cn