FastAPI - Websocket


WebSocket是客户端和服务器之间的持久连接,用于在两者之间提供双向、全双工通信通信通过单个 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”文件夹中。

主要.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})

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

套接字.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”文件夹中。

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”的 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 服务器并访问 http://localhost:8000/ 以呈现聊天窗口,如下所示 -

FastAPI Websocket

输入特定文本并按发送按钮。输入消息将通过 websocket 在浏览器上重定向。

FastAPI Websocket