Flask-socketio AttributeError:“请求”对象没有属性“ sid”

时间:2020-06-19 17:10:16

标签: python flask socket.io

在烧瓶中使用socketio时出现此错误:AttributeError: 'Request' object has no attribute 'sid'。输出为:

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"]

1 个答案:

答案 0 :(得分:0)

请参考此处有关AttributeError: 'Request' object has no attribute 'sid'的答案

我相信您的错误可能是由此行引起的

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

从上面引用原因

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

您知道您要向此用户发送事件吗? 路线?如果要发送给所有连接的客户端,请添加 广播=真。如果您知道要寻址的用户的SID, 然后添加room = sid。您还需要指定名称空间,因此添加 namespace ='/'或使用正确的名称空间名称。

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