python - 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"]
解决方案
参考这里关于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='/' 或使用正确的命名空间名称。
错误也可能很简单,用户在被路由/重定向之前已断开连接。
推荐阅读
- azure - Azure 点到站点 VPN - 无法连接到对等 VNet 中的虚拟机
- wordpress - Woocommerce:在产品类别名称下列出某些产品属性值
- javascript - JS onclick 事件在 firefox 中不起作用,但在基于 codeigniter 和 bootstrap 的 chrome 中起作用
- mongodb - SpringBoot multipleRepositories <> 多个数据库集群
- hibernate - Hibernate:防止不同线程插入重复行
- c# - Parallel.for 循环执行
- javascript - Chart.js 重绘正在渲染的图表
- arrays - 保证分区后恒定差异时快速排序的最坏情况运行时
- reactjs - 如何使用 react-router 更改 url
- drupal - Drupal 8:使用 hook_form_alter 将 Ajax 附加到字段引用