Fastapi 简明教程

FastAPI - Websockets

WebSocket 是一个客户端和服务器之间的持久连接,用于在两者之间提供双向的 full-duplex 通信。通信通过单个 TCP/IP 套接字连接通过 HTTP 发生。它可以看作是 HTTP 的升级,而不是协议本身。

HTTP 的局限性之一是它是一个严格的半双工或单向协议。另一方面,借助 WebSocket,我们可以发送基于消息的数据(类似于 UDP),但借助 TCP 的可靠性。WebSocket 使用 HTTP 作为初始传输机制,但在收到 HTTP 响应后保持 TCP 连接的活动状态。可以将同一连接对象用于客户端和服务器之间的双向通信。因此,可以使用 WebSocket API 构建实时应用。

FastAPI 通过 FastAPI 模块中的 WebSocket 类支持 WebSocket。以下示例演示了在 FastAPI 应用程序中 WebSocket 的功能。

首先,我们有一个 index() 函数来呈现一个模板 (socket.html)。它绑定到 “/” 路由。HTML 文件 socket.html 放置在 “templates” 文件夹中。

main.py

from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
templates = Jinja2Templates(directory="templates")
from fastapi.staticfiles import StaticFiles
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
   return templates.TemplateResponse("socket.html", {"request": request})

模板文件呈现一个文本框和一个按钮。

socket.html

<!DOCTYPE html>
<html>
   <head>
      <title>Chat</title>
      <script src="{{ url_for('static', path='ws.js') }}"></script>
   </head>
   <body>
      <h1>WebSocket Chat</h1>
      <form action="" onsubmit="sendMessage(event)">
      <input type="text" id="messageText" autocomplete="off"/>
      <button>Send</button>
      </form>
      <ul id='messages'>
      </ul>
   </body>
</html>

在 socket.html 内部,有一个对 JavaScript 函数的调用,该函数将在表单提交时执行。因此,为了提供 JavaScript 服务,“static” 文件夹首先被挂载。JavaScript 文件 ws.js 放置在 “static” 文件夹中。

ws.js

var ws = new WebSocket("ws://localhost:8000/ws");
ws.onmessage = function(event) {
   var messages = document.getElementById('messages')
   var message = document.createElement('li')
   var content = document.createTextNode(event.data)
   message.appendChild(content)
   messages.appendChild(message)
};
function sendMessage(event) {
   var input = document.getElementById("messageText")
   ws.send(input.value)
   input.value = ''
   event.preventDefault()
}

加载 JavaScript 代码时,它创建一个套接字,在 “ws://localhost:8000/ws” 处进行监听。 sendMessage() 函数将输入消息定向到 WebSocket URL。

此路由调用应用程序代码中的 websocket_endpoint() 函数。接受传入的连接请求,并在客户端浏览器上显示传入的消息。将以下代码添加到 main.py 中。

from fastapi import WebSocket
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
   await websocket.accept()
   while True:
      data = await websocket.receive_text()
      await websocket.send_text(f"Message text was: {data}")

保存 FastAPI 代码文件 (main.py)、模板 (socket.html) 和 JavaScript 文件 (ws.js)。运行 Uvicorn 服务器并访问 [role="bare"] [role="bare"]http://localhost:8000/ 以呈现如下所示的聊天窗口 −

web1

键入某个文本并按下发送按钮。输入消息将通过 WebSocket 重定向到浏览器上。

web2