Web应用示例
使用 Uvicorn 可用于异步 Web 服务
# main.py
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def read_root():
return {"message": "Hello, World!"}
保存以上代码到 main.py
文件中。然后,在命令行中执行以下命令:
uvicorn main:app --reload
这将启动一个名为 main
的 ASGI 应用程序,使用 Uvicorn 服务器运行在本地主机的默认端口 8000 上,并监听根路径 /
的 GET 请求。在浏览器中访问 http://localhost:8000
,将看到 “Hello, World!” 的消息。
WebSocket应用示例
现在,Python网络应用的流行框架为:FastAPI+Uvicorn 支持 WebSocket 的应用。这里给出一上框架示例,你可以将它扩展成一个具体的应用。
FastAPI 本身不直接支持 WebSocket,但你可以通过集成 Starlette(因为 FastAPI 是基于 Starlette 的)来实现 WebSocket 功能。
首先,确保你已经安装了 FastAPI 和 Uvicorn:
pip install fastapi uvicorn
然后,你可以创建一个 Python 文件(比如 main.py
),并编写以下代码:
# main.py
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from starlette.websockets import WebSocket
import asyncio
app = FastAPI()
# WebSocket 路由处理函数
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
while True:
data = await websocket.receive_text()
if data == "close":
await websocket.close()
break
await websocket.send_text(f"Message text was: {data}")
except Exception as e:
print(f"WebSocket connection error: {e}")
# 将 WebSocket 路由添加到 FastAPI 应用
app.add_websocket_route("/ws", websocket_endpoint)
# 添加一个 HTTP 路由作为示例
@app.get("/")
async def read_root():
return JSONResponse(content={"Hello": "World"})
在这个框架例子中,websocket_endpoint 是一个异步函数,它处理 WebSocket 连接。当客户端连接到 /ws 路由时,这个函数会被调用。它首先接受连接,然后进入一个循环,等待接收来自客户端的文本消息。如果接收到 "close" 消息,则关闭 WebSocket 连接;否则,它会将接收到的消息回显给客户端。
请注意,app.add_websocket_route 方法用于将 WebSocket 路由添加到 FastAPI 应用中。这是 FastAPI 提供的一个便捷方法,用于与 Starlette 的 WebSocket 功能集成。
要运行这个应用程序,你需要在命令行中执行以下命令(而不是在 Python 脚本中):
uvicorn main:app --reload
这个命令会启动 Uvicorn 服务器,监听 FastAPI 应用(main.py
文件中的 app
对象)。--reload
选项会在代码更改时自动重启服务器,这在开发过程中非常有用。
现在,你可以使用浏览器的开发者工具或任何支持 WebSocket 的客户端库来测试 WebSocket 连接了。
测试
编写一个简单的 Python 脚本,使用 websockets
库来连接到 WebSocket 服务器并发送/接收消息。
首先,确保你已经安装了 websockets
库:
pip install websockets
然后,创建一个新的 Python 文件(比如 test_websocket.py
),并编写以下代码:
# test_websocket.py
import asyncio
import websockets
async def test_websocket():
uri = "ws://localhost:8000/ws"
async with websockets.connect(uri) as websocket:
# 发送消息到服务器
await websocket.send("Hello, WebSocket server!")
# 接收服务器的响应
response = await websocket.recv()
print(f"Received from server: {response}")
# 发送关闭消息(可选,因为服务器可能不依赖于特定消息来关闭连接)
await websocket.send("close")
# 等待服务器关闭连接(可选,因为 websocket.close() 通常在服务器端调用)
try:
# 这里我们尝试再接收一次以触发可能的异常,但通常不需要这样做
# 除非你想确保连接确实关闭了
await websocket.recv()
except websockets.ConnectionClosed:
print("WebSocket connection closed by server.")
# 运行测试函数
asyncio.run(test_websocket())
在上面的测试脚本中,发送 "close" 消息到服务器是可选的,因为 WebSocket 连接的关闭通常是由服务器或客户端在适当的时候触发的。在这个例子中,服务器端的 websocket_endpoint 函数会在接收到 "close" 消息时关闭连接,但即使不发送这个消息,客户端也可以在完成其任务后正常关闭连接。
此外,try-except 块用于捕获 websockets.ConnectionClosed 异常,这在尝试从已经关闭的连接中接收数据时可能会触发。然而,在这个特定的测试脚本中,由于我们在发送 "close" 消息后立即尝试接收(这通常不是一个好的做法,因为服务器可能还没有时间关闭连接),这个异常可能不会被触发。为了简化测试,你可以省略这个 try-except 块,或者将其保留以了解如何处理可能的连接关闭情况。
现在,你可以按照以下步骤运行测试:
确保你的 FastAPI + Uvicorn WebSocket 应用程序正在运行(通过执行 uvicorn main:app --reload 命令)。
在另一个命令行窗口中,运行测试脚本(通过执行 python test_websocket.py 命令)。
你应该会看到测试脚本输出从服务器接收到的消息,类似于:
Received from server: Message text was: Hello, WebSocket server!
浏览器中测试
也可在浏览器中测试,基本步骤:
首先,确保你的FastAPI + Uvicorn WebSocket服务器正在运行(uvicorn main:app --reload
)。
打开浏览器(如Chrome),然后按下F12或右键点击页面元素选择“检查”来打开开发者工具。
在Console面板中,你可以使用JavaScript来创建一个WebSocket连接,并发送/接收消息。例如:
// 创建一个WebSocket连接
const ws = new WebSocket('ws://localhost:8000/ws');
// 连接打开时触发的回调函数
ws.onopen = function(event) {
console.log('WebSocket Connected');
// 发送消息到服务器
ws.send('Hello, WebSocket server!');
};
// 接收到服务器消息时触发的回调函数
ws.onmessage = function(event) {
console.log('Received from server: ', event.data);
// 关闭连接(可选)
// ws.close();
};
// 连接关闭时触发的回调函数
ws.onclose = function(event) {
console.log('WebSocket Connection Closed');
};
// 捕获错误
ws.onerror = function(error) {
console.error('WebSocket Error: ', error);
};
将上述代码复制到Console面板中并执行,你应该能在Console中看到连接成功、接收消息以及连接关闭的日志(如果你调用了ws.close()的话)。
其它测试工具:
除了浏览器的开发者工具外,你还可以使用专门的WebSocket测试工具(如WebSocket Test Client插件、在线WebSocket测试服务等)来测试WebSocket连接。这些工具通常提供更直观的界面和更丰富的功能,如自动重连、发送不同类型的数据(文本、二进制)等。
注意事项:
- 确保WebSocket服务器的URL(包括协议、主机名和端口)与你在浏览器中尝试连接的URL完全匹配。
- WebSocket连接是持久的,与HTTP请求/响应模型不同。因此,你需要手动关闭连接(除非服务器或浏览器因某种原因关闭了它)。
- 如果服务器或浏览器实现了WebSocket的安全版本(即WSS,WebSocket Secure),则需要在URL中使用
wss://
协议。不过,在本地开发环境中,你通常会使用ws://
协议。