当前位置: 首页 > news >正文

用vue3显示websocket的状态

在上次vue3项目上增加一个标签,显示当前的连接状态,两个按钮:重新连接 和 断开连接

修改App.vue

<template>
  <header>
    <title>ws状态测试</title>
  </header>

  <main>
    <WsStatus />
  </main>
</template>

<script setup lang="ts">
import WsStatus from './components/WsStatus.vue'
</script>

<style scoped>
header {
  line-height: 1.5;
}

.logo {
  display: block;
  margin: 0 auto 2rem;
}

@media (min-width: 1024px) {
  header {
    display: flex;
    place-items: center;
    padding-right: calc(var(--section-gap) / 2);
  }

  .logo {
    margin: 0 2rem 0 0;
  }

  header .wrapper {
    display: flex;
    place-items: flex-start;
    flex-wrap: wrap;
  }
}
</style>

WsStatus.vue

创建一个组件WsStatus.vue

<template>
    <div class="WsStatus">
        <h1>WebSocket 测试</h1>
        <div class="status">
            连接状态: <span :class="statusClass">{{ connectionStatus }}</span>
        </div>
        <button @click="reconnect" :disabled="isConnecting">
            {{ isConnecting ? '连接中...' : '重新连接' }}
        </button>
        <button @click="closeConnect" :disabled="connectStatus">断开连接</button>
        <canvas></canvas>
    </div>
</template>

<script setup lang="ts" name="WsStatus">
import { ref, onMounted, onUnmounted } from 'vue'

const ws = ref()
const imageUrl = ref()
const connectionStatus = ref('未连接')
const isConnecting = ref(false)
const connectStatus = ref(false)
const statusClass = ref('disconnected')

function get_appropriate_ws_url(extra_url: string) {
    var pcol;
    // 获得页面上的url
    var u = document.URL;

    /*
     * We open the websocket encrypted if this page came on an
     * https:// url itself, otherwise unencrypted
     */

    // 去掉http://或者https://
    if (u.substring(0, 5) === "https") {
        pcol = "wss://";
        u = u.substr(8);
    } else {
        pcol = "ws://";
        if (u.substring(0, 4) === "http")
            u = u.substr(7);
    }

    /* + "/xxx" bit is for IE10 workaround */

    //回来的url就城了ws://地址或者wss://地址
    return pcol + u.split('/')[0] + "/" + extra_url;
}


// WebSocket配置(修改为你的服务器地址)
const wsUrl = get_appropriate_ws_url("")

const connectWebSocket = () => {
    if (isConnecting.value) return

    isConnecting.value = true
    connectionStatus.value = '连接中...'
    statusClass.value = 'connecting'

    ws.value = new WebSocket(wsUrl)

    ws.value.onopen = () => {
        connectionStatus.value = '已连接'
        statusClass.value = 'connected'
        isConnecting.value = false
        connectStatus.value = false
    }

    ws.value.onmessage = (event: any) => {
        console.log('收到数据')

    }

    ws.value.onerror = (error: any) => {
        console.error('WebSocket错误:', error)
        connectionStatus.value = '连接错误'
        statusClass.value = 'error'
        isConnecting.value = false
    }

    ws.value.onclose = () => {
        connectionStatus.value = '连接已关闭'
        statusClass.value = 'disconnected'
        isConnecting.value = false
        connectStatus.value = true
    }
}


// 组件挂载时自动连接
onMounted(() => {
    connectWebSocket()
})

// 组件卸载时关闭连接
onUnmounted(() => {
    if (ws.value) {
        ws.value.close()
    }
})

function reconnect() {
    if (ws.value) {
        ws.value.close()
    }
    connectWebSocket()
}

function closeConnect() {
    if (ws.value) {
        ws.value.close()
    }
}

</script>

<style scoped>
.websocket-page {
    padding: 20px;
    max-width: 800px;
    margin: 0 auto;
}

.status {
    margin: 20px 0;
    font-size: 18px;
}

.status span {
    font-weight: bold;
}

.connected {
    color: #4CAF50;
}

.connecting {
    color: #FFC107;
}

.disconnected {
    color: #F44336;
}

.error {
    color: #F44336;
}

button {
    padding: 10px 20px;
    background-color: #2196F3;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}

button:disabled {
    background-color: #BBDEFB;
    cursor: not-allowed;
}

.messages {
    margin-top: 30px;
    border-top: 1px solid #eee;
    padding-top: 20px;
    background-size: 100% 100%;
}

ul {
    list-style-type: none;
    padding: 0;
    max-height: 300px;
    overflow-y: auto;
    border: 1px solid #ddd;
    padding: 10px;
    border-radius: 4px;
}

li {
    padding: 5px 0;
    border-bottom: 1px solid #eee;
}

.live-image {
    position: fixed;
    top: 50%;
    left: 50%;
    width: 100vw;
    /* 根据需要设置宽度 */
    height: 100vw;

    object-fit: cover;
    transform: translate(-50%, -50%);
}

#camImage,
#canvas {
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    /* height: 100%; */
    z-index: -1;
}

/* 竖屏 */
@media screen and (orientation: portrait) {}

/* 横屏 */
@media screen and (orientation: landscape) {}
</style>

编译打包上传部署

$ npm run build
$ scp -r ./dist/* root@192.168.9.163:/oem/usr/www

测试

在rv1106摄像头打开运行ws服务器

# /oem/usr/bin/ws_cam

浏览器访问 http://192.168.9.163:7681/
看到相应页面,按按键会有相应的变换。

相关文章:

  • # RAG 框架 # 一文入门 全链路RAG系统构建与优化 —— 架构、策略与实践
  • DeepSeek:开启机器人智能化的革命性突破
  • 计算机视觉|Swin Transformer:视觉 Transformer 的新方向
  • 基于springboot的仓库管理系统
  • 鸿蒙Next开发中的坑与问题总结
  • Flutter中的const和final的区别
  • Linux的部分常用基础指令
  • 一周学会Flask3 Python Web开发-SQLAlchemy删除数据操作-班级模块
  • 算法日常刷题笔记(5)
  • 人工智能中神经网络是如何进行学习的
  • asp.net webform组件和常见的html组件的使用
  • 【设计模式】】工厂模式
  • R 语言科研绘图 --- 密度图-汇总
  • Spring Boot整合Sa-Token极简指南
  • C++ QT零基础教学(二)
  • 六种最新优化算法(TOC、MSO、AE、DOA、GOA、OX)求解多个无人机协同路径规划(可以自定义无人机数量及起始点),MATLAB代码
  • 算法专题一:双指针
  • 基于eNSP的IPV4和IPV6企业网络规划
  • Mac电脑python 有没有ros接口 查看lidar的数据
  • Vue配置和安装教程(2025最新)
  • 上海一隧道成“王家卫风”网红拍照点?交管部门已专项整治,一人被处罚
  • 马斯克:大幅削减政治支出,仍将执掌特斯拉至少5年,除非去世
  • 失智老人有两个儿子却欠费住养老院两年多,法检合力指定监护人
  • 上海皮影戏《九色鹿》闪耀塞尔维亚,再获2项国际大奖
  • 围绕“工程智能”系统布局,同济大学官宣成立五大研究院
  • 三部门印发《2025年深入推进IPv6规模部署和应用工作要点》