FastAPI - WebSockets



WebSocket 是客户端和服务器之间的一个持久连接,用于在两者之间提供双向、全双工通信。通信通过单个 TCP/IP 套接字连接在 HTTP 上进行。它可以被视为 HTTP 的升级,而不是协议本身。

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

FastAPI 通过 FastAPI 模块中的 WebSocket 类支持 WebSockets。以下示例演示了 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://127.0.0.1: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://127.0.0.1:8000/ws”处侦听的 websocket。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 服务器并访问 https://127.0.0.1:8000/ 以呈现如下所示的聊天窗口 -

FastAPI Websockets

键入某些文本并按发送按钮。输入的消息将通过 websocket 重定向到浏览器。

FastAPI Websockets
广告