382 lines
10 KiB
JavaScript
382 lines
10 KiB
JavaScript
/**
|
||
* 前端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连接'); |