ai问答:使用 Vue3 组合式API 和 TS 封装 websocket 断线重连

这是一个使用 Vue3 组合式 API 和 TS 封装 websocket 的例子

这个组件在 setup 中:

  • 创建了一个 WebSocket 连接
  • 定义了 sendMessage 方法发送消息
  • 监听 WebSocket 的开启、接收消息和关闭事件
  • 暴露 sendMessage、onClose 方法给模板使用
import {ref} from 'vue'

export default {
    setup() {
        const ws = ref<WebSocket>()
        const text = ref<number | string>(1)
        const reconnect = ref<boolean>(false)

        function init() {
            // http://www.websocket-test.com/
            ws.value = new WebSocket('ws://121.40.165.18:8800')

            // 实例 - 打开连接
            ws.value.onopen = () => {
                console.log('WebSocket connected!')
                reconnect.value = false
            }

            // 实例 - 接受数据
            ws.value.onmessage = ({data}) => {
                console.log('Received message:', data)
            }

            // 实例 - 监听关闭
            ws.value.onclose = () => {
                console.log('WebSocket closed!')
                if (!reconnect.value) {
                    reconnect.value = true
                    setTimeout(init, 1000)
                }
            }
        }

        // 实例 - 关闭连接
        function onClose() {
            ws.value?.close()
        }

        // 实例 - 发送数据
        function sendMessage(msg: any) {
            text.value = msg + 1
            ws.value?.send(msg + 1)
        }

        init()

        return {text, sendMessage, onClose}
    }
}

那么,可以通过组件:

  • 输入消息(默认是数字)并点击 发送按钮
  • 触发 sendMessage 方法,通过 WebSocket 连接发送消息
  • 接收来自 WebSocket 服务端的响应消息
  • 监听 WebSocket 状态变化
  • 触发 onClose 方法,关闭 WebSocket 连接,测试断线重连功能

使用这个组件的模板:

<div class="parent">
    <div>
        <input v-model="text">
        <button @click="sendMessage(text)">Send</button>
    </div>
    <div>
        <button @click="onClose">断线重连</button>
    </div>
</div>

这是一个基本的 WebSocket 断线重连示例:

  • 在 setup 中处理逻辑
  • 暴露需要在模板或外部使用的方法/数据
  • 模板中可以直接使用这些方法/数据

完善的演示代码如下:

<template>
    <div class="parent">
        <div>
            <input v-model="text">
            <button @click="sendMessage(text)">Send</button>
        </div>
        <ul>
            <li v-for="(num,idx) in list" key="idx" v-html="num"></li>
        </ul>
        <div v-if="active">
            <button @click="onClose">断线重连</button>
        </div>
    </div>
</template>
import {ref} from 'vue'

export default {
    setup() {
        const ws = ref<WebSocket>()
        const text = ref<number|string>(1)
        const reconnect = ref<boolean>(false)
        
        const list = ref<any>([])
        const active = ref(false)
        const timer = ref(0)

        function init() {
            // http://www.websocket-test.com/
            ws.value = new WebSocket('ws://121.40.165.18:8800')

            // 实例 - 打开连接
            ws.value.onopen = () => {
                console.log('WebSocket connected!')

                // 断线重连 - 标记
                reconnect.value = false

                // 断线重连 - 按钮
                active.value = true

                // 停止重连
                clearInterval(timer.value)
            }

            // 实例 - 接受数据
            ws.value.onmessage = ({data}) => {
                console.log('Received message:', data)
                list.value.push(data);
            }

            // 实例 - 监听关闭
            ws.value.onclose = () => {
                console.log('WebSocket closed!')
                if (!reconnect.value) {
                    connect();
                }
            }
        }

        // 实例 - 关闭连接
        function onClose() {
            list.value = []
            active.value = false
            ws.value?.close()
        }

        // 实例 - 发送数据
        function sendMessage(msg: string) {
            text.value = msg + 1
            ws.value?.send(msg + 1)
        }

        init()

        // 断线重连
        function connect() {
            reconnect.value = true
            timer.value = setInterval(init, 1000)
        }

        return {text, list, active, sendMessage, onClose}
    }
}
posted @ 2023-04-24 16:01  让梦想纵横  阅读(451)  评论(0编辑  收藏  举报