一般网站建设公司株洲搜索引擎优化

web/2025/10/4 23:19:58/文章来源:
一般网站建设公司,株洲搜索引擎优化,在电商网站上做推广的技巧,做pc端网站渠道1 认识webSocket WebSocket_ohana#xff01;的博客-CSDN博客 一#xff0c;什么是websocket WebSocket是HTML5下一种新的协议#xff08;websocket协议本质上是一个基于tcp的协议#xff09;它实现了浏览器与服务器全双工通信#xff0c;能更好的节省服务器资源和带宽…1 认识webSocket  WebSocket_ohana的博客-CSDN博客 一什么是websocket WebSocket是HTML5下一种新的协议websocket协议本质上是一个基于tcp的协议它实现了浏览器与服务器全双工通信能更好的节省服务器资源和带宽并达到实时通讯的目的Websocket是一个持久化的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单允许服务端主动向客户端推送数据。在WebSocket API中浏览器和服务器只需要完成一次握手两者之间就直接可以创建持久性的连接并进行双向数据传输。 2 技术选型 为什么选择webSocket WebSocket有以下特点 是真正的全双工方式建立连接后客户端与服务器端是完全平等的可以互相主动请求。而HTTP长连接基于HTTP是传统的客户端对服务器发起请求的模式。 HTTP长连接中每次数据交换除了真正的数据部分外服务器和客户端还要大量交换HTTP header信息交换效率很低。Websocket协议通过第一个request建立了TCP连接之后之后交换的数据都不需要发送 HTTP header就能交换数据这显然和原有的HTTP协议有区别所以它需要对服务器和客户端都进行升级才能实现主流浏览器都已支持HTML5 3 WebSocket  Demo 前端服务 npm install websocket // websocket: ^1.0.32,新建 websocket.js 文件 node 安装 npm install ws //     ws: ^7.3.0, vue项目中使用WebSocket_vue websocket服务端_weixin_43964779的博客-CSDN博客 开发者API WebSocket() - Web API 接口参考 | MDN client: scriptvar app new Vue({el: #app,data: {message: ,lists: [],ws: {},name: ,isShow: true,num: 0,roomid: ,uid: ,handle: {}},mounted() {},methods: {init() {this.ws new WebSocket(ws://127.0.0.1:3000)this.ws.onopen this.onOpenthis.ws.onmessage this.onMessagethis.ws.onclose this.onClosethis.ws.onerror this.onError},enter() {if (this.name.trim() ) {alert(用户名不得为空)return}this.init()this.isShow false},onOpen: function () {// console.log(open: this.ws.readyState);//ws.send(Hello fro,m client!)// 发起鉴权请求//this.ws.send(JSON.stringify({// event: auth,// message: //eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIx//MjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNT//E2MjM5MDIyfQ.//XbPfbIHMI6arZ3Y922BhjWgQzWXcXNrz0ogtVhfEd2o//}))this.ws.send(JSON.stringify({event: enter,message: this.name,roomid: this.roomid,uid: this.uid}))},onMessage: function (event) {// 当用户未进入聊天室则不接收消息if (this.isShow) {return}// 接收服务端发送过来的消息var obj JSON.parse(event.data)switch (obj.event) {case noauth:// 鉴权失败// 路由跳转到 /login 重新获取tokenbreak;case enter:// 当有一个新的用户进入聊天室this.lists.push(欢迎 obj.message 加入聊天室)break;case out:this.lists.push(obj.name 已经退出了聊天室)break;case heartbeat://this.checkServer() // timeInterval t// 可以注释掉以下心跳状态主动测试服务端是否会断开客户端的连接this.ws.send(JSON.stringify({event: heartbeat,message: pong}))breakdefault:if (obj.name ! this.name) {// 接收正常的聊天this.lists.push(obj.name : obj.message)}}this.num obj.num},onClose: function () {// 当链接主动断开的时候触发close事件console.log(close: this.ws.readyState);console.log(已关闭websocket);this.ws.close()},onError: function () {// 当连接失败时触发error事件console.log(error: this.ws.readyState);console.log(websocket连接失败);// 连接失败之后1s进行断线重连var _this thissetTimeout(function () {_this.init()}, 1000)},// 发送消息send: function () {this.lists.push(this.name : this.message)this.ws.send(JSON.stringify({event: message,message: this.message,name: this.name}))this.message },checkServer: function () {var _this thisclearTimeout(this.handle)this.handle setTimeout(function () {_this.onClose()setTimeout(function () {_this.init()}, 1000)// 设置1ms的时延调试在服务器测未及时响应时客户端的反应}, 30000 1000)}}})/script Server: package.json: {name: server,version: 1.0.0,description: ,main: index.js,scripts: {start: nodemon src/index.js},keywords: [],author: ,license: ISC,dependencies: {bluebird: ^3.7.2,jsonwebtoken: ^8.5.1,redis: ^2.8.0,ws: ^7.2.1},devDependencies: {nodemon: ^2.0.2} }index.js: const WebSocket require(ws) const wss new WebSocket.Server({ port: 3000 }) // const jwt require(jsonwebtoken) const {getValue, setValue, existKey} require(./config/RedisConfig)const timeInterval 30000 // 多聊天室的功能 // roomid - 对应相同的roomid进行广播消息 let group {}// const run async () { // setValue(imooc, hello) // const result await getValue(imooc) // console.log(TCL: run - result, result) // }// run() const prefix imooc- wss.on(connection, function connection (ws) {// 初始的心跳连接状态ws.isAlive trueconsole.log(one client is connected);// 接收客户端的消息ws.on(message, async function(msg) {const msgObj JSON.parse(msg)const roomid prefix (msgObj.roomid ? msgObj.roomid : ws.roomid)if (msgObj.event enter) {// 当用户进入之后需要判断用户的房间是否存在// 如果用户的房间不存在则在redis中创建房间号用户保存用户信息// 主要是用于统计房间里的人数用于后面进行消息发送ws.name msgObj.messagews.roomid msgObj.roomidws.uid msgObj.uidconsole.log(TCL: connection - ws.uid, ws.uid)// 判断redis中是否有对应的roomid的键值const result await existKey(roomid)if (result 0) {// 初始化一个房间数据setValue(roomid, ws.uid)} else {// 已经存在该房间缓存数据const arrStr await getValue(roomid)let arr arrStr.split(,)if (arr.indexOf(ws.uid) -1) {setValue(roomid, arrStr , ws.uid)}}if (typeof group[ws.roomid] undefined) {group[ws.roomid] 1} else {group[ws.roomid] }}// // 鉴权// if (msgObj.event auth) {// jwt.verify(msgObj.message, secret, (err, decode) {// if (err) {// // websocket返回前台鉴权失败消息// ws.send(JSON.stringify({// event: noauth,// message: please auth again// })) // console.log(auth error);// return// } else {// // 鉴权通过// console.log(decode);// ws.isAuth true// return // }// })// return// }// // 拦截非鉴权的请求// if (!ws.isAuth) {// return// }// 心跳检测if (msgObj.event heartbeat msgObj.message pong) {ws.isAlive truereturn}// 广播消息// 获取房间里所有的用户信息const arrStr await getValue(roomid)let users arrStr.split(,)wss.clients.forEach(async (client) {// 判断非自己的客户端if (client.readyState WebSocket.OPEN client.roomid ws.roomid) {msgObj.name ws.namemsgObj.num group[ws.roomid]client.send(JSON.stringify(msgObj))// 排队已经发送了消息了客户端 - 在线if (users.indexOf(client.uid) ! -1) {users.splice(users.indexOf(client.uid), 1)}// 消息缓存信息取redis中的uid数据let result await existKey(ws.uid)if (result ! 0) {// 存在未发送的离线消息数据let tmpArr await getValue(ws.uid)let tmpObj JSON.parse(tmpArr)let uid ws.uidif (tmpObj.length 0) {let i []// 遍历该用户的离线缓存数据// 判断用户的房间id是否与当前一致tmpObj.forEach((item) {if (item.roomid client.roomid uid client.uid) {client.send(JSON.stringify(item))i.push(item)}})// 删除已经发送的缓存消息数据if (i.length 0) {i.forEach((item) {tmpObj.splice(item, 1)})}setValue(ws.uid, JSON.stringify(tmpObj))}}}})// 断开了与服务端连接的用户的id并且其他的客户端发送了消息if (users.length 0 msgObj.event message) {users.forEach(async function(item) {const result await existKey(item)if (result ! 0) {// 说明已经存在其他房间该用户的离线消息数据let userData await getValue(item)let msgs JSON.parse(userData)msgs.push({roomid: ws.roomid,...msgObj})setValue(item, JSON.stringify(msgs))} else {// 说明先前这个用户一直在线并且无离线消息数据setValue(item, JSON.stringify([{roomid: ws.roomid,...msgObj}]))}})}})// 当ws客户端断开链接的时候ws.on(close, function() {if (ws.name) {group[ws.roomid] --}let msgObj {}// 广播消息wss.clients.forEach((client) {// 判断非自己的客户端if (client.readyState WebSocket.OPEN ws.roomid client.roomid) {msgObj.name ws.namemsgObj.num group[ws.roomid]msgObj.event outclient.send(JSON.stringify(msgObj))}})}) })// setInterval(() { // wss.clients.forEach((ws) { // if (!ws.isAlive ws.roomid) { // group[ws.roomid] -- // delete ws[roomid] // return ws.terminate() // } // // 主动发送心跳检测请求 // // 当客户端返回了消息之后主动设置flag为在线 // ws.isAlive false // ws.send(JSON.stringify({ // event: heartbeat, // message: ping, // num: group[ws.roomid] // })) // }) // }, timeInterval) 4 心跳检测断线重连 服务器先发-客户端-服务器 ∞   心跳检测 服务ping-客户端   服务器端有定时器 如果没有收到 会在下次遍历中关闭与该客户的服务 ws.terminate() //终止发送  退出了本次连接 客户段Clinet 客户段在定时器中加入 断开重连的代码在下次服务器发送过来的PIng  的代码中 清除掉上次的定时器同时就清除了上次心跳检查的断开代码然后发送pong-服务器服务器收到后继续大发送ping-客户端当本次请求一直未收到ping时  心跳检查的定时器没有被清除 就会执行close方法关闭本次连接并重新Init新的链接这就是断线重连。 服务器端 定时器 setInterval(() { //定时器wss.clients.forEach((ws) {if (!ws.isAlive ws.roomid) { //客户段终止group[ws.roomid] -- delete ws[roomid]return ws.terminate() //终止发送 退出了本次连接}// 主动发送心跳检测请求// 当客户端返回了消息之后主动设置flag为在线ws.isAlive falsews.send(JSON.stringify({event: heartbeat,message: ping,num: group[ws.roomid]}))}) }, timeInterval) 客户端 心跳检查与 断线重连 //心跳检查case heartbeat://this.checkServer() // timeInterval t 如果一直接收到ping 那么这次的请求就会删除上次的定时器 定时器不会被执行// 可以注释掉以下心跳状态主动测试服务端是否会断开客户端的连接this.ws.send(JSON.stringify({event: heartbeat,message: pong}))break//检查心跳 checkServer: function () {var _this thisclearTimeout(this.handle) //清除计时器this.handle setTimeout(function () {_this.onClose()setTimeout(function () {_this.init()}, 1000)// 设置1ms的时延调试在服务器测未及时响应时客户端的反应}, 30000 1000)} springboot整合webSocket看完即入门_springboot websocket_hmb↑的博客-CSDN博客 webSocket前端开发实现心跳检测机制_前端心跳检测_mayuan2011的博客-CSDN博客 为什么要使用webSocket以及心跳检测机制 在使用webSocket的过程中如果遇到网络断开服务端并没有触发onclose事件就会出现此状况服务端会继续向客户端发送多余的连接并且这些数据会丢失。 因此就需要一种机制来检测客户端和服务端是否处于正常的连接状态因此就有了webSocket的心跳检测机制即如果有心跳则说客户端和服务端的连接还存在无心跳相应则说明链接已经断开需要采取重新连接等措施。 5 总结  WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单允许服务端主动向客户端推送数据。在WebSocket API中浏览器和服务器只需要完成一次握手两者之间就直接可以创建持久性的连接并进行双向数据传输。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/87029.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

山东网站方案对网站建设的调研报告

1. 题目 给定一个整数数组 A&#xff0c;坡是元组 (i, j)&#xff0c;其中 i < j 且 A[i] < A[j]。这样的坡的宽度为 j - i。 找出 A 中的坡的最大宽度&#xff0c;如果不存在&#xff0c;返回 0 。 示例 1&#xff1a; 输入&#xff1a;[6,0,8,2,1,5] 输出&#xff1…

企业网站欣赏郑州企业形象设计黑龙江网站建设seo优化

1、spring的概念apache推出的java企业框架&#xff0c;提供了基于ioc的对象工厂、aop面向切面编程等功能及其他增强功能。当前版本4.xxx&#xff0c;支持注解的配置。 springmvc。2、控制反转(ioc):inversion of control。用来描述框架的重要特征spring针对ioc的具体实现&#…

韩语网站建设苏宁推客如何做网站

整合Spring Boot和Apache Solr进行全文搜索 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在现代应用开发中&#xff0c;全文搜索是许多应用不可或缺的功能之…

做网站的服务器cpu异常网站后台管理开发

在现代前端开发中&#xff0c;React 提供了多种方法来组织和管理代码。这些方法包括 API 封装、自定义 Hooks、组件、独立模块和 Context。理解它们的区别和联系&#xff0c;可以帮助我们编写更清晰、更模块化的代码。 1. API 封装 目的&#xff1a;处理与后端服务的通信逻辑…

写作网站排行榜潇朋友免费班级网站建设系统

成人学习一般遵循的规律第一阶段是激发起对过去的经历的回忆&#xff0c;让学习者回头想想自己以前做了些什么&#xff0c;是在什么情况下运用什么方法做的&#xff1b;第二阶段&#xff0c;启发学习者对这些经历进行反思&#xff0c;检讨这些经历的成功与失败之所在&#xff0…

浙江省建设信息港网站网站项目分析怎么做 方法

借助集合框架来实现超市会员管理系统&#xff0c;实现以下功能&#xff1a; 1.开卡 2.积分累计 3.查询剩余积分 4.积分兑换 5.修改密码 6.退出 -------------------------------------------------------------------------------------------------- 展示&#x…

网站建设方案如何写如何写手机app程序

Java8实战-总结11 Lambda表达式方法引用管中窥豹如何构建方法引用 构造函数引用 Lambda表达式 方法引用 方法引用让你可以重复使用现有的方法定义&#xff0c;并像Lambda一样传递它们。在一些情况下&#xff0c;比起使用Lambda表达式&#xff0c;它们似乎更易读&#xff0c;感…

郑州网站推广效果北京搜索优化排名公司

相同点&#xff1a;三者存储的都是有序&#xff0c;可重复的数据。 异&#xff1a; ①&#xff1a;ArrayList底层存储类型是Object数组&#xff0c;而LinkedList底层是双向链表 ②&#xff1a;ArrayList和Vector调用创建空参构造器创建对象时&#xff0c;默认的size是10&…

成都装饰公司网站建设网站网站注册

关键词:xml、DTD约束、Schema约束、dom解析、sax解析、jaxp解析器、dom4j解析器 一、xml的简介 1、eXtensible Markup Language:可扩展标记型语言 ①标记型语言:HTML是标记型语言,即使用标签来操作。 ②可扩展: HTML里面的标签是固定,每个标签都有特定的含义<h1><…

工作室 网站经营性备案竞价排名营销

【0】README1&#xff09;本文旨在 intro 异步消息的 相关基础知识&#xff1b;【1】intro【1.1】发送消息1&#xff09;intro&#xff1a;间接性是异步消息的关键所在&#xff1b;2&#xff09;当一个应用向另一个应用发送消息时&#xff0c;两个应用之间没有直接的联系。相反…

editplus怎么创网站做创业项目的网站

前言&#xff1a; 在日常开发当中&#xff0c;如果想要开发多边形&#xff0c;一般都需要多个盒子或者伪元素的帮助&#xff0c;有没有一直办法能只使用一个盒子实现呢&#xff1f; 有的&#xff1a;css裁剪 目录 前言&#xff1a; clip-path到底是什么&#xff1f; clip-pa…

织梦网站 防黑aso优化app推广

创建 字面量方式 var arr []; var arr ["成员1", 2];//可以是不同成员构造函数方式 空的 var array new Array(); 指定长度 var array2 new Array(10); 成员值都是undefined。此方式有技巧使用 虽然值是undefined&#xff0c;但join后不会出现undefined字符串 比…

网站管理入口青浦建设机械网站

Hello大家好&#xff0c;我是你们的南枫学长&#xff0c;咱们今天来学——爬虫之MySql数据入库。 话不多说&#xff0c;导入咱们的老朋友&#xff1a; Pymysql就是我们Python里面的mysql库&#xff0c;主要功能就是用来连接MySql数据库&#xff0c;那么下载还是一样的操作去进…

番禺区住房和建设局网站然后搭建网站

发现穿越类小说 《穿越位面的狂人》 起点地址&#xff1a; https://book.qidian.com/info/1010641845 小说名《位面穿梭之宿舍电梯》改为《穿越位面的狂人》nx大学大一学生柳风&#xff0c;因经济拮据&#xff0c;不得不住在宿舍楼顶的一间破屋子里&#xff0c;半夜下楼上厕…

绵阳网站建设高端品牌wordpress canvas 粒子跟随特效

你正在探访一家农场&#xff0c;农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示&#xff0c;其中 fruits[i] 是第 i 棵树上的水果 种类 。 你想要尽可能多地收集水果。然而&#xff0c;农场的主人设定了一些严格的规矩&#xff0c;你必须按照要求采摘水果&…

网站建设 万网企业网络营销策划方案设计

这是一个HTML文件&#xff0c;主要包含了一些CSS样式和JavaScript代码&#xff0c;用于创建一个动画效果。 在CSS部分&#xff0c;定义了一些基本的样式&#xff0c;包括页面的背景颜色、位置、大小等。特别的&#xff0c;定义了两种球形元素&#xff08;.ball_A 和 .ball_B&am…

站长之家域名查询排行wordpress博客登不上

本期笔者带给大家部署一个本地私有化知识库&#xff0c;简单明了&#xff0c;直接步入主题&#xff0c;需要读者可以继续关注支持一下啊&#xff01; 目录 背景步骤 一、环境准备二、Ollama环境部署三、AnythingLLM安装 总结 开始下载应用&#xff1a; 操作系统&#xff1a…

邢台网站推广多少钱网站 可以做无形资产吗

真正原始创新是怎么样的&#xff1f;希望这些列表对做视觉研究的朋友有些启发&#xff0c;希望大家能帮我补充一些&#xff0c;谢谢。转载请注明http://hi.baidu.com/daren007或者http://www.sciencenet.cn/blog/王中任.htm。1、D. Marr; T. Poggio.Cooperative Computation of…

网站备案号怎么修改wordpress实现圈子功能

RabbitMQ发布确认机制确保消息从生产者成功传输到交换机和队列&#xff0c;提高系统可靠性。在Spring Boot项目中&#xff0c;通过配置publisher-confirm-type和publisher-returns&#xff0c;启用发布确认和消息返回机制。配置RabbitTemplate的确认回调和返回回调&#xff0c;…

网站名称备案医院管理系统

目录 仿函数 示例一&#xff1a; 示例二 : 常见的仿函数 priority_queue简介 priority_queue的常用接口 priority_queue的模拟实现 基础接口 push() 堆的向上调整算法 堆的插入 pop() 堆的向下调整算法 堆的删除 priority_queue最终实现 仿函数 仿函数&#xff…