【前端】websocket 讲解与项目中的使用(附源码)

【前端】websocket 讲解与项目中的使用(附源码)

码农世界 2024-06-04 前端 137 次浏览 0个评论

let url = ${process.env['VUE_APP_WEBSOCKET']}/websocket

let ws = new WebSocket(url)

ws.addEventListener(‘open’, e => {

console.log(‘长连接连接成功’)

// 执行心跳方法

dispatch(‘wsHeartStart’)

})

websocket 链接成功以后,开启心跳方法。心跳功能的实现如下:

const state = {

ws: null,

// 心跳时间(s)

wsTimeout: 20,

// 等待心跳响应时间(s),等待心跳的响应时间要大于心跳时间5s以上

waitHeartTime: 25

}

// 开启心跳

wsHeartStart({ state, dispatch }) {

timer.wsTimeoutObj = setTimeout(() => {

if(state.ws && state.ws.readyState == 1) {

state.ws.send(‘’)

} else {

dispatch(‘handlerWSError’)

}

}, state.wsTimeout * 1000)

timer.serverTimeoutObj = setTimeout(() => {

console.log(‘接收心跳异常!’)

dispatch(‘handlerWSError’)

}, state.waitHeartTime * 1000)

}

稍微解释一下:上面这个代码片段,描述了心跳的基本意思;就是用定时器去向服务端发送一个空的字符串,我们与后端约定,当后端 ws 收到空字符串的时候,要回一个字符串。如果我们没有收到,则判断为 接收心跳异常,准备重连机制。(完整代码在文章末尾)

要点总结

===================================================================

要点总结的内容,建议大家细细品一下。

  • WebSocket 协议本质上是一个基于 TCP 的协议。为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息 "Upgrade: WebSocket" 表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。【如下图:】
    • 软件通信有七层结构,下三层结构偏向与数据通信,上三层更偏向于数据处理,中间的传输层则是连接上三层与下三层之间的桥梁,每一层都做不同的工作,上层协议依赖于下层协议。基于这个通信结构的概念。Socket 其实并不是一个协议,是应用层与 TCP/IP 协议族通信的中间软件抽象层,它是一组接口。当两台主机通信时,让 Socket 去组织数据,以符合指定的协议。TCP 连接则更依靠于底层的 IP 协议,IP 协议的连接则依赖于链路层等更低层次。WebSocket 则是一个典型的应用层协议。总的来说:Socket 是传输控制层协议,WebSocket 是应用层协议。

      问题思考

      ===================================================================

      • 如何做鉴权操作,例如 ws 请求中添加自定义 headers ?

        扩展知识

        ===================================================================

        那么,除了 websocket 还有哪些能实现长连接的工具呢?

        1、SSE(Server-sent Events)

        SSE(Server-sent Events)是 WebSocket 的一种轻量代替方案,使用 HTTP 协议。 => Server-Sent Events 教程

        2、stomp 介绍

        3、MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)

        MQTT JavaScript 客户端库

        MQTT 入门介绍

        4、课外阅读:[WebSocket 是什么原理?为什么可以实现持久连接?

        ]( )

        源代码

        ==================================================================

        import { EventLsbridge } from ‘@/common/eventLsbridge’

        import { loadFromSession } from ‘@/common/session-storage’

        import { Message } from ‘element-ui’

        const timer = {

        reconnectObj: null,

        wsTimeoutObj: null,

        serverTimeoutObj: null,

        // 重连时间间隔(s)

        reconnectTime: 3

        }

        const state = {

        ws: null,

        // 心跳时间(s)

        wsTimeout: 20,

        // 等待心跳响应时间(s),等待心跳的响应时间要大于心跳时间4s以上

        waitHeartTime: 24

        }

        const mutations = {

        set_reconnectObj: (state, val) => {

        state.reconnectObj = val

        },

        }

        const actions = {

        // 心跳重置

        wsHearReset({ dispatch }) {

        clearTimeout(timer.serverTimeoutObj)

        clearTimeout(timer.wsTimeoutObj)

        dispatch(‘wsHeartStart’)

        },

        // 开启心跳

        wsHeartStart({ state, dispatch }) {

        timer.wsTimeoutObj = setTimeout(() => {

        if(state.ws && state.ws.readyState == 1) {

        state.ws.send(‘’)

        } else {

        dispatch(‘handlerWSError’)

        }

        }, state.wsTimeout * 1000)

        timer.serverTimeoutObj = setTimeout(() => {

        console.log(‘接收心跳异常!’)

        dispatch(‘handlerWSError’)

        }, state.waitHeartTime * 1000)

        },

        // 初始化ws连接

        initWebsocket({ dispatch, state }) {

        if (state.ws) {

        return

        } else {

        return new Promise(resolve => {

        let url = ${process.env['VUE_APP_WEBSOCKET']}/websocket

        state.ws = new WebSocket(url)

        state.ws.addEventListener(‘open’, e => {

        console.log(‘长连接连接成功’)

        clearTimeout(timer.reconnectObj)

        dispatch(‘wsHeartStart’)

        })

        state.ws.addEventListener(‘message’, e => {

        dispatch(‘wsHearReset’)

        dispatch(‘handlerWSMessage’, e)

        })

        state.ws.addEventListener(‘close’, e => {

        console.log(‘ws close’)

        dispatch(‘handlerWSClose’, e)

        })

        state.ws.addEventListener(‘error’, e => {

        console.log(‘ws error’)

        dispatch(‘handlerWSError’, e)

        })

        })

        }

        },

        handlerSend({state}, id = -1) {

        if(!state.ws) {

        return

        }

        if(state.ws.readyState == 1) {

        state.ws.send(

        JSON.stringify({

        id

        })

        )

        }

        },

        handlerWSClose({ state }, e) {

        state.ws?.close()

        },

        handlerWSError({state, dispatch}, e) {

        console.log(‘ws-error’)

        state.ws?.close()

        state.ws = null

        dispatch(‘reconnect’)

        },

        reconnect({state, commit, dispatch}) {

        console.log(‘ws-重连’)

        clearTimeout(timer.wsTimeoutObj)

        clearTimeout(timer.serverTimeoutObj)

        clearTimeout(timer.reconnectObj)

        if (loadFromSession(‘userInfo’)?.userId) {

        Message.warning(‘网络出现异常,请检查网络后尝试刷新页面’)

        }

        timer.reconnectObj = window.setTimeout(() => {

        dispatch(‘initWebsocket’)

        timer.reconnectTime += 4

        if(timer.reconnectTime > 60) {

        timer.reconnectTime = 20

        }

        }, timer.reconnectTime * 1000)

        },

        // ws回调

        handlerWSMessage({state}, e) {

        let respData = {}

        try {

        respData = JSON.parse(e.data)

        } catch (e) {

        // not todo

        }

        if (respData?.data) {

        EventLsbridge.vueEmit(EventLsbridge.eventName.wsData, respData)

        }

        }

        }

        export default {

        namespaced: true,

        state,

        mutations,

        actions

        }

        自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

        深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

        因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

        既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

        由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

        如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

        最后

        基础知识是前端一面必问的,如果你在基础知识这一块翻车了,就算你框架玩的再6,webpack、git、node学习的再好也无济于事,因为对方就不会再给你展示的机会,千万不要因为基础错过了自己心怡的公司。前端的基础知识杂且多,并不是理解就ok了,有些是真的要去记。当然了我们是牛x的前端工程师,每天像背英语单词一样去背知识点就没必要了,只要平时工作中多注意总结,面试前端刷下题目就可以了。

        什么?你问面试题资料在哪里,这不是就在你眼前吗(滑稽

        发知识点,真正体系化!**

        [外链图片转存中…(img-7vj58319-1712998991488)]

        由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

        如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

        最后

        基础知识是前端一面必问的,如果你在基础知识这一块翻车了,就算你框架玩的再6,webpack、git、node学习的再好也无济于事,因为对方就不会再给你展示的机会,千万不要因为基础错过了自己心怡的公司。前端的基础知识杂且多,并不是理解就ok了,有些是真的要去记。当然了我们是牛x的前端工程师,每天像背英语单词一样去背知识点就没必要了,只要平时工作中多注意总结,面试前端刷下题目就可以了。

        什么?你问面试题资料在哪里,这不是就在你眼前吗(滑稽

        资料领取方式:戳这里获取

转载请注明来自码农世界,本文标题:《【前端】websocket 讲解与项目中的使用(附源码)》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,137人围观)参与讨论

还没有评论,来说两句吧...

Top