最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于Vue3+WebSocket實(shí)現(xiàn)實(shí)時(shí)文件傳輸監(jiān)控系統(tǒng)

 更新時(shí)間:2025年03月26日 10:20:45   作者:北辰alk  
WebSocket是一種在客戶端和服務(wù)器之間進(jìn)行雙向通信的網(wǎng)絡(luò)協(xié)議,它通過建立持久性的、全雙工的連接,允許服務(wù)器主動(dòng)向客戶端發(fā)送數(shù)據(jù),本文小編給大家介紹了基于Vue3+WebSocket實(shí)現(xiàn)實(shí)時(shí)文件傳輸監(jiān)控系統(tǒng),需要的朋友可以參考下

一、需求分析與技術(shù)選型

1.1 實(shí)時(shí)監(jiān)控系統(tǒng)核心需求

  • 實(shí)時(shí)顯示文件傳輸進(jìn)度
  • 動(dòng)態(tài)更新傳輸速度/剩余時(shí)間
  • 多任務(wù)并行狀態(tài)管理
  • 異常中斷實(shí)時(shí)告警
  • 歷史傳輸記錄可視化

1.2 技術(shù)架構(gòu)設(shè)計(jì)

1.3 技術(shù)棧說明

  • 前端:Vue3 + Element Plus + ECharts
  • 實(shí)時(shí)通信:WebSocket + Socket.IO
  • 后端:Node.js + Express + WebSocket
  • 數(shù)據(jù)存儲(chǔ):MongoDB(歷史記錄)
  • 輔助庫:dayjs(時(shí)間處理)、lodash(數(shù)據(jù)處理)

二、環(huán)境搭建與配置

2.1 創(chuàng)建Vue3項(xiàng)目

npm create vue@latest
# 選擇TypeScript、Router、Pinia

2.2 安裝核心依賴

npm install socket.io-client @types/socket.io-client echarts element-plus

2.3 WebSocket服務(wù)端搭建

// server/ws-server.js
const express = require('express')
const { createServer } = require('http')
const { Server } = require('socket.io')

const app = express()
const httpServer = createServer(app)
const io = new Server(httpServer, {
  cors: {
    origin: "http://localhost:5173",
    methods: ["GET", "POST"]
  }
})

// 連接管理
const activeConnections = new Map()

io.on('connection', (socket) => {
  console.log(`客戶端連接: ${socket.id}`)
  
  // 身份驗(yàn)證
  socket.on('auth', (token) => {
    const userId = verifyToken(token) // 鑒權(quán)邏輯
    activeConnections.set(userId, socket)
  })

  // 斷開處理
  socket.on('disconnect', () => {
    activeConnections.delete(socket.userId)
  })
})

httpServer.listen(3001)

三、前端WebSocket集成

3.1 Socket服務(wù)封裝

// src/utils/socket.ts
import { io, Socket } from 'socket.io-client'

class SocketService {
  private static instance: SocketService
  private socket: Socket | null = null
  
  constructor() {
    this.initSocket()
  }

  public static getInstance(): SocketService {
    if (!SocketService.instance) {
      SocketService.instance = new SocketService()
    }
    return SocketService.instance
  }

  private initSocket(): void {
    this.socket = io('http://localhost:3001', {
      transports: ['websocket'],
      auth: {
        token: localStorage.getItem('token')
      }
    })

    this.socket.on('connect', () => {
      console.log('WebSocket連接成功')
    })

    this.socket.on('exception', (error) => {
      console.error('WebSocket錯(cuò)誤:', error)
    })
  }

  // 監(jiān)聽傳輸事件
  public onFileProgress(callback: (data: TransferData) => void): void {
    this.socket?.on('file-progress', callback)
  }

  // 發(fā)送控制命令
  public sendControl(command: ControlCommand): void {
    this.socket?.emit('transfer-control', command)
  }
}

export const socket = SocketService.getInstance()

四、實(shí)時(shí)監(jiān)控界面開發(fā)

4.1 傳輸任務(wù)列表組件

<template>
  <el-table :data="tasks" style="width: 100%">
    <el-table-column prop="fileName" label="文件名" />
    <el-table-column label="進(jìn)度">
      <template #default="{ row }">
        <el-progress 
          :percentage="row.progress" 
          :status="getStatus(row)"
        />
      </template>
    </el-table-column>
    <el-table-column label="速度">
      <template #default="{ row }">
        {{ formatSpeed(row.speed) }}
      </template>
    </el-table-column>
    <el-table-column label="操作">
      <template #default="{ row }">
        <el-button @click="handlePause(row.id)">暫停</el-button>
      </template>
    </el-table-column>
  </el-table>
</template>

4.2 實(shí)時(shí)速度圖表(ECharts集成)

<script setup lang="ts">
import * as echarts from 'echarts'

const chartRef = ref<HTMLElement>()
let chart: echarts.ECharts

onMounted(() => {
  chart = echarts.init(chartRef.value)
  
  const option = {
    xAxis: { type: 'time' },
    yAxis: { name: '速度 (MB/s)' },
    series: [{
      data: [],
      type: 'line',
      smooth: true
    }]
  }
  
  chart.setOption(option)
})

// 更新圖表數(shù)據(jù)
const updateChart = (newData: SpeedPoint[]) => {
  chart.setOption({
    series: [{
      data: newData
    }]
  })
}
</script>

五、文件傳輸核心邏輯

5.1 增強(qiáng)版文件上傳器

class EnhancedFileUploader {
  private ws: WebSocket
  private file: File
  private chunkSize: number
  private uploadedBytes = 0
  
  constructor(file: File) {
    this.file = file
    this.chunkSize = this.calculateChunkSize()
    this.ws = new WebSocket('ws://localhost:3001/upload')
  }

  private calculateChunkSize(): number {
    // 根據(jù)網(wǎng)絡(luò)速度動(dòng)態(tài)調(diào)整分片大小
    const baseSize = 1024 * 1024 // 1MB
    return navigator.connection?.downlink 
      ? baseSize * Math.floor(navigator.connection.downlink / 5)
      : baseSize
  }

  async startUpload() {
    const reader = new FileReader()
    let offset = 0
    
    const readChunk = () => {
      const chunk = this.file.slice(offset, offset + this.chunkSize)
      reader.readAsArrayBuffer(chunk)
    }

    reader.onload = (e) => {
      if (e.target?.result) {
        this.ws.send(e.target.result)
        this.uploadedBytes += this.chunkSize
        this.reportProgress()
        
        if (offset < this.file.size) {
          offset += this.chunkSize
          readChunk()
        }
      }
    }

    readChunk()
  }

  private reportProgress() {
    const progress = (this.uploadedBytes / this.file.size) * 100
    const speed = this.calculateSpeed()
    
    socket.sendControl({
      type: 'progress',
      data: {
        fileId: this.file.name,
        progress: Number(progress.toFixed(1)),
        speed: speed,
        remaining: this.calculateRemainingTime(speed)
      }
    })
  }
}

5.2 速度計(jì)算算法

class SpeedCalculator {
  private records: Array<{ time: number; bytes: number }> = []
  
  update(bytes: number): void {
    this.records.push({
      time: Date.now(),
      bytes: bytes
    })
    // 保留最近10秒記錄
    if (this.records.length > 10) {
      this.records.shift()
    }
  }

  get currentSpeed(): number {
    if (this.records.length < 2) return 0
    
    const first = this.records[0]
    const last = this.records[this.records.length - 1]
    const timeDiff = (last.time - first.time) / 1000
    const bytesDiff = last.bytes - first.bytes
    
    return bytesDiff / timeDiff // bytes/sec
  }
}

六、服務(wù)端實(shí)時(shí)處理

6.1 WebSocket事件處理器

// 文件傳輸事件處理
io.on('connection', (socket) => {
  socket.on('file-upload', async (chunk, ack) => {
    try {
      const filePath = path.join(uploadDir, fileName)
      await fs.promises.appendFile(filePath, Buffer.from(chunk))
      
      ack({
        status: 'success',
        received: chunk.length
      })
      
      // 廣播進(jìn)度更新
      io.emit('file-progress', {
        fileId: fileName,
        progress: calculateProgress(),
        speed: currentSpeed
      })
    } catch (error) {
      ack({ status: 'error', message: error.message })
    }
  })

  // 傳輸控制命令
  socket.on('transfer-control', (command) => {
    switch (command.type) {
      case 'pause':
        handlePause(command.fileId)
        break
      case 'resume':
        handleResume(command.fileId)
        break
      case 'cancel':
        handleCancel(command.fileId)
        break
    }
  })
})

6.2 傳輸狀態(tài)管理

class TransferManager {
  constructor() {
    this.transfers = new Map()
  }

  addTransfer(fileId, fileSize) {
    this.transfers.set(fileId, {
      startTime: Date.now(),
      bytesTransferred: 0,
      status: 'uploading'
    })
  }

  updateProgress(fileId, bytes) {
    const transfer = this.transfers.get(fileId)
    transfer.bytesTransferred += bytes
    transfer.lastUpdate = Date.now()
  }

  getTransferStatus(fileId) {
    return this.transfers.get(fileId) || null
  }
}

七、高級(jí)功能實(shí)現(xiàn)

7.1 斷線自動(dòng)重連

// 前端重連邏輯
class ReconnectManager {
  private retries = 0
  private maxRetries = 5
  
  constructor(private socket: Socket) {
    socket.on('disconnect', () => {
      this.scheduleReconnect()
    })
  }

  private scheduleReconnect() {
    if (this.retries < this.maxRetries) {
      setTimeout(() => {
        this.socket.connect()
        this.retries++
      }, Math.min(1000 * 2 ** this.retries, 30000))
    }
  }
}

7.2 帶寬節(jié)流控制

class BandwidthThrottle {
  private tokens: number
  private lastFill: number
  
  constructor(
    private capacity: number, // 帶寬容量(bytes/sec)
    private interval = 1000 // 令牌填充間隔
  ) {
    this.tokens = capacity
    this.lastFill = Date.now()
  }

  async consume(bytes: number): Promise<void> {
    const now = Date.now()
    const elapsed = now - this.lastFill
    
    if (elapsed > this.interval) {
      this.tokens = this.capacity
      this.lastFill = now
    }

    if (this.tokens >= bytes) {
      this.tokens -= bytes
      return
    }
    
    const waitTime = (bytes - this.tokens) / this.capacity * 1000
    await new Promise(resolve => setTimeout(resolve, waitTime))
    this.tokens = this.capacity - (bytes - this.tokens)
    this.lastFill = Date.now()
  }
}

7.3 傳輸質(zhì)量監(jiān)控

class NetworkMonitor {
  private latencyHistory: number[] = []
  private packetLossCount = 0
  
  start() {
    setInterval(async () => {
      const latency = await this.measureLatency()
      this.latencyHistory.push(latency)
      
      if (latency > 1000) {
        this.emit('high-latency', latency)
      }
    }, 5000)
  }

  private measureLatency(): Promise<number> {
    return new Promise((resolve) => {
      const start = Date.now()
      socket.emit('ping', () => {
        resolve(Date.now() - start)
      })
    })
  }
}

八、安全與優(yōu)化

8.1 安全防護(hù)措施

  • 傳輸加密:啟用WSS協(xié)議
  • 請(qǐng)求驗(yàn)證
// 服務(wù)端中間件
const authMiddleware = (socket, next) => {
  try {
    const token = socket.handshake.auth.token
    const decoded = jwt.verify(token, SECRET_KEY)
    socket.user = decoded
    next()
  } catch (error) {
    next(new Error('認(rèn)證失敗'))
  }
}
  • DDOS防護(hù):限制連接頻率
const limiter = rateLimit({
  windowMs: 60 * 1000, // 1分鐘
  max: 100 // 最大連接數(shù)
})

8.2 性能優(yōu)化策略

  • 二進(jìn)制傳輸優(yōu)化
// 使用MessagePack替代JSON
socket.emit('binary-data', msgpack.encode(largeData))
  • 心跳檢測(cè)機(jī)制
// 服務(wù)端設(shè)置
io.set('heartbeat interval', 5000)
io.set('heartbeat timeout', 10000)
  • 集群部署
# 使用Redis適配器
npm install @socket.io/redis-adapter

九、項(xiàng)目部署方案

9.1 生產(chǎn)環(huán)境架構(gòu)

9.2 Nginx配置示例

# WebSocket代理配置
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

server {
    listen 443 ssl;
    server_name example.com;

    location /socket.io/ {
        proxy_pass http://ws_backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
    }
}

十、效果演示與驗(yàn)證

10.1 測(cè)試場景設(shè)計(jì)

  1. 正常傳輸測(cè)試:上傳2GB文件觀察實(shí)時(shí)數(shù)據(jù)
  2. 網(wǎng)絡(luò)中斷測(cè)試:斷開網(wǎng)絡(luò)后恢復(fù)觀察續(xù)傳
  3. 多并發(fā)測(cè)試:同時(shí)上傳10個(gè)文件觀察性能
  4. 極限測(cè)試:模擬1%丟包率環(huán)境

10.2 監(jiān)控指標(biāo)驗(yàn)證

指標(biāo)預(yù)期結(jié)果
進(jìn)度更新頻率≤500ms
速度計(jì)算誤差≤5%
斷線重連時(shí)間≤3s
CPU占用率≤30%

十一、總結(jié)與展望

11.1 實(shí)現(xiàn)成果

  • 完整的實(shí)時(shí)文件傳輸監(jiān)控系統(tǒng)
  • 企業(yè)級(jí)WebSocket應(yīng)用架構(gòu)
  • 生產(chǎn)環(huán)境部署方案
  • 全面的異常處理機(jī)制

11.2 未來擴(kuò)展方向

  • 集成P2P傳輸協(xié)議
  • 添加AI預(yù)測(cè)傳輸時(shí)間
  • 實(shí)現(xiàn)跨設(shè)備同步傳輸
  • 開發(fā)移動(dòng)端適配版本

相關(guān)文章

  • Vue-cli@3.0 插件系統(tǒng)簡析

    Vue-cli@3.0 插件系統(tǒng)簡析

    Vue-cli@3.0 是一個(gè)全新的 Vue 項(xiàng)目腳手架。這篇文章主要介紹了Vue-cli@3.0 插件系統(tǒng)簡析,需要的朋友可以參考下
    2018-09-09
  • 詳解vuex的簡單使用

    詳解vuex的簡單使用

    這篇文章主要介紹了詳解vuex的簡單使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-03-03
  • vue+echarts圖表的基本使用步驟總結(jié)

    vue+echarts圖表的基本使用步驟總結(jié)

    這篇文章主要給大家介紹了關(guān)于vue+echarts圖表的基本使用步驟,Echarts是一款基于JavaScript的開源可視化圖表庫,而Vue是一種流行的JavaScript框架,用于構(gòu)建用戶界,需要的朋友可以參考下
    2023-11-11
  • 詳解vue 圖片上傳功能

    詳解vue 圖片上傳功能

    這篇文章主要介紹了vue 圖片上傳功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Vue.set()和this.$set()使用和區(qū)別

    Vue.set()和this.$set()使用和區(qū)別

    我們發(fā)現(xiàn)Vue.set()和this.$set()這兩個(gè)api的實(shí)現(xiàn)原理基本一模一樣,那么Vue.set()和this.$set()的區(qū)別是什么,本文詳細(xì)的介紹一下,感興趣的可以了解一下
    2021-06-06
  • Vue3+Ts實(shí)現(xiàn)父子組件間傳值的兩種方式

    Vue3+Ts實(shí)現(xiàn)父子組件間傳值的兩種方式

    這篇文章主要給大家介紹了基于Vue3+Ts實(shí)現(xiàn)父子組件間傳值的兩種方式,使用v-model+emit傳值和使用v-bind+emit傳值兩種方式,文章通過代碼示例介紹的非常詳細(xì),感興趣的同學(xué)可以參考閱讀
    2023-09-09
  • js節(jié)流防抖應(yīng)用場景,以及在vue中節(jié)流防抖的具體實(shí)現(xiàn)操作

    js節(jié)流防抖應(yīng)用場景,以及在vue中節(jié)流防抖的具體實(shí)現(xiàn)操作

    這篇文章主要介紹了js節(jié)流防抖應(yīng)用場景,以及在vue中節(jié)流防抖的具體實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Vue 滾動(dòng)行為的具體使用方法

    Vue 滾動(dòng)行為的具體使用方法

    本篇文章主要介紹了Vue 滾動(dòng)行為的具體使用方法。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • vue部署后靜態(tài)文件加載404的解決

    vue部署后靜態(tài)文件加載404的解決

    這篇文章主要介紹了vue部署后靜態(tài)文件加載404的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 基于vue+openlayer實(shí)現(xiàn)地圖聚合和撒點(diǎn)效果

    基于vue+openlayer實(shí)現(xiàn)地圖聚合和撒點(diǎn)效果

    Openlayers 是一個(gè)模塊化、高性能并且功能豐富的WebGIS客戶端的JavaScript包,用于顯示地圖及空間數(shù)據(jù),并與之進(jìn)行交互,具有靈活的擴(kuò)展機(jī)制,本文給大家介紹vue+openlayer實(shí)現(xiàn)地圖聚合效果和撒點(diǎn)效果,感興趣的朋友一起看看吧
    2021-09-09

最新評(píng)論

理塘县| 武鸣县| 舟山市| 紫金县| 清流县| 台州市| 刚察县| 资阳市| 江源县| 北京市| 环江| 综艺| 金川县| 会昌县| 巴塘县| 澄迈县| 河津市| 保定市| 玉门市| 武邑县| 大姚县| 涞源县| 平乐县| 康乐县| 渑池县| 册亨县| 三台县| 崇义县| 吉首市| 曲沃县| 醴陵市| 阿尔山市| 抚宁县| 彩票| 彭阳县| 南康市| 航空| 社旗县| 图们市| 灌云县| 白朗县|