簡體   English   中英

Sanic Websocket異步管理

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM