Fastapi整合SSE服務後端主動推送訊息到前端

神精兵發表於2024-06-21

sse技術簡介

SSE(Server-Sent Events)是一種允許伺服器向客戶端瀏覽器推送資訊的技術。它是 HTML5 的一部分,專門用於建立一個單向的從伺服器到客戶端的通訊連線。SSE的使用場景非常廣泛,包括實時訊息推送、實時通知更新等。
嚴格地說,HTTP 無法做到伺服器主動推送資訊。但是,有一種變通方法,就是伺服器向客戶端宣告,接下來要傳送的是流資訊(streaming)。

也就是說,傳送的不是一次性的資料包,而是一個資料流,會連續不斷地傳送過來。這時,客戶端不會關閉連線,會一直等著伺服器發過來的新的資料流,影片播放就是這樣的例子。本質上,這種通訊就是以流資訊的方式,完成一次用時很長的下載。

SSE 就是利用這種機制,使用流資訊向瀏覽器推送資訊。

FastAPI整合SSE功能

配置環境
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple sse-starlette fastapi[all]

程式碼實現:

try:
    from sse_starlette.sse import EventSourceResponse
    import asyncio
except:
    import os
    os.system('pip install -i https://pypi.tuna.tsinghua.edu.cn/simple sse-starlette')
    from sse_starlette.sse import EventSourceResponse
    import asyncio


@router.get("/sse")
async def root(request: Request):
    async def event_generator(request: Request):
        while True:
            if await request.is_disconnected():
                print("連線已中斷")
                break
            sse_test_data = gl.gl_Redis.hgetall('sse:test:data')
            sse_test_data['warn_site'] = sse_test_data['warn_site'].split(',') if sse_test_data.get('warn_site') else []
            yield {
                "event": "message",
                # "retry": 15000,
                "data": demjson.encode(sse_test_data)
            }

            await asyncio.sleep(10)
    g = event_generator(request)
    return EventSourceResponse(g)

SEE客戶端測試指令碼

import aiohttp
import asyncio

async def test():
    headers = {'Content-Type': 'text/event-stream'}
    sseresp = aiohttp.request("GET", r"http://127.0.0.1:9000/api/sse", headers=headers)
    async with sseresp as r:
        async for chunk in r.content.iter_any():
            print(chunk.decode())

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(test())

【特別提示】在現在大多數webviews框架打包APP時,sse服務無效!!!

本文由部落格一文多發平臺 OpenWrite 釋出!

相關文章