编程 FastAPI和WebSockets构建一个实时聊天应用程序

2024-11-18 16:03:28 +0800 CST views 633

FastAPI WebSockets:构建实时聊天应用程序

FastAPI 是一个现代、快速(高性能)的 Web 框架,用于基于标准 Python 类型提示构建 API。其强大功能之一是支持 WebSockets,这使得客户端和服务器之间的实时通信成为可能。在本文中,我们将通过构建一个简单的实时聊天应用程序,探讨如何在 FastAPI 中使用 WebSockets。

1. WebSockets 简介

WebSockets 提供了一个通过单个长连接实现全双工通信的通道。与传统的 HTTP 请求不同,WebSockets 支持双向通信,允许服务器将更新直接发送到客户端,而无需客户端请求。这使得 WebSockets 成为聊天应用、实时通知和游戏等实时应用的理想选择。

2. 设置 FastAPI 项目

首先,安装 FastAPI 和 ASGI 服务器(例如 uvicorn):

pip install fastapi uvicorn

接着,创建一个新的 Python 文件 main.py,并设置基本的 FastAPI 应用:

from fastapi import FastAPI, WebSocket
from fastapi.websockets import WebSocketDisconnect

app = FastAPI()

@app.get("/")
async def get():
    return {"message": "Welcome to FastAPI WebSockets Chat App"}

3. 实现 WebSocket 端点

接下来,我们为聊天应用实现 WebSocket 端点,并创建一个类来管理客户端连接以及向所有连接的客户端广播消息。

from typing import List

class ConnectionManager:
    def __init__(self):
        self.active_connections: List[WebSocket] = []

    async def connect(self, websocket: WebSocket):
        await websocket.accept()
        self.active_connections.append(websocket)

    def disconnect(self, websocket: WebSocket):
        self.active_connections.remove(websocket)

    async def send_personal_message(self, message: str, websocket: WebSocket):
        await websocket.send_text(message)

    async def broadcast(self, message: str):
        for connection in self.active_connections:
            await connection.send_text(message)

manager = ConnectionManager()

@app.websocket("/ws/chat")
async def websocket_endpoint(websocket: WebSocket):
    await manager.connect(websocket)
    try:
        while True:
            data = await websocket.receive_text()
            await manager.broadcast(f"Client says: {data}")
    except WebSocketDisconnect:
        manager.disconnect(websocket)
        await manager.broadcast("A client disconnected")

4. 创建前端

现在,让我们创建一个简单的 HTML 文件作为聊天应用的前端。在 main.py 的同一目录中创建一个名为 index.html 的新文件。

<!DOCTYPE html>
<html>
<head>
    <title>FastAPI Chat</title>
</head>
<body>
    <h1>FastAPI WebSockets Chat</h1>
    <div id="chat-log"></div>
    <input type="text" id="message-input" autocomplete="off"/>
    <button onclick="sendMessage()">Send</button>

    <script>
        const ws = new WebSocket("ws://localhost:8000/ws/chat");
        
        ws.onmessage = function(event) {
            const messages = document.getElementById('chat-log');
            const message = document.createElement('div');
            const content = document.createTextNode(event.data);
            message.appendChild(content);
            messages.appendChild(message);
        };

        function sendMessage() {
            const input = document.getElementById("message-input");
            ws.send(input.value);
            input.value = '';
        }
    </script>
</body>
</html>

5. 运行和测试应用程序

要运行应用程序,请使用 uvicorn 启动 FastAPI 服务器:

uvicorn main:app --reload

打开 Web 浏览器并导航到 http://localhost:8000,查看聊天应用程序的运行情况。您可以打开多个浏览器窗口或选项卡,在它们之间实时发送消息。

6. 增强功能

1. 添加用户身份验证

可以通过在前端添加用户名输入来增强聊天应用。更新前端 HTML:

<input type="text" id="username-input" placeholder="Enter your username" autocomplete="off"/>

并修改 sendMessage() 函数:

function sendMessage() {
    const input = document.getElementById("message-input");
    const username = document.getElementById("username-input").value;
    ws.send(`${username}: ${input.value}`);
    input.value = '';
}

后端不需要做太多更改,依旧会接收并广播完整消息。

2. 消息持久化

为了持久化消息,可以使用 SQLite 数据库来存储聊天记录,并在客户端连接时加载历史记录。

main.py 中添加 SQLite 数据库的相关代码:

import sqlite3

# Database setup
conn = sqlite3.connect('chat.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS messages (content TEXT)''')
conn.commit()

# 在广播消息时,保存到数据库
async def broadcast(self, message: str):
    c.execute("INSERT INTO messages (content) VALUES (?)", (message,))
    conn.commit()
    for connection in self.active_connections:
        await connection.send_text(message)

3. 添加输入指示器

为了显示用户正在输入的消息,可以扩展前端,使用 WebSocket.send() 发送 "用户正在输入" 消息。

<input type="text" id="message-input" autocomplete="off" oninput="indicateTyping()"/>
<script>
function indicateTyping() {
    const username = document.getElementById("username-input").value;
    ws.send(`${username} is typing...`);
}
</script>

后端无需做太多修改,直接接收并广播这些“输入中”的提示消息。

结语

本文展示了如何使用 FastAPI 和 WebSockets 构建一个实时聊天应用。我们实现了基本的聊天功能,并逐步扩展了身份验证、消息持久化和输入指示器等功能。WebSockets 是构建实时 Web 应用程序的理想工具,FastAPI 简洁的架构使其实现非常简单。

推荐文章

Rust 高性能 XML 读写库
2024-11-19 07:50:32 +0800 CST
Go 单元测试
2024-11-18 19:21:56 +0800 CST
Mysql允许外网访问详细流程
2024-11-17 05:03:26 +0800 CST
# 解决 MySQL 经常断开重连的问题
2024-11-19 04:50:20 +0800 CST
如何使用go-redis库与Redis数据库
2024-11-17 04:52:02 +0800 CST
Manticore Search:高性能的搜索引擎
2024-11-19 03:43:32 +0800 CST
用 Rust 玩转 Google Sheets API
2024-11-19 02:36:20 +0800 CST
如何在 Vue 3 中使用 Vuex 4?
2024-11-17 04:57:52 +0800 CST
js常用通用函数
2024-11-17 05:57:52 +0800 CST
CSS Grid 和 Flexbox 的主要区别
2024-11-18 23:09:50 +0800 CST
HTML + CSS 实现微信钱包界面
2024-11-18 14:59:25 +0800 CST
16.6k+ 开源精准 IP 地址库
2024-11-17 23:14:40 +0800 CST
开发外贸客户的推荐网站
2024-11-17 04:44:05 +0800 CST
程序员茄子在线接单