当然可以!以下是使用 FastAPI 框架创建一个包含 WebSocket 接口的服务,并使用 Postman 来测试该接口的详细步骤。
一、使用 FastAPI 创建 WebSocket 服务
1. 环境准备
确保你已经安装了 Python(推荐使用 Python 3.7 及以上版本)。然后,按照以下步骤安装所需的库:
# 创建并激活虚拟环境(可选,但推荐)
python -m venv venv
source venv/bin/activate # 对于 Windows 用户使用 `venv\Scripts\activate`
# 安装 FastAPI 和 Uvicorn
pip install fastapi uvicorn
2. 编写 FastAPI 应用
下面是一个简单的 FastAPI 应用示例,包含一个 WebSocket 接口。该接口实现了回显功能,即接收到的消息会原样返回给客户端。
# 文件名:main.py
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse
app = FastAPI()
@app.get("/")
async def get():
return HTMLResponse("""
<!DOCTYPE html>
<html>
<head>
<title>WebSocket 测试</title>
</head>
<body>
<h1>WebSocket 测试页面</h1>
<form action="" οnsubmit="sendMessage(event)">
<input type="text" id="messageText" autocomplete="off"/>
<button>发送</button>
</form>
<ul id='messages'>
</ul>
<script>
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()
}
</script>
</body>
</html>
""")
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
while True:
data = await websocket.receive_text()
await websocket.send_text(f"服务器收到: {data}")
except WebSocketDisconnect:
print("客户端断开连接")
3. 运行 FastAPI 应用
使用 Uvicorn 运行应用:
uvicorn main:app --reload
main
:指的是main.py
文件。app
:是 FastAPI 实例的名称。--reload
:在代码修改时自动重启服务器(适用于开发环境)。
运行后,你的 WebSocket 服务将监听在 ws://localhost:8000/ws
。
二、使用 Postman 测试 WebSocket 接口
1. 确保 Postman 版本支持 WebSocket
确保你安装的是最新版本的 Postman,因为 WebSocket 功能是在较新的版本中引入的。你可以从 Postman 官网 下载最新版本。
2. 创建新的 WebSocket 请求
-
打开 Postman。
-
创建新请求:
- 点击左上角的 “New” 按钮。
- 选择 “WebSocket Request”。
-
输入 WebSocket URL:
在地址栏中输入你的 WebSocket 服务器的 URL。在本例中,使用本地服务器:
ws://localhost:8000/ws
-
连接到 WebSocket 服务器:
- 输入 URL 后,点击 “Connect” 按钮。
- 如果连接成功,状态会显示为 “Connected”。
3. 发送消息
-
输入消息:
在 “Message” 输入框中输入你想发送的消息。例如:
Hello, FastAPI WebSocket!
-
发送消息:
点击 “Send” 按钮发送消息。
4. 接收消息
-
发送消息后,你应该在 “Messages” 面板中看到服务器的响应。例如:
服务器收到: Hello, FastAPI WebSocket!
5. 断开连接
测试完成后,点击 “Disconnect” 按钮以断开与 WebSocket 服务器的连接。
三、完整示例操作
以下是一个完整的操作流程示例:
-
启动 FastAPI 服务:
在终端中运行:
uvicorn main:app --reload
你应该会看到类似如下的输出,表示服务器正在运行:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [12345] using statreload INFO: Started server process [12346] INFO: Waiting for application startup. INFO: Application startup complete.
-
打开 Postman 并创建 WebSocket 请求:
- 输入 URL:
ws://localhost:8000/ws
- 点击 “Connect”
- 输入 URL:
-
发送消息并查看响应:
- 在 “Message” 输入框中输入:
Hello, FastAPI!
- 点击 “Send”
- 在 “Messages” 面板中看到:
服务器收到: Hello, FastAPI!
- 在 “Message” 输入框中输入:
-
断开连接:
点击 “Disconnect”
四、注意事项
-
端口和地址:确保 FastAPI 服务器和 Postman 中使用的地址及端口一致。例如,如果你在服务器上使用不同的端口(如 8001),请相应地在 Postman 中修改 URL。
-
防火墙和网络设置:如果你在远程服务器上运行 FastAPI,需要确保相关端口对外开放,并且网络配置允许连接。
-
认证与安全:如果你的 WebSocket 接口需要认证(如使用 JWT 或其他令牌),你需要在连接 URL 中包含查询参数,或者在连接后通过发送认证消息来完成认证。
例如,使用查询参数传递令牌:
ws://localhost:8000/ws?token=your_jwt_token
在 FastAPI 中,你可以通过
websocket.query_params
获取这些参数:@app.websocket("/ws") async def websocket_endpoint(websocket: WebSocket): token = websocket.query_params.get("token") if not validate_token(token): await websocket.close(code=1008) # Policy Violation return await websocket.accept() # 后续逻辑
-
消息格式:确保发送的消息格式符合服务器的要求。例如,如果服务器期望 JSON 格式的数据,请发送有效的 JSON 字符串。
五、扩展功能
你可以根据需要扩展 WebSocket 接口的功能,例如:
- 广播消息:实现多个客户端之间的消息广播。
- 群组管理:将客户端分组,实现不同群组的消息隔离。
- 实时数据推送:如实时聊天、在线游戏等应用场景。
以下是一个简单的广播消息的示例:
# 文件名:main.py
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from typing import List
app = FastAPI()
class ConnectionManager:
def __init__(self):
self.active_connections: List[WebSocket] = []
async def connect(self, websocket: WebSocket):
await websocket.accept()
self.active_connections.append(websocket)
print(f"新连接:{websocket.client}")
def disconnect(self, websocket: WebSocket):
self.active_connections.remove(websocket)
print(f"断开连接:{websocket.client}")
async def broadcast(self, message: str):
for connection in self.active_connections:
await connection.send_text(message)
manager = ConnectionManager()
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await manager.connect(websocket)
try:
while True:
data = await websocket.receive_text()
await manager.broadcast(f"客户端 {websocket.client} 说: {data}")
except WebSocketDisconnect:
manager.disconnect(websocket)
在这个示例中,所有连接到 /ws
的客户端都会收到其他客户端发送的消息,实现了基本的广播功能。
一、在 FastAPI 中实现带有 Token 校验的 WebSocket 接口
1. 环境准备
确保你已经安装了以下库:
# 创建并激活虚拟环境(可选,但推荐)
python -m venv venv
source venv/bin/activate # Windows 用户使用 `venv\Scripts\activate`
# 安装 FastAPI 和 Uvicorn
pip install fastapi uvicorn
# 安装 AuthJWT 用于 JWT 认证
pip install fastapi-jwt-auth
# 安装其他可能需要的库
pip install pydantic
2. 配置 AuthJWT
AuthJWT 是一个用于处理 JWT 认证的 FastAPI 插件。我们需要配置它的密钥和相关设置。
创建一个配置文件 config.py
:
# 文件名:config.py
from pydantic import BaseSettings
class Settings(BaseSettings):
authjwt_secret_key: str = "your_secret_key" # 替换为你自己的密钥
class Config:
env_file = ".env"
settings = Settings()
注意:在生产环境中,请确保 SECRET_KEY 的安全性,避免硬编码在代码中。可以通过环境变量或其他安全方式管理密钥。
3. 编写 FastAPI 应用
根据你提供的 chat
函数示例,我们将创建一个包含 Token 校验的 WebSocket 接口。以下是完整的 main.py
示例:
# 文件名:main.py
from fastapi import FastAPI, WebSocket, WebSocketDisconnect, Depends, HTTPException
from fastapi_jwt_auth import AuthJWT
from fastapi_jwt_auth.exceptions import AuthJWTException
from fastapi.responses import HTMLResponse
from fastapi import status
from pydantic import BaseModel
from typing import Optional
import json
import logging
# 导入配置
from config import settings
app = FastAPI()
# 设置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# 配置 AuthJWT
class SettingsModel(BaseModel):
authjwt_secret_key: str = settings.authjwt_secret_key
@AuthJWT.load_config
def get_config():
return SettingsModel()
# 处理 AuthJWT 异常
@app.exception_handler(AuthJWTException)
def authjwt_exception_handler(request, exc):
return JSONResponse(
status_code=exc.status_code,
content={"detail": exc.message}
)
# 示例用户数据获取函数
async def get_login_user(Authorize: AuthJWT):
try:
current_user = Authorize.get_jwt_subject()
# 这里可以根据 current_user 从数据库获取用户信息
return {"user_id": current_user}
except:
raise HTTPException(status_code=401, detail="Unauthorized")
# WebSocket 端点
@app.websocket('/chat/{flow_id}')
async def chat(
*,
flow_id: str,
websocket: WebSocket,
t: Optional[str] = None,
chat_id: Optional[str] = None,
version_id: Optional[int] = None,
Authorize: AuthJWT = Depends(),
):
"""Websocket endpoint for chat."""
try:
if t:
Authorize.jwt_required(auth_from='websocket', token=t)
Authorize._token = t
else:
Authorize.jwt_required(auth_from='websocket', websocket=websocket)
login_user = await get_login_user(Authorize)
user_id = login_user["user_id"]
# 这里添加你的业务逻辑,例如 flow_id 验证等
# 以下为示例逻辑,请根据实际需求修改
# 示例:简单的回显功能
await websocket.accept()
logger.info(f"用户 {user_id} 连接到 flow_id {flow_id}")
while True:
data = await websocket.receive_text()
logger.info(f"收到消息: {data} 来自用户: {user_id}")
await websocket.send_text(f"服务器收到: {data}")
except WebSocketDisconnect:
logger.info(f"用户 {user_id} 断开连接")
except Exception as exc:
logger.error(f"Websocket 错误: {str(exc)}")
await websocket.close(code=status.WS_1011_INTERNAL_ERROR, reason=str(exc))
4. 创建 Token 生成端点
为了测试,我们需要一个生成 Token 的端点。创建一个简单的登录端点 login
,用于生成 JWT Token。
# 在 main.py 中添加以下内容
from fastapi import Form
@app.post('/login')
def login(username: str = Form(...), password: str = Form(...), Authorize: AuthJWT = Depends()):
"""
简单的登录端点,用于生成 JWT Token。
"""
# 这里添加你的用户验证逻辑,例如检查用户名和密码
if username != "testuser" or password != "testpass":
raise HTTPException(status_code=401, detail="Bad username or password")
access_token = Authorize.create_access_token(subject=username)
return {"access_token": access_token}
注意:这是一个非常简化的示例,请根据实际需求实现用户认证逻辑。
5. 运行 FastAPI 应用
确保所有代码保存后,使用 Uvicorn 运行应用:
uvicorn main:app --reload
运行后,服务器将监听在 http://localhost:8000
。
二、使用 Postman 测试带有 Token 校验的 WebSocket 接口
1. 生成 JWT Token
首先,我们需要通过登录端点获取一个有效的 Token。
-
打开 Postman。
-
创建一个新的请求:
- 方法选择 POST。
- URL 输入:
http://localhost:8000/login
。
-
设置请求体:
- 选择
x-www-form-urlencoded
。 - 添加以下键值对:
username
:testuser
password
:testpass
- 选择
-
发送请求。
-
获取 Token:
-
如果用户名和密码正确,你将收到类似如下的响应:
{ "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." }
-
复制
access_token
的值,稍后将用于 WebSocket 连接。
-
2. 创建 WebSocket 请求
-
在 Postman 中创建新的 WebSocket 请求:
- 点击左上角的 “New” 按钮。
- 选择 “WebSocket Request”。
-
输入 WebSocket URL:
-
假设你要连接到
flow_id
为
12345
的聊天接口,URL 格式如下:
ws://localhost:8000/chat/12345?t=your_access_token
-
将
your_access_token
替换为之前获取的 Token。例如:
ws://localhost:8000/chat/12345?t=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
-
-
连接到 WebSocket 服务器:
- 输入 URL 后,点击 “Connect” 按钮。
- 如果 Token 有效,连接将成功,状态显示为 “Connected”。
- 如果 Token 无效或缺失,连接将被服务器拒绝,并显示错误信息。
3. 发送和接收消息
-
发送消息:
-
在
“Message”
输入框中输入你想发送的消息。例如:
Hello, FastAPI with Token!
-
点击 “Send” 按钮发送消息。
-
-
接收消息:
-
服务器会回显消息,例如:
服务器收到: Hello, FastAPI with Token!
-
这些消息会显示在 “Messages” 面板中,便于调试和验证接口行为。
-
4. 断开连接
测试完成后,点击 “Disconnect” 按钮以断开与 WebSocket 服务器的连接。
三、完整操作流程示例
以下是一个完整的操作流程示例,帮助你更好地理解和实施:
1. 启动 FastAPI 服务
在终端中运行:
uvicorn main:app --reload
你应该会看到类似如下的输出,表示服务器正在运行:
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [12345] using statreload
INFO: Started server process [12346]
INFO: Waiting for application startup.
INFO: Application startup complete.
2. 获取 JWT Token
-
发送登录请求:
-
方法:POST
-
URL:
http://localhost:8000/login
-
Body:
x-www-form-urlencoded
username
:testuser
password
:testpass
-
-
获取 Token:
-
成功响应:
{ "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." }
-
3. 连接到 WebSocket 端点
- 创建 WebSocket 请求:
- URL:
ws://localhost:8000/chat/12345?t=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
- URL:
- 连接成功:
- 状态显示为 “Connected”。
4. 发送和接收消息
-
发送消息:
Hello, FastAPI with Token!
-
接收响应:
服务器收到: Hello, FastAPI with Token!
5. 断开连接
点击 “Disconnect” 按钮。
四、注意事项
1. Token 传递方式
在你的 chat
函数中,Token 可以通过查询参数 t
传递,也可以通过 WebSocket 的方式传递。我们在示例中使用了查询参数的方式,这也是最常见和简便的方法。
2. 安全性
- 使用
wss://
:在生产环境中,建议使用加密的 WebSocket 连接(wss://
),以保护 Token 和数据的安全。 - Token 过期与刷新:确保 Token 有合理的过期时间,并实现 Token 刷新机制,防止长期有效的 Token 被滥用。
3. 错误处理
- 无效 Token:当 Token 无效或缺失时,服务器会以 1008(Policy Violation) 状态码关闭连接,并提供相应的错误信息。你可以在客户端捕获此事件并做出相应处理。
- 其他错误:对于其他异常情况,服务器会以 1011(Internal Error) 状态码关闭连接,并返回错误详情。
4. 扩展功能
根据需求,你可以进一步扩展 WebSocket 服务的功能,例如:
- 广播消息:实现多个客户端之间的消息广播。
- 群组管理:将客户端分组,实现不同群组的消息隔离。
- 实时数据推送:如实时聊天、在线游戏等应用场景。
- 用户管理:根据 Token 获取用户信息,实现个性化服务。
- 权限控制:根据用户角色限制访问某些功能或频道。
- 心跳机制:实现心跳机制,检测客户端是否仍然在线。