在烧瓶中使用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"]
答案 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 ='/'或使用正确的名称空间名称。
错误也可能很简单,例如用户在路由/重定向之前已断开连接。