BodyBalanceEvaluation/javascript_websocket_example.js
2025-07-29 18:28:40 +08:00

382 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 前端WebSocket连接示例 - JavaScript版本
* 使用Socket.IO客户端连接Flask-SocketIO后端
*/
// 引入Socket.IO客户端库
// 在HTML中添加: <script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
// 或者使用npm安装: npm install socket.io-client
class WebSocketManager {
constructor() {
this.socket = null;
this.isConnected = false;
this.isRtspRunning = false;
this.frameCount = 0;
this.reconnectAttempts = 0;
this.maxReconnectAttempts = 5;
this.reconnectInterval = 3000;
// 后端服务器配置
this.BACKEND_URL = 'http://localhost:5000'; // 根据实际情况修改
// 如果是远程服务器,使用: 'http://192.168.1.173:5000'
}
/**
* 连接WebSocket服务器
*/
connect() {
try {
console.log(`正在连接到 ${this.BACKEND_URL}`);
// 创建Socket.IO连接
this.socket = io(this.BACKEND_URL, {
transports: ['websocket', 'polling'], // 支持WebSocket和轮询
timeout: 10000, // 连接超时时间
forceNew: true, // 强制创建新连接
autoConnect: true // 自动连接
});
this.setupEventListeners();
} catch (error) {
console.error('连接异常:', error);
this.onError(error);
}
}
/**
* 设置事件监听器
*/
setupEventListeners() {
// 连接成功事件
this.socket.on('connect', () => {
this.isConnected = true;
this.reconnectAttempts = 0;
console.log(`WebSocket连接成功Socket ID: ${this.socket.id}`);
this.onConnect();
});
// 连接失败事件
this.socket.on('connect_error', (error) => {
this.isConnected = false;
console.error('连接失败:', error.message);
this.onConnectError(error);
this.attemptReconnect();
});
// 断开连接事件
this.socket.on('disconnect', (reason) => {
this.isConnected = false;
this.isRtspRunning = false;
console.log('连接断开:', reason);
this.onDisconnect(reason);
// 如果不是主动断开,尝试重连
if (reason !== 'io client disconnect') {
this.attemptReconnect();
}
});
// 监听RTSP状态事件
this.socket.on('rtsp_status', (data) => {
console.log('RTSP状态:', data);
this.handleRtspStatus(data);
});
// 监听RTSP帧数据
this.socket.on('rtsp_frame', (data) => {
if (data.image) {
this.frameCount++;
this.onRtspFrame(data.image);
// 每30帧记录一次
if (this.frameCount % 30 === 0) {
console.log(`已接收 ${this.frameCount}`);
}
}
});
}
/**
* 断开WebSocket连接
*/
disconnect() {
if (this.socket) {
this.socket.disconnect();
this.socket = null;
this.isConnected = false;
this.isRtspRunning = false;
console.log('主动断开连接');
}
}
/**
* 启动RTSP视频流
*/
startRtsp() {
if (this.socket && this.isConnected) {
console.log('发送start_rtsp事件');
this.socket.emit('start_rtsp');
this.frameCount = 0;
} else {
console.warn('WebSocket未连接无法启动RTSP');
}
}
/**
* 停止RTSP视频流
*/
stopRtsp() {
if (this.socket && this.isConnected) {
console.log('发送stop_rtsp事件');
this.socket.emit('stop_rtsp');
} else {
console.warn('WebSocket未连接无法停止RTSP');
}
}
/**
* 处理RTSP状态变化
*/
handleRtspStatus(data) {
switch (data.status) {
case 'started':
this.isRtspRunning = true;
this.onRtspStarted();
break;
case 'stopped':
this.isRtspRunning = false;
this.onRtspStopped();
break;
case 'already_running':
console.log('RTSP已在运行中');
this.isRtspRunning = true;
break;
case 'error':
console.error('RTSP错误:', data.message);
this.onRtspError(data.message);
break;
}
}
/**
* 尝试重连
*/
attemptReconnect() {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.reconnectAttempts++;
console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
setTimeout(() => {
this.connect();
}, this.reconnectInterval);
} else {
console.error('WebSocket重连失败已达到最大重试次数');
this.onReconnectFailed();
}
}
// ========== 事件回调函数(可以被重写) ==========
/**
* 连接成功回调
*/
onConnect() {
// 可以在这里添加连接成功后的逻辑
console.log('WebSocket连接成功回调');
}
/**
* 连接错误回调
*/
onConnectError(error) {
// 可以在这里添加连接错误处理逻辑
console.log('WebSocket连接错误回调:', error);
}
/**
* 断开连接回调
*/
onDisconnect(reason) {
// 可以在这里添加断开连接处理逻辑
console.log('WebSocket断开连接回调:', reason);
}
/**
* 通用错误回调
*/
onError(error) {
// 可以在这里添加错误处理逻辑
console.log('WebSocket错误回调:', error);
}
/**
* RTSP启动回调
*/
onRtspStarted() {
console.log('RTSP视频流已启动');
}
/**
* RTSP停止回调
*/
onRtspStopped() {
console.log('RTSP视频流已停止');
}
/**
* RTSP错误回调
*/
onRtspError(message) {
console.error('RTSP错误:', message);
}
/**
* RTSP帧数据回调
* @param {string} base64Image - Base64编码的图像数据
*/
onRtspFrame(base64Image) {
// 在这里处理接收到的视频帧
// 例如显示在img元素中
const imgElement = document.getElementById('rtspImage');
if (imgElement) {
imgElement.src = 'data:image/jpeg;base64,' + base64Image;
}
}
/**
* 重连失败回调
*/
onReconnectFailed() {
console.error('WebSocket重连失败');
}
}
// ========== 使用示例 ==========
// 创建WebSocket管理器实例
const wsManager = new WebSocketManager();
// 重写回调函数(可选)
wsManager.onConnect = function() {
console.log('自定义连接成功处理');
// 连接成功后可以自动启动RTSP
// this.startRtsp();
};
wsManager.onRtspFrame = function(base64Image) {
// 自定义帧处理逻辑
const imgElement = document.getElementById('videoDisplay');
if (imgElement) {
imgElement.src = 'data:image/jpeg;base64,' + base64Image;
imgElement.style.display = 'block';
}
};
// ========== 具体使用方法 ==========
/**
* 1. 连接WebSocket
*/
function connectWebSocket() {
wsManager.connect();
}
/**
* 2. 断开WebSocket
*/
function disconnectWebSocket() {
wsManager.disconnect();
}
/**
* 3. 启动RTSP视频流
*/
function startRtspStream() {
wsManager.startRtsp();
}
/**
* 4. 停止RTSP视频流
*/
function stopRtspStream() {
wsManager.stopRtsp();
}
/**
* 5. 检查连接状态
*/
function checkConnectionStatus() {
console.log('连接状态:', wsManager.isConnected);
console.log('RTSP状态:', wsManager.isRtspRunning);
console.log('接收帧数:', wsManager.frameCount);
}
// ========== HTML页面中的使用示例 ==========
/*
<!DOCTYPE html>
<html>
<head>
<title>WebSocket RTSP示例</title>
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
</head>
<body>
<div>
<button onclick="connectWebSocket()">连接</button>
<button onclick="disconnectWebSocket()">断开</button>
<button onclick="startRtspStream()">启动RTSP</button>
<button onclick="stopRtspStream()">停止RTSP</button>
<button onclick="checkConnectionStatus()">检查状态</button>
</div>
<div>
<h3>视频显示</h3>
<img id="videoDisplay" style="max-width: 100%; display: none;" />
</div>
<script src="javascript_websocket_example.js"></script>
</body>
</html>
*/
// ========== Node.js环境中的使用示例 ==========
/*
// 安装依赖: npm install socket.io-client
const { io } = require('socket.io-client');
// 然后使用上面的WebSocketManager类
const wsManager = new WebSocketManager();
wsManager.connect();
// 5秒后启动RTSP
setTimeout(() => {
wsManager.startRtsp();
}, 5000);
// 30秒后停止RTSP并断开连接
setTimeout(() => {
wsManager.stopRtsp();
setTimeout(() => {
wsManager.disconnect();
}, 2000);
}, 30000);
*/
// 导出类(用于模块化)
if (typeof module !== 'undefined' && module.exports) {
module.exports = WebSocketManager;
}
// 全局暴露(用于浏览器环境)
if (typeof window !== 'undefined') {
window.WebSocketManager = WebSocketManager;
window.wsManager = wsManager;
}
console.log('WebSocket管理器已加载可以使用 wsManager 实例或创建新的 WebSocketManager 实例');
console.log('使用方法:');
console.log('1. wsManager.connect() - 连接WebSocket');
console.log('2. wsManager.startRtsp() - 启动RTSP视频流');
console.log('3. wsManager.stopRtsp() - 停止RTSP视频流');
console.log('4. wsManager.disconnect() - 断开WebSocket连接');