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

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

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 简洁的架构使其实现非常简单。

推荐文章

2024年微信小程序开发价格概览
2024-11-19 06:40:52 +0800 CST
windows下mysql使用source导入数据
2024-11-17 05:03:50 +0800 CST
前端如何给页面添加水印
2024-11-19 07:12:56 +0800 CST
Vue3中的响应式原理是什么?
2024-11-19 09:43:12 +0800 CST
使用Vue 3和Axios进行API数据交互
2024-11-18 22:31:21 +0800 CST
在 Nginx 中保存并记录 POST 数据
2024-11-19 06:54:06 +0800 CST
Vue3中如何处理跨域请求?
2024-11-19 08:43:14 +0800 CST
百度开源压测工具 dperf
2024-11-18 16:50:58 +0800 CST
维护网站维护费一年多少钱?
2024-11-19 08:05:52 +0800 CST
Linux查看系统配置常用命令
2024-11-17 18:20:42 +0800 CST
liunx服务器监控workerman进程守护
2024-11-18 13:28:44 +0800 CST
使用 Nginx 获取客户端真实 IP
2024-11-18 14:51:58 +0800 CST
H5保险购买与投诉意见
2024-11-19 03:48:35 +0800 CST
任务管理工具的HTML
2025-01-20 22:36:11 +0800 CST
程序员茄子在线接单