【问题标题】:How can I serve stored data from web-sockets using Flask?如何使用 Flask 从网络套接字提供存储的数据?
【发布时间】:2020-06-16 14:07:12
【问题描述】:

TLDR;我正在尝试运行一个从 web 套接字 URI 获取数据的客户端,然后使用 Flask 来提供从套接字获取的数据。

我的预期工作流程如下:从网络套接字读取数据(异步)-> 将数据写入 Python 字典(连续)-> 使用 Flask 上的 GET 请求从 Python 字典读取数据(连续)

我面临的问题是我使用 Python 字典进行存储,但是当我从 Flask 读取该字典时,它没有显示更新的值。

我为我的问题创建了一个带有代码的插图

客户:

import asyncio
import websockets
import json

SOME_URI = "ws://localhost:8080/foo"
connections = set()
connections.add(SOME_URI)


class Storage:
    storage = dict() # local storage dict for simplicity

    @staticmethod
    def store(data): # here I store the value
        a, b, c = data
        Storage.storage[a] = c

    @staticmethod
    def show(): # Here I just show the value to be used in the GET
        return Storage.storage


async def consumer_handler(uri):
    async with websockets.connect(uri) as websocket:
        async for message in websocket:
            await consumer(message)


async def consumer(message):
    line = json.loads(message)
    Storage.store(line) # adds message to dict


async def main():
    await asyncio.wait([consumer_handler(uri) for uri in connections])


if __name__ == "__main__":
    asyncio.run(main())

应用:

from flask import Flask
from client import Storage

app = Flask(__name__)
app.debug = True


@app.route('/bar', methods=['GET'])
def get_instruments():
    res = Storage.show() # I expected here to see updated value for the dict as it fills up from websockets
    return res, 200


if __name__ == "__main__":
    app.run()

每当我尝试向 Flask 页面发出 GET 请求时,我都会得到一个 Empty dict 的值(不反映我从 Web 套接字添加的更改)。我希望每次 GET 请求都能获得字典的更新值。

【问题讨论】:

    标签: python python-3.x flask websocket python-asyncio


    【解决方案1】:

    问题在于您有两个独立 Python 进程在这里涉及——一个是用于摄取数据的异步脚本,另一个是运行烧瓶。由于这些是单独的进程,您在第一个进程上执行的dict 更新对第二个进程不可见。

    您需要某种形式的 IPC(进程间通信)机制来实现数据可移植性和/或持久性。一个明显且更容易尝试的选择是使用命名的 FIFO 或纯文件。根据您要处理的复杂程度,使用 Redis(或类似的)也是另一种选择。

    【讨论】:

    • 我已经开始使用 Redis 实现这个,感谢您指出这一点。您所说的“命名 FIFO”到底是什么意思,以及在 Python 中使用文件或 FIFO 的实现是什么? (不是真的要代码,只是高级解释)
    • @Rey619 请参阅en.wikipedia.org/wiki/Named_pipe 了解命名的 FIFO。文件的实现只是我们通过open 操作的常规文件。 FWIW,您可以使用 os.mkfifo 创建一个命名的 FIFO(在下面调用 mkfifo(3))。
    猜你喜欢
    • 2013-08-06
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多