Files
chat/websocket_handler.py
T
theliu 5ff0c575a1 v1.0
2026-04-26 20:05:33 +08:00

167 lines
6.1 KiB
Python

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'])