flask + websocket 简单聊天功能

一. flask + websocket 简单聊天功能

1. 目录及依赖

# 安装所需依赖
pip install Flask Flask-SocketIO
|-- project
    |-- templates
        |--user.html
    |-- app.py

2. 代码

2.1 app.py 文件

user1, usre2, user3 分别对应不同的用户。每个用户都有不同的 id, 作为唯一标识(代码可见)。

from flask import Flask, render_template, request
from flask_socketio import SocketIO, send, emit, join_room, leave_room

app = Flask(__name__)
app.config["SECRET_KEY"] = "secret!"
socketio = SocketIO(app)

# 用户ID和Socket连接的映射
clients = {}


@app.route("/user1")
def user1():
    return render_template("user.html", user_id="user1")


@app.route("/user2")
def user2():
    return render_template("user.html", user_id="user2")


@app.route("/user3")
def user3():
    return render_template("user.html", user_id="user3")

# 监控连接操作
@socketio.on("connect")
def handle_connect():
    user_id = request.args.get("user_id")
    clients[user_id] = request.sid
    print(f"{user_id} connected with session ID {request.sid}")

# 监控断开操作
@socketio.on("disconnect")
def handle_disconnect():
    user_id = None
    for uid, sid in clients.items():
        if sid == request.sid:
            user_id = uid
            break
    if user_id:
        del clients[user_id]
        print(f"{user_id} disconnected")

# private_message 定义接受标识  emit 发送信息
@socketio.on("private_message")
def handle_private_message(data):
    recipient_id = data["recipient_id"]
    message = data["message"]
    if recipient_id in clients:
        recipient_sid = clients[recipient_id]
        emit("message", message, to=recipient_sid)
        print(f"Message from {request.sid} to {recipient_sid}: {message}")
    else:
        emit("message", "User not found", to=request.sid)


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

2.2 user.html 文件

运行三个浏览器窗口即可,路由为 http://127.0.0.1:5000/user1,http://127.0.0.1:5000/user2, http://127.0.0.1:5000/user3

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Chat</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.0/socket.io.min.js"></script>
  </head>
  <body>
    <h1>Chat User</h1>
    <p id="userId" style="display: none">{{ user_id }}</p>
    <ul id="messages"></ul>
    <input id="recipientId" placeholder="Recipient ID" autocomplete="off" />
    <input id="myMessage" placeholder="Your message" autocomplete="off" />
    <button onclick="sendMessage()">Send</button>

    <script>
      var userId = document.getElementById("userId").textContent;
      var socket = io({
        query: {
          user_id: userId,
        },
      });
      # message 定义接受标识
      socket.on("message", function (msg) {
        var item = document.createElement("li");
        item.textContent = msg;
        document.getElementById("messages").appendChild(item);
        window.scrollTo(0, document.body.scrollHeight);
      });
      # emit 发送信息
      function sendMessage() {
        var recipientId = document.getElementById("recipientId").value;
        var message = document.getElementById("myMessage").value;
        socket.emit("private_message", {
          recipient_id: recipientId,
          message: message,
        });
        document.getElementById("myMessage").value = "";
      }
    </script>
  </body>
</html>
posted @ 2024-07-02 11:29  codegjj  阅读(47)  评论(0)    收藏  举报