一个常用Python应用框架:FastAPI+Uvicorn 支持 WebSocket 的应用程序

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://协议。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值