對應文章:進一步完善前端框架搭建及vue-konva依賴的使用(Vscode)-CSDN博客
目錄
一、后端開發
1.模擬傳感器數據
2.前端頁面呈現數據+后端互通
2.1更新模擬傳感器數據程序(多次請求)
2.2🧩 功能目標
2.3🧱 系統結構簡述
2.4? 實現步驟(附代碼)
2.4.1步驟1:Django 視圖中添加獲取模擬傳感器數據的接口
2.4.2步驟2:配置 Django URL 路由
2.4.3步驟3:前端 Vue3 使用 Axios 獲取數據
2.4.4完善2.4.3
一、后端開發
功能模塊 | 子功能 | 描述 | 技術建議 |
---|---|---|---|
🧪 模擬傳感器程序 | 數據模擬 | 模擬溫度、濕度、火情等傳感器數據 | Python 腳本 / Node.js |
網絡發送 | 將數據定時打包并發送至本機某個端口(TCP/UDP) | Socket 編程 | |
配置可調 | 支持調整模擬頻率、數值范圍等 | JSON 配置或命令行參數 | |
🌐 后端服務 | 端口監聽 | 后端監聽指定端口,接收來自模擬程序的數據 | Spring Boot / Node.js / django |
數據解析 | 將接收到的字符串(如 JSON)解析為結構化數據 | JSON解析器 | |
數據推送 | 使用 WebSocket 將實時數據推送給前端 | Spring Boot WebSocket / Socket.IO | |
REST 查詢接口 | 提供歷史數據查詢接口(可選) | RESTful API | |
日志與錯誤處理 | 數據記錄、連接失敗、格式異常處理 | 日志組件如 Logback |
1.模擬傳感器數據
由于硬件還未到位所以手動模擬傳感器數據:
-
在原本的工程中創建腳本文件夾:scripts
然后再創建🧪 模擬傳感器程序:
# sensor_simulator.py import socket import json import random import time ? # 模擬數據生成函數 def generate_sensor_data():return {"temperature": round(random.uniform(20, 40), 2), # 攝氏度"humidity": round(random.uniform(30, 90), 2), ? ? # 百分比"light": random.randint(100, 1000), ? ? ? ? ? ? ? # lux"pressure": random.randint(80, 120), ? ? ? ? ? ? # kPa} ? # 啟動 TCP 服務器 def start_sensor_server(host='127.0.0.1', port=9000):server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind((host, port))server_socket.listen(1)print(f"傳感器模擬器已啟動,監聽 {host}:{port}") ?client_socket, addr = server_socket.accept()print(f"客戶端已連接:{addr}") ?try:while True:data = generate_sensor_data()json_data = json.dumps(data)client_socket.sendall((json_data + '\n').encode('utf-8'))print(f"發送數據: {json_data}")time.sleep(2) # 每2秒發送一次數據except (ConnectionResetError, BrokenPipeError):print("客戶端斷開連接")finally:client_socket.close()server_socket.close() ? if __name__ == '__main__':start_sensor_server() ?
同時呢,可以寫一個模擬前端的測試程序,看模擬傳感器數據程序是否正常運行:
# test_client.py import socket ? with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:s.connect(('127.0.0.1', 9000))while True:data = s.recv(1024)print("接收到數據:", data.decode('utf-8'))
然后,我們就在Vscode中創建兩個終端分別運行這兩個腳本文件:
PS E:\py_project\Security_System\Security_System_workplace\Security_System_project\scripts> python .\sensor_simulator_v2.py ? PS E:\py_project\Security_System\Security_System_workplace\Security_System_project\scripts> python .\test_client.py
如圖所示:
2.前端頁面呈現數據+后端互通
2.1更新模擬傳感器數據程序(多次請求)
# sensor_simulator.py import socket import json import random import time ? # 生成模擬傳感器數據 def generate_sensor_data():return {"temperature": round(random.uniform(20, 40), 2), # 攝氏度"humidity": round(random.uniform(30, 90), 2), ? ? # 百分比"light": random.randint(100, 1000), ? ? ? ? ? ? ? # lux"pressure": random.randint(80, 120), ? ? ? ? ? ? # kPa"timestamp": time.strftime('%Y-%m-%d %H:%M:%S')} ? def start_sensor_server(host='127.0.0.1', port=9000):server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server_socket.bind((host, port))server_socket.listen()print(f"傳感器模擬器已啟動,監聽 {host}:{port}") ?try:while True:# 等待客戶端連接client_socket, addr = server_socket.accept()print(f"新連接:{addr}") ?# 生成并發送一次數據data = generate_sensor_data()json_data = json.dumps(data)client_socket.sendall(json_data.encode('utf-8'))client_socket.close() # 關閉當前連接except KeyboardInterrupt:print("模擬器已停止")finally:server_socket.close() ? if __name__ == '__main__':start_sensor_server() ?
2.2🧩 功能目標
通過 Django 后端連接本地 socket 模擬器程序,將接收到的數據通過接口返回給 Vue 前端頁面進行展示。
2.3🧱 系統結構簡述
Vue3 (前端頁面)? Axios 請求 Django 后端接口? socket 通信 傳感器模擬器(本地監聽端口)
2.4? 實現步驟(附代碼)
2.4.1步驟1:Django 視圖中添加獲取模擬傳感器數據的接口
def get_sensor_data(request):try:# 創建 socket 客戶端連接本地監聽端口with socket.create_connection(("127.0.0.1", 9000), timeout=5) as client:# 接收數據(1024字節)received_data = client.recv(1024).decode('utf-8')parsed_data = json.loads(received_data) # ? 轉為 dictreturn JsonResponse({"status": "success", "data": parsed_data})except Exception as e:return JsonResponse({"status": "error", "message": str(e)})
2.4.2步驟2:配置 Django URL 路由
path('api/sensor-data/', views.get_sensor_data, name='get_sensor_data')
2.4.3步驟3:前端 Vue3 使用 Axios 獲取數據
<template><div class="sensor-view"><h2>實時傳感器數據</h2> ?<div v-if="error" class="error">{{ error }}</div> ?<div v-else-if="!sensorData || Object.keys(sensorData).length === 0" class="loading">加載中...</div> ?<div v-else class="sensor-data"><p><strong>溫度:</strong>{{ sensorData.temperature }} ℃</p><p><strong>濕度:</strong>{{ sensorData.humidity }} %</p><p><strong>光照強度:</strong>{{ sensorData.light }}</p><p><strong>氣壓:</strong>{{ sensorData.pressure }}</p><p><strong>時間戳:</strong>{{ sensorData.timestamp }}</p></div> ?<button @click="fetchData">刷新</button></div> </template> ? <script setup> import { ref, onMounted } from 'vue' import { getSensorData } from '@/api/sensor_data' ? const sensorData = ref(null) const error = ref(null) ? const fetchData = async () => {try {const res = await getSensorData()console.log('傳感器數據:', res.data)if (res.data.status === 'success') {sensorData.value = res.data.dataerror.value = null} else {error.value = res.data.message || '數據異常'}} catch (err) {error.value = '請求失敗:' + err.messageconsole.error(err)} } ? onMounted(() => {fetchData()setInterval(fetchData, 2000) }) </script> ? <style scoped> .sensor-view {max-width: 400px;margin: auto;padding: 20px;font-family: Arial, sans-serif; } ? .sensor-data p {margin: 6px 0; } ? .error {color: red; } ? .loading {color: gray; } ? button {margin-top: 12px;padding: 6px 12px; } </style> ?
2.4.4完善2.4.3
想要讓2.4.3中的組件在瀏覽器中能夠正常顯示,應該再做以下幾個操作:
-
Vue 前端通過 Axios 請求 Django 后端 API 接口。比如:
axios.get('http://127.0.0.1:8000/api/sensor-data/')
這樣前端才能訪問后端接口
-
因為前后端分別運行在不同端口,所以需要進行跨域配置:
前端:
-
首先:需要配置axios
操作步驟:
-
在src目錄下創建api文件夾放置有關后端的接口函數:
-
創建axios.js文件:
import axios from 'axios' ? const instance = axios.create({baseURL: 'http://127.0.0.1:8000/api', // Django 后端地址timeout: 5000, }) ? export default instance ?
-
就在全局中進行注冊axios:main.js文件中
// 全局掛載 axios 到 $axios app.config.globalProperties.$axios = axios
-
為了和后端接口對應上:path('api/sensor-data/', views.get_sensor_data, name='get_sensor_data'),
所以需要創建sensor_data.js文件中的接口函數:
// 獲取模擬傳感器數據 export const getSensorData = () => {return request.get('sensor-data/') // 實際訪問的是 http://127.0.0.1:8000/api/sensor-data/ }
-
接下來寫我們的傳感器數據組件即可:
<template><div class="sensor-view"><h2>實時傳感器數據</h2> ?<div v-if="error" class="error">{{ error }}</div> ?<div v-else-if="!sensorData || Object.keys(sensorData).length === 0" class="loading">加載中...</div> ?<div v-else class="sensor-data"><p><strong>溫度:</strong>{{ sensorData.temperature }} ℃</p><p><strong>濕度:</strong>{{ sensorData.humidity }} %</p><p><strong>光照強度:</strong>{{ sensorData.light }}</p><p><strong>氣壓:</strong>{{ sensorData.pressure }}</p><p><strong>時間戳:</strong>{{ sensorData.timestamp }}</p></div> ?<button @click="fetchData">刷新</button></div> </template> ? <script setup> import { ref, onMounted } from 'vue' import { getSensorData } from '@/api/sensor_data' ? const sensorData = ref(null) const error = ref(null) ? const fetchData = async () => {try {const res = await getSensorData()console.log('傳感器數據:', res.data)if (res.data.status === 'success') {sensorData.value = res.data.dataerror.value = null} else {error.value = res.data.message || '數據異常'}} catch (err) {error.value = '請求失敗:' + err.messageconsole.error(err)} } ? onMounted(() => {fetchData()setInterval(fetchData, 2000) }) </script> ? <style scoped> .sensor-view {max-width: 400px;margin: auto;padding: 20px;font-family: Arial, sans-serif; } ? .sensor-data p {margin: 6px 0; } ? .error {color: red; } ? .loading {color: gray; } ? button {margin-top: 12px;padding: 6px 12px; } </style> ?
-
運行后我們可以發現并沒有正確界面顯示
-
所以這就是我接下來要說的:
端口轉發問題:
配置 Vite 的開發代理
打開或創建
vite.config.js
文件,然后添加如下配置:// vite.config.js server: {proxy: {'/api': {target: 'http://127.0.0.1:8000',changeOrigin: true,// rewrite: (path) => path.replace(/^\/api/, '')}}}
-
同時我接下來要說的:
我們每次需要跳轉一個界面時都需要使用router(路由),所以我們需要再router下的index.js文件里面的內容完善以下:
import SensorViewer from '../components/SensorViewer.vue' { path: '/sensor-view',name: 'SensorView',component: SensorViewer}
-
后端:
-
首先:需要再settings.py文件中的INSTALLED_APPS中添加:
"corsheaders"
然后在MIDDLEWARE 中添加:
"corsheaders.middleware.CorsMiddleware",
注意:上面這行代碼必須在:
"django.middleware.common.CommonMiddleware",
之前。
-
接著:
配置允許的前端地址:
CORS_ALLOWED_ORIGINS = ["http://localhost:5173", # 允許 Vue 的端口 ]
-
獲取傳感器數據的視圖函數中:
parsed_data = json.loads(received_data) # ? 轉為 dict
將原本的字符串格式轉換成為JSON格式。
以JSON格式的數據傳遞給前端部分,然后前端獲取標準數據格式后進行數據解析最終
在頁面中呈現數據
-
實現效果圖: