feat: 添加消息推送能力,添加新闻催化分析页的合规提示
This commit is contained in:
194
src/services/socketService.js
Normal file
194
src/services/socketService.js
Normal file
@@ -0,0 +1,194 @@
|
||||
// src/services/socketService.js
|
||||
/**
|
||||
* 真实 Socket.IO 服务 - 用于生产环境连接真实后端
|
||||
*/
|
||||
|
||||
import { io } from 'socket.io-client';
|
||||
import { logger } from '../utils/logger';
|
||||
import { getApiBase } from '../utils/apiConfig';
|
||||
|
||||
const API_BASE_URL = getApiBase();
|
||||
|
||||
class SocketService {
|
||||
constructor() {
|
||||
this.socket = null;
|
||||
this.connected = false;
|
||||
this.reconnectAttempts = 0;
|
||||
this.maxReconnectAttempts = 5;
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接到 Socket.IO 服务器
|
||||
* @param {object} options - 连接选项
|
||||
*/
|
||||
connect(options = {}) {
|
||||
if (this.socket && this.connected) {
|
||||
logger.warn('socketService', 'Already connected');
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info('socketService', 'Connecting to Socket.IO server...', { url: API_BASE_URL });
|
||||
|
||||
// 创建 socket 连接
|
||||
this.socket = io(API_BASE_URL, {
|
||||
transports: ['websocket', 'polling'],
|
||||
reconnection: true,
|
||||
reconnectionDelay: 1000,
|
||||
reconnectionDelayMax: 5000,
|
||||
reconnectionAttempts: this.maxReconnectAttempts,
|
||||
timeout: 20000,
|
||||
autoConnect: true,
|
||||
withCredentials: true, // 允许携带认证信息
|
||||
...options,
|
||||
});
|
||||
|
||||
// 监听连接成功
|
||||
this.socket.on('connect', () => {
|
||||
this.connected = true;
|
||||
this.reconnectAttempts = 0;
|
||||
logger.info('socketService', 'Socket.IO connected successfully', {
|
||||
socketId: this.socket.id,
|
||||
});
|
||||
});
|
||||
|
||||
// 监听断开连接
|
||||
this.socket.on('disconnect', (reason) => {
|
||||
this.connected = false;
|
||||
logger.warn('socketService', 'Socket.IO disconnected', { reason });
|
||||
});
|
||||
|
||||
// 监听连接错误
|
||||
this.socket.on('connect_error', (error) => {
|
||||
this.reconnectAttempts++;
|
||||
logger.error('socketService', 'connect_error', error, {
|
||||
attempts: this.reconnectAttempts,
|
||||
maxAttempts: this.maxReconnectAttempts,
|
||||
});
|
||||
|
||||
if (this.reconnectAttempts >= this.maxReconnectAttempts) {
|
||||
logger.error('socketService', 'Max reconnection attempts reached');
|
||||
this.socket.close();
|
||||
}
|
||||
});
|
||||
|
||||
// 监听重连尝试
|
||||
this.socket.io.on('reconnect_attempt', (attemptNumber) => {
|
||||
logger.info('socketService', 'Reconnection attempt', { attemptNumber });
|
||||
});
|
||||
|
||||
// 监听重连成功
|
||||
this.socket.io.on('reconnect', (attemptNumber) => {
|
||||
this.reconnectAttempts = 0;
|
||||
logger.info('socketService', 'Reconnected successfully', { attemptNumber });
|
||||
});
|
||||
|
||||
// 监听重连失败
|
||||
this.socket.io.on('reconnect_failed', () => {
|
||||
logger.error('socketService', 'Reconnection failed after max attempts');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 断开连接
|
||||
*/
|
||||
disconnect() {
|
||||
if (!this.socket) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info('socketService', 'Disconnecting from Socket.IO server...');
|
||||
this.socket.disconnect();
|
||||
this.socket = null;
|
||||
this.connected = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听事件
|
||||
* @param {string} event - 事件名称
|
||||
* @param {Function} callback - 回调函数
|
||||
*/
|
||||
on(event, callback) {
|
||||
if (!this.socket) {
|
||||
logger.warn('socketService', 'Cannot listen to event: socket not initialized', { event });
|
||||
return;
|
||||
}
|
||||
|
||||
this.socket.on(event, callback);
|
||||
logger.info('socketService', `Event listener added: ${event}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除事件监听
|
||||
* @param {string} event - 事件名称
|
||||
* @param {Function} callback - 回调函数(可选)
|
||||
*/
|
||||
off(event, callback) {
|
||||
if (!this.socket) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
this.socket.off(event, callback);
|
||||
} else {
|
||||
this.socket.off(event);
|
||||
}
|
||||
|
||||
logger.info('socketService', `Event listener removed: ${event}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息到服务器
|
||||
* @param {string} event - 事件名称
|
||||
* @param {*} data - 发送的数据
|
||||
* @param {Function} callback - 确认回调(可选)
|
||||
*/
|
||||
emit(event, data, callback) {
|
||||
if (!this.socket || !this.connected) {
|
||||
logger.warn('socketService', 'Cannot emit: socket not connected', { event, data });
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
this.socket.emit(event, data, callback);
|
||||
} else {
|
||||
this.socket.emit(event, data);
|
||||
}
|
||||
|
||||
logger.info('socketService', `Event emitted: ${event}`, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加入房间
|
||||
* @param {string} room - 房间名称
|
||||
*/
|
||||
joinRoom(room) {
|
||||
this.emit('join_room', { room });
|
||||
}
|
||||
|
||||
/**
|
||||
* 离开房间
|
||||
* @param {string} room - 房间名称
|
||||
*/
|
||||
leaveRoom(room) {
|
||||
this.emit('leave_room', { room });
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取连接状态
|
||||
*/
|
||||
isConnected() {
|
||||
return this.connected;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Socket ID
|
||||
*/
|
||||
getSocketId() {
|
||||
return this.socket?.id || null;
|
||||
}
|
||||
}
|
||||
|
||||
// 导出单例
|
||||
export const socketService = new SocketService();
|
||||
|
||||
export default socketService;
|
||||
Reference in New Issue
Block a user