如何与服务器端事件创建可靠的flask-SQLAlchemy交互?

时间:2020-10-11 15:11:42

标签: flask-sqlalchemy

我有一个烧瓶应用程序,可以正常运行,现在我正在尝试向页面添加消息通知部分。我遇到的困难是,我要依靠的数据库更改似乎没有及时更新。

html代码是基本的:

    <ul id="out" cols="85" rows="14">

    </ul><br><br>

    <script type="text/javascript">
    var ul = document.getElementById("out");
    var eventSource = new EventSource("/stream_game_channel");
    eventSource.onmessage = function(e) {
        ul.innerHTML += e.data + '<br>';
    }
    </script>

这是第二个用户正在执行的味精写入代码。我知道代码块正在运行,因为正确调用了redis触发器:

        msg_join = Messages(game_id=game_id[0],
                            type="gameStart",
                            msg_from=current_user.username,
                            msg_to="Everyone",
                            message=f'{current_user.username} has requested to join.')

        db.session.add(msg_join)
        db.session.commit()

        channel = str(game_id[0]).zfill(5) + 'startGame'
        session['channel'] = channel

        date_time = datetime.utcnow().strftime("%Y/%m/%d %H:%M:%S")
        redisChannel.set(channel, date_time)

这是烧瓶流代码,它是由新的redis时间正确触发的,但是当我提取消息列表时,第二个用户添加的新消息尚无法访问:

@games.route('/stream_game_channel')
def stream_game_channel():
    @stream_with_context
    def eventStream():
        channel = session.get('channel')
        game_id = int(left(channel, 5))
        cnt = 0
        while cnt < 1000:
            print(f'cnt = 0 process running from: {current_user.username}')
            time.sleep(1)
            ntime = redisChannel.get(channel)
            if cnt == 0:
                msgs = db.session.query(Messages).filter(Messages.game_id == game_id)
                msg_list = [i.message for i in msgs]
                cnt += 1
                ltime = ntime
                lmsg_list = msg_list
                for i in msg_list:
                    yield "data: {}\n\n".format(i)
            elif ntime != ltime:
                print(f'cnt > 0 process running from: {current_user.username}')
                time.sleep(3)
                msgs = db.session.query(Messages).filter(Messages.game_id == game_id)
                msg_list = [i.message for i in msgs]
                new_messages = # need to write this code still
                ltime = ntime
                cnt += 1
                yield "data: {}\n\n".format(msg_list[len(msg_list)-len(lmsg_list)])
    return Response(eventStream(), mimetype="text/event-stream")

我遇到的语法错误是msg_list的长度完全相同(即,当我期望时,推送的新消息不会被写入)。奇怪的是,第二个用户的会话似乎正在访问此信息,因为它的流正确反映了添加的情况。

我正在使用Amazon RDS MySQL数据库。

1 个答案:

答案 0 :(得分:0)

解决方案是在没有db.session.query(Messages).filter(...)之前使用db.session.commit()。这样可以立即从其他用户会话中读取内容,并且我的代码开始对消息列表长度的更改做出正确的反应。

相关问题