我正在使用Flask开发基于房间的应用程序。通过SQL-Alchemy在Postgresql数据库中跟踪每个房间及其成员。用户是匿名的,因此是临时的:用户仅在房间里一直保留在数据库中。
在“正常”使用情况下,所有操作均按预期进行:通过url加入会议室或刷新页面一次或两次。但是,如果用户连续多次刷新页面(例如,向浏览器的刷新按钮发送垃圾邮件),则会出现问题。连接事件被正确触发,但是断开事件从未运行。结果,根据数据库仍然认为用户在房间里。这种不准确的数据会导致很多其他问题。为什么断开事件不触发,我能做些什么来解决此问题?
谢谢, 迈克尔
代码在连接上运行:
@socketio.on('connect')
def add_to_room_and_sync_client():
print('------------------------ user has connected!!!')
print(request.sid)
room = session['room_hash']
# Add user to room
join_room(room)
RoomManager.join_room(room)
# Broadcast connection to all users in room
username = session['username']
emit('statusUpdate', {'username':session['username'], 'status':'joining'}, room=room)
# Get newly connected client up-to-date
emit('sync', cache_manager.get_data_structures(session['room_hash']))
离开代码:
@socketio.on('disconnect')
def disconnect_user():
print('user has disconnected!-------------------------')
url = request.headers['Referer']
room = url.split('/')[-1]
leave_room(room)
RoomManager.leave_room(room)
username = session['username']
emit('statusUpdate', {'username':session['username'], 'status':'leaving'}, room=room)
RoomManager的相关代码:
class RoomManager():
def join_room(hash_):
room = Room.query.filter_by(id=hash_).first()
# Add user to database if they do not exist. Otherwise, select them from database
user = User.query.filter_by(id=session['user_id']).first()
if user == None:
user = User(session['user_id'], session['username'])
# Add user to room list. Also, if there is currently no owner,
# give this user ownership of the room
room.users.append(user)
if room.owner == None:
room.owner = user
db.session.commit()
def leave_room(hash_):
room = Room.query.filter_by(id=hash_).first()
user = User.query.filter_by(id=session['user_id']).first()
# Remove user from room
room.users.remove(user)
# If this user was the owner, make someone else the owner
if room.owner == user:
print('he owns it')
if len(room.users) == 0:
room.owner = None
else:
room.owner = room.users[0]
# If this is the only room the user is in, remove them from the database
if len(user.rooms) == 0:
db.session.delete(user)
db.session.commit()