[英]Sanic Websocket Asynchronous Management
我有一個Sanic應用程序。 它為html頁面提供了一些可變的局部狀態。 根據狀態,用戶會通過WebSocket收到不同的響應:
import time
import random
import simplejson as json
from sanic import Sanic, response
from sanic.websocket import WebSocketProtocol
flowers = {
'purple': 'aster',
'red' : 'rose',
'white' : 'daisy'
}
def random_quality():
return random.choice(['Nice', 'Beautiful', 'Fragrant', 'Vivid'])
app = Sanic()
@app.route('/')
def handle_request(_req):
return response.html("""
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
</head>
<body>
<div id="current">Select color</div><br>
<input type="radio" name="flower" onchange="notifyColor(this.value)" value="purple" />Purple<br>
<input type="radio" name="flower" onchange="notifyColor(this.value)" value="red" />Red<br>
<input type="radio" name="flower" onchange="notifyColor(this.value)" value="white" />White<br>
<script type="text/javascript">
var ws;
var notifyColor = (color) => {
ws.send(color);
}
window.onload = () => {
ws = new WebSocket('ws://localhost:3000/api/');
var quality;
var flower;
ws.onmessage = (e) =>{
let res = JSON.parse(e.data);
if (res.hasOwnProperty("flower")) {
flower = res.flower;
}
quality = res.quality
document.getElementById("current").innerText = quality + ' ' + flower;
}
}
</script>
</body>
</html>
""")
@app.websocket('/api/')
async def cache_api(_req, ws):
while True:
color = await ws.recv()
flower = flowers[color]
quality = random_quality()
res = json.dumps({'flower': flower, 'quality': quality})
await ws.send(res)
app.run(debug=True, port=3000, protocol=WebSocketProtocol)
但是,我想周期性地將部分數據周期性地推送給用戶,而用戶仍然可以更改本地狀態並通知服務器:
# pseudocode-ish
@app.websocket('/api/')
async def cache_api(_req, ws):
while True:
color = await ws.recv()
flower = flowers[color]
res1 = json.dumps({'flower': flower})
await ws.send(res1)
#---------------------------------------------#
# AND ALSO SIMULTANEOUSLY ("ASYNCHRONOUSLY"?) #
#---------------------------------------------#
while True:
quality = random_quality()
res2 = json.dumps({'quality': quality})
await ws.send(res2)
time.sleep(2)
如何實現呢? 我必須使用中間件功能嗎? 如果是,一個人怎么寫? 在我的情況下,無法使用多個websocket或不同的api端點。
一個通用的簡化方法就像
@app.websocket('/api/')
async def cache_api(_req, ws):
async def _operation_one():
while True:
color = await ws.recv()
flower = flowers[color]
res1 = json.dumps({'flower': flower})
await ws.send(res1)
async def _operation_two():
while True:
quality = random_quality()
res2 = json.dumps({'quality': quality})
await ws.send(res2)
await asyncio.sleep(2)
await asyncio.gather([
_operation_one(),
_operation_two(),
])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.