from flask_socketio import emit, join_room, leave_room from flask import request import time import json class WebSocketHandler: def __init__(self, socketio, user_manager): self.socketio = socketio self.user_manager = user_manager self.active_calls = {} # 正在进行的语音通话 self.setup_handlers() def setup_handlers(self): @self.socketio.on('connect') def handle_connect(auth=None): print(f'Client connected: {request.sid}') @self.socketio.on('disconnect') def handle_disconnect(): account = None # 找到断开连接的用户 for acc, user in self.user_manager.users.items(): if user.get('socket_id') == request.sid: account = acc break if account: self.user_manager.update_user_status(account, online=False) # 通知好友用户离线 emit('user_status', { 'account': account, 'online': False }, broadcast=True) @self.socketio.on('authenticate') def handle_authenticate(data): account = data.get('account') if account in self.user_manager.users: self.user_manager.update_user_status( account, online=True, socket_id=request.sid ) # 通知所有用户此用户上线 emit('user_status', { 'account': account, 'online': True }, broadcast=True) @self.socketio.on('private_message') def handle_private_message(data): to_account = data.get('to') message = data.get('message') from_account = data.get('from') # 获取接收者的socket_id recipient = self.user_manager.get_user(to_account) if recipient and recipient.get('socket_id'): emit('private_message', { 'from': from_account, 'message': message, 'timestamp': time.time() }, room=recipient['socket_id']) # 同时发送给自己(用于确认) emit('private_message_sent', { 'to': to_account, 'message': message, 'timestamp': time.time() }) @self.socketio.on('group_message') def handle_group_message(data): group_id = data.get('group_id') message = data.get('message') from_account = data.get('from') emit('group_message', { 'group_id': group_id, 'from': from_account, 'message': message, 'timestamp': time.time() }, room=group_id) @self.socketio.on('join_group') def handle_join_group(data): group_id = data.get('group_id') join_room(group_id) @self.socketio.on('leave_group') def handle_leave_group(data): group_id = data.get('group_id') leave_room(group_id) @self.socketio.on('start_call') def handle_start_call(data): """开始语音通话""" to_account = data.get('to') from_account = data.get('from') call_id = data.get('call_id') self.active_calls[call_id] = { 'participants': [from_account, to_account], 'start_time': time.time() } # 通知对方 recipient = self.user_manager.get_user(to_account) if recipient and recipient.get('socket_id'): emit('incoming_call', { 'from': from_account, 'call_id': call_id }, room=recipient['socket_id']) @self.socketio.on('answer_call') def handle_answer_call(data): """接听电话""" call_id = data.get('call_id') if call_id in self.active_calls: emit('call_accepted', { 'call_id': call_id }, room=request.sid) @self.socketio.on('end_call') def handle_end_call(data): """结束通话""" call_id = data.get('call_id') if call_id in self.active_calls: # 通知所有参与者 for participant in self.active_calls[call_id]['participants']: user = self.user_manager.get_user(participant) if user and user.get('socket_id'): emit('call_ended', { 'call_id': call_id }, room=user['socket_id']) del self.active_calls[call_id] @self.socketio.on('webrtc_signal') def handle_webrtc_signal(data): """WebRTC信令转发""" to_account = data.get('to') signal = data.get('signal') recipient = self.user_manager.get_user(to_account) if recipient and recipient.get('socket_id'): emit('webrtc_signal', signal, room=recipient['socket_id']) @self.socketio.on('file_uploaded') def handle_file_uploaded(data): """文件上传完成通知""" filename = data.get('filename') url = data.get('url') to_account = data.get('to') from_account = data.get('from') # 通知接收者 recipient = self.user_manager.get_user(to_account) if recipient and recipient.get('socket_id'): emit('file_received', { 'from': from_account, 'filename': filename, 'url': url, 'timestamp': time.time() }, room=recipient['socket_id'])