FastAPI Websockets
WebSocket 是客户端和服务器之间的持久性连接,在两者之间提供双向、 全双工的 通信。通信是通过单个TCP/IP套接字连接在HTTP上进行的。它可以被看作是HTTP的升级,而不是一个协议本身。
HTTP的局限性之一是,它是一个严格的半双工或单向的协议。另一方面,通过WebSockets,我们可以发送基于消息的数据,类似于UDP,但具有TCP的可靠性。WebSocket使用HTTP作为初始传输机制,但在收到HTTP响应后保持TCP连接的活力。同样的连接对象,它可以用于客户端和服务器之间的双向通信。因此,可以使用WebSocket API构建实时应用程序。
FastAPI通过FastAPI模块中的WebSocket类支持WebSockets。下面的例子演示了WebSocket在FastAPI应用程序中的功能。
首先,我们有一个 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提供服务,首先要加载 “静态 “文件夹。JavaScript文件ws.js被放置在 “静态 “文件夹中。
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 “的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)。Run the Uvicorn server and visit http://localhost:8000/ to render the chat window as below −
输入某个文本并按下发送按钮。输入的信息将通过websocket重定向到浏览器上。