私はPython asyncioを勉強するためのスニペットを書こうとしています。基本的な考え方は次のとおりです。asyncioを使用すると、一部のデータをタイムリーに更新し、aiohttp経由で表示できますか?
は、ユーザーへのデータの復帰がここに速やか
を変更します
ユーザーにいくつかのデータを提示する「単純な」ウェブサーバ(aiohttp)を使用していますコード:
import asyncio
import random
from aiohttp import web
userfeed = [] # the data suppose to return to the user via web browsers
async def data_updater(): #to simulate data change promptly
while True:
await asyncio.sleep(3)
userfeed = [x for x in range(random.randint(1, 20))]
print('user date updated: ', userfeed)
async def web_handle(request):
text = str(userfeed)
#print('in handler:', text) # why text is empty?
return web.Response(text=text)
async def init(loop):
app = web.Application(loop=loop)
app.router.add_route('GET', '/', web_handle)
srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8000)
print('Server started @ http://127.0.0.1:8000...')
return srv
loop = asyncio.get_event_loop()
asyncio.ensure_future(data_updater())
asyncio.ensure_future(init(loop))
loop.run_forever()
問題は、コードが実行されている(のpython 3.5)が、が更新されていない理由は
- :-(
web_handler()
でもブラウザで常に空であると? - この機能に関して、更新メカニズムが複雑になる可能性があるため、後でasync IO waitが含まれる可能性があります。を
data_updater()
に使用する代わりに、より正確なタイマーを取得する方が良いでしょうか?
あなたのページを閲覧しているユーザーに通知を送信したいですか(そのユーザーの操作なし)?もしそうなら、あなたは* websocket *技術を見てください。これはかなり簡単な方法で 'aiohttp'に実装されています([examples](https://github.com/KeepSafe/aiohttp/blob/master/)です) examples/web_ws.py)をソースコードに追加します)。それ以外の場合は、関数間で 'userfeed'変数を渡すための' 'app'オブジェクト(http://aiohttp.readthedocs.io/en/stable/faq.html#id3)(' dict'インタフェースを提供する)を使用してくださいそれをグローバルにすることは避けてください。 – mgc
@ mgc、返信ありがとうございます。私はデータが自動的にユーザーのブラウザでフラッシュされるのを望んでいません。ちょうどクライアントのプルモデルで十分です.Wgetのようなブラウザやツールを使ってURLを開くたびに最新のデータが表示されます。ここで混乱するのは、なぜグローバル変数が更新されていないのですか?(web_handler()内のprintは常に[]ですが、 'data _updater()'は変更されたものを表示します)?非同期defは通常のdefとは異なりますが、何らかの形でコンテキストをキャッシュしますか? – user340307
この文脈でのグローバル変数の使用は、[documentation](http://aiohttp.readthedocs.io/en/stable/web.html#data-sharing-aka-no-html)で明示的に推奨されていないので、シングルトン - してください)。しかし、本当にグローバルな 'userfeed'を使って動作させる必要があれば、' data_updated'と 'web_handle'の両方の関数に' global userfeed'を追加すれば動作します(このように 'userfeed'は変数を参照しますあなたの例では、各関数はローカルな 'userfeed'を持っていました)。 – mgc