BodyBalanceEvaluation/javascript_websocket_example.js

382 lines
10 KiB
JavaScript
Raw Normal View History

2025-07-29 18:28:40 +08:00
/**
* 前端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连接');