• Python
  • 基于Flask-SocketIO的用户一对一聊天Demo

支持一对一的私聊模式,而不是聊天室形式。

from flask import Flask, request, session
from flask_socketio import SocketIO, emit, join_room, leave_room

app = Flask(__name__)
app.config['SECRET_KEY'] = 'mysecretkey'
socketio = SocketIO(app)

# 用来存储私聊消息历史记录
messages = {}

# 用来存储用户会话和对应的私聊会话号
sessions = {}

@app.route('/history', methods=['GET'])
def history():
    """
    获取与指定用户的私聊历史记录
    """
    username = request.args.get('username')
    room = sessions.get((session.get('username'), username))
    if room and messages.get(room):
        return {'messages': messages[room]}
    return {'messages': []}

@socketio.on('join')
def join(data):
    """
    建立一对一私聊会话
    """
    username = data['username']
    peer = data['peer']
    room = (username, peer)
    join_room(room)
    # 存储会话和私聊会话号的对应关系
    sessions[(session['username'], peer)] = room
    # 如果之前有历史记录,发送给用户
    if messages.get(room):
        emit('history', {'messages': messages[room]}, room=request.sid)

@socketio.on('message')
def message(data):
    """
    接收和发送新消息
    """
    sender = session.get('username')
    recipient = data['recipient']
    content = data['content']
    room = sessions.get((sender, recipient))
    # 存储新消息
    if messages.get(room):
        messages[room].append((sender, content))
    else:
        messages[room] = [(sender, content)]
    # 发送给接收者
    emit('message', {'sender': sender, 'content': content}, room=room)

@socketio.on('leave')
def leave(data):
    """
    结束私聊会话
    """
    username = data['username']
    peer = data['peer']
    room = sessions.get((session.get('username'), peer))
    leave_room(room)
    sessions.pop((session.get('username'), peer))

if __name__ == '__main__':
    socketio.run(app, debug=True)

使用说明:

1.运行该Flask应用后,客户端需要先向/history?username=xx接口发送GET请求获取与指定用户的私聊历史记录。
2.客户端连接到Socket.IO服务器,并使用emit('join', {'username': xx, 'peer': xx})建立一对一私聊会话。
3.发送新消息使用emit('message', {'recipient': xx, 'content': xx})。
4.结束私聊会话使用emit('leave', {'username': xx, 'peer': xx})。
5.该demo使用session存储当前用户名,私聊会话号是一个包含发送者和接收者用户名的元组。
6.所有私聊消息按会话号存储在内存中的字典messages,实际可以存储在数据库中。消息记录包含发送者和内容。
7.接收消息时,服务器会向对应的私聊会话号广播消息,只有发送者和接收者能收到。

这个demo实现了一对一私聊的基本功能,你可以根据实际需求继续扩展,比如添加在线状态查看、未读消息计数等功能。