首页 > 解决方案 > Flask-socketio AttributeError:“请求”对象没有属性“sid”

问题描述

我收到此错误:AttributeError: 'Request' object has no attribute 'sid'在烧瓶中使用 socketio 时。这是输出:

File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/user/tennisprogram/application.py", line 34, in create_game_post
    join_room(str(gameid))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/flask_socketio/__init__.py", line 865, in join_room
    sid = sid or flask.request.sid
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/werkzeug/local.py", line 347, in __getattr__
    return getattr(self._get_current_object(), name)
AttributeError: 'Request' object has no attribute 'sid'

这是我正在使用的代码。如果您需要后端以外的东西,请告诉我,我很乐意提供它:)。输入:

from flask import Flask, redirect, request, render_template, session, url_for
from flask_socketio import SocketIO, emit, join_room, leave_room, close_room

app = Flask(__name__)
socket = SocketIO(app)
app.config["SECRET_KEY"] = 'secret-key'

games = [None, None, None, None, None, None, None, None, None, None]

class Game:
    def __init__(self, player1, player2, id):
        self.id = id
        self.infodictionary = {"player1_name":player1, "player1_score":["0", "0", "0"], "player2_name":player2, "player2_score":["0", "0", "0"]}

@app.route("/")
def index():
    return render_template("index.html")

@app.route("/create_game")
def create_game():
    return render_template("create_game.html")

@app.route("/create_game/post", methods=["POST"])
def create_game_post():
    if "host" in session:
        return "Already hosting a game" #Handle later
    for gameid, game in enumerate(games):
        if game == None:
            game = Game(request.form.get("player1"), request.form.get("player2"), gameid)
            games[gameid] = game
            session["host"] = gameid
            return redirect(url_for('game', id=game.id))
    return "No game slot available" #Handle later

@app.route("/game/<id>")
def game(id):
    join_room(str(id))
    if int(id) == session["host"]:
        return render_template("score.html", host=True, game=games[int(id)])
    else:
        return render_template("score.html", host=False, game=games[int(id)])

@socket.on("host-update")
def update(data):
    p1 = data["player1_score"]
    p2 = data["player2_score"]
    games[int(data["id"])].infodictionary["player1_score"] = p1
    games[int(data["id"])].infodictionary["player2_score"] = p2
    emit("update", {"player1_score":p1, "player2_score":p2}, room=data["id"])

#Handling join game
'''
@socket.on("joingame")
def join(data):
    r = data["room"]
    join_room(r)
'''

@app.route("/join_game")
def join_game():
    return render_template("join_game.html")
    #join_game.html will redirect user to join_game_post. The socket will activate in join_game.html

@app.route("/join_game/join", methods=["POST"])
def join_game_post():
    id = request.form.get("id")
    return redirect(url_for("game", id=id))

@app.route("/del")
def delete_host():
    games[int(session["host"])] = None
    del session["host"]

标签: pythonflasksocket.io

解决方案


参考这里关于AttributeError 的答案:'Request' object has no attribute 'sid'

我相信你的错误可能是由这条线引起的

*emit("update", {"player1_score":p1, "player2_score":p2}, room=data["id"])

从上面的来源引用原因

emit() 函数默认发送给原始事件的发送者。此默认值仅在您从事件处理程序调用函数时才有意义。您正在从没有 Socket.IO 上下文(特别是 request.sid)的路由中调用它。

你知道你想从这条路线向哪个用户发出事件吗?如果您想向所有连接的客户端发送,请添加广播 = True。如果您知道要寻址的用户的 sid,则添加 room=sid。您还需要指定命名空间,因此添加 namespace='/' 或使用正确的命名空间名称。

错误也可能很简单,用户在被路由/重定向之前已断开连接。


推荐阅读