Flask -socketio AttributeError: объект 'Request' не имеет атрибута 'sid' - PullRequest
0 голосов
/ 19 июня 2020

Я получаю эту ошибку: AttributeError: 'Request' object has no attribute 'sid' при использовании socketio в flask. Вот результат:

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 голосов
/ 20 июня 2020

Ссылаясь на ответ здесь о AttributeError: объект 'Request' не имеет атрибута 'sid'

Я считаю, что ваша ошибка может быть вызвана этой строкой

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

Цитата из источника, приведенного выше.

Функция emit () по умолчанию отправляет отправителю исходное событие. Это значение по умолчанию имеет смысл только тогда, когда вы вызываете функцию из обработчика событий. Вы вызываете его из маршрута, который не имеет контекста Socket.IO (в частности, request.sid).

Вы знаете, каким пользователям вы хотите отправить событие из этого маршрута ? Если вы хотите отправлять сообщения всем подключенным клиентам, добавьте broadcast = True. Если вы знаете sid пользователя, к которому хотите обратиться, добавьте room = sid. Вам также необходимо указать пространство имен, поэтому добавьте namespace = '/' или используйте правильное имя пространства имен.

Ошибка может быть такой же простой, как: пользователь был отключен перед маршрутизацией /redirected.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...