| 66 |
websocket后端基础示例FastAPI案例 |
<div style="color: #d1d3db; background-color: #1a1b1d; font-family: 'JetBrains Mono', Consolas, 'Courier New', monospace; font-size: 13px; line-height: 22px; white-space: pre;">
<div><span style="color: #b38cff;">from</span> <span style="color: #81cfe0;">fastapi</span> <span style="color: #b38cff;">import</span> <span style="color: #81cfe0;">FastAPI</span>, <span style="color: #81cfe0;">WebSocket</span>, <span style="color: #81cfe0;">WebSocketDisconnect</span></div>
<div><span style="color: #b38cff;">from</span> <span style="color: #81cfe0;">fastapi</span>.<span style="color: #81cfe0;">middleware</span>.<span style="color: #81cfe0;">cors</span> <span style="color: #b38cff;">import</span> <span style="color: #81cfe0;">CORSMiddleware</span></div>
<div><span style="color: #b38cff;">import</span> <span style="color: #81cfe0;">uvicorn</span></div>
<br />
<div><span style="color: #737780;"># 创建 FastAPI 实例</span></div>
<div><span style="color: #ded47e;">app</span> <span style="color: #d5d8e0;">=</span> <span style="color: #81cfe0;">FastAPI</span>()</div>
<br />
<div><span style="color: #737780;"># 配置 CORS (跨域资源共享)</span></div>
<div><span style="color: #737780;"># 允许所有来源访问,实际生产环境中应更严格地配置</span></div>
<div><span style="color: #ded47e;">app</span>.<span style="color: #f29d79;">add_middleware</span>(</div>
<div> <span style="color: #81cfe0;">CORSMiddleware</span>,</div>
<div> <span style="color: #ded47e;">allow_origins</span><span style="color: #d5d8e0;">=</span>[<span style="color: #82d99f;">"*"</span>], <span style="color: #737780;"># 允许所有来源</span></div>
<div> <span style="color: #ded47e;">allow_credentials</span><span style="color: #d5d8e0;">=</span><span style="color: #80bbff;">True</span>,</div>
<div> <span style="color: #ded47e;">allow_methods</span><span style="color: #d5d8e0;">=</span>[<span style="color: #82d99f;">"*"</span>], <span style="color: #737780;"># 允许所有 HTTP 方法</span></div>
<div> <span style="color: #ded47e;">allow_headers</span><span style="color: #d5d8e0;">=</span>[<span style="color: #82d99f;">"*"</span>], <span style="color: #737780;"># 允许所有 HTTP 头</span></div>
<div>)</div>
<br />
<div><span style="color: #737780;"># 连接管理器类</span></div>
<div><span style="color: #737780;"># 用于管理活跃的 WebSocket 连接,实现消息广播</span></div>
<div><span style="color: #b38cff;">class</span> <span style="color: #81cfe0;">ConnectionManager</span>:</div>
<div> <span style="color: #b38cff;">def</span> <span style="color: #f29d79;">__init__</span>(<span style="color: #ded47e;">self</span>):</div>
<div> <span style="color: #737780;"># 存储活跃的 WebSocket 连接列表</span></div>
<div> <span style="color: #ded47e;">self</span>.<span style="color: #e0e3ee;">active_connections</span>: <span style="color: #81cfe0;">list</span>[<span style="color: #81cfe0;">WebSocket</span>] <span style="color: #d5d8e0;">=</span> []</div>
<br />
<div> <span style="color: #b38cff;">async</span> <span style="color: #b38cff;">def</span> <span style="color: #f29d79;">connect</span>(<span style="color: #ded47e;">self</span>, <span style="color: #ded47e;">websocket</span>: <span style="color: #81cfe0;">WebSocket</span>):</div>
<div> <span style="color: #82d99f;">"""接受连接并将其添加到活跃连接列表"""</span></div>
<div> <span style="color: #b38cff;">await</span> <span style="color: #ded47e;">websocket</span>.<span style="color: #f29d79;">accept</span>()</div>
<div> <span style="color: #ded47e;">self</span>.<span style="color: #e0e3ee;">active_connections</span>.<span style="color: #f29d79;">append</span>(<span style="color: #ded47e;">websocket</span>)</div>
<br />
<div> <span style="color: #b38cff;">def</span> <span style="color: #f29d79;">disconnect</span>(<span style="color: #ded47e;">self</span>, <span style="color: #ded47e;">websocket</span>: <span style="color: #81cfe0;">WebSocket</span>):</div>
<div> <span style="color: #82d99f;">"""断开连接时从列表中移除"""</span></div>
<div> <span style="color: #ded47e;">self</span>.<span style="color: #e0e3ee;">active_connections</span>.<span style="color: #f29d79;">remove</span>(<span style="color: #ded47e;">websocket</span>)</div>
<br />
<div> <span style="color: #b38cff;">async</span> <span style="color: #b38cff;">def</span> <span style="color: #f29d79;">broadcast</span>(<span style="color: #ded47e;">self</span>, <span style="color: #ded47e;">message</span>: <span style="color: #81cfe0;">str</span>):</div>
<div> <span style="color: #82d99f;">"""向所有活跃连接发送消息"""</span></div>
<div> <span style="color: #b38cff;">for</span> <span style="color: #ded47e;">connection</span> <span style="color: #b38cff;">in</span> <span style="color: #ded47e;">self</span>.<span style="color: #e0e3ee;">active_connections</span>:</div>
<div> <span style="color: #b38cff;">await</span> <span style="color: #ded47e;">connection</span>.<span style="color: #f29d79;">send_text</span>(<span style="color: #ded47e;">message</span>)</div>
<br />
<div><span style="color: #737780;"># 实例化连接管理器</span></div>
<div><span style="color: #ded47e;">manager</span> <span style="color: #d5d8e0;">=</span> <span style="color: #81cfe0;">ConnectionManager</span>()</div>
<br />
<div><span style="color: #737780;"># WebSocket 路由 endpoint</span></div>
<div><span style="color: #737780;"># 路径参数 client_id 用于标识客户端</span></div>
<div><span style="color: #f29d79;">@</span><span style="color: #ded47e;">app</span><span style="color: #f29d79;">.</span><span style="color: #f29d79;">websocket</span>(<span style="color: #82d99f;">"/ws/</span><span style="color: #80bbff;">{client_id}</span><span style="color: #82d99f;">"</span>)</div>
<div><span style="color: #b38cff;">async</span> <span style="color: #b38cff;">def</span> <span style="color: #f29d79;">websocket_endpoint</span>(<span style="color: #ded47e;">websocket</span>: <span style="color: #81cfe0;">WebSocket</span>, <span style="color: #ded47e;">client_id</span>: <span style="color: #81cfe0;">int</span>):</div>
<div> <span style="color: #737780;"># 1. 建立连接</span></div>
<div> <span style="color: #b38cff;">await</span> <span style="color: #ded47e;">manager</span>.<span style="color: #f29d79;">connect</span>(<span style="color: #ded47e;">websocket</span>)</div>
<div> <span style="color: #b38cff;">try</span>:</div>
<div> <span style="color: #737780;"># 2. 循环接收消息</span></div>
<div> <span style="color: #b38cff;">while</span> <span style="color: #80bbff;">True</span>:</div>
<div> <span style="color: #737780;"># 等待客户端发送文本消息</span></div>
<div> <span style="color: #ded47e;">data</span> <span style="color: #d5d8e0;">=</span> <span style="color: #b38cff;">await</span> <span style="color: #ded47e;">websocket</span>.<span style="color: #f29d79;">receive_text</span>()</div>
<div> <span style="color: #737780;"># 3. 广播消息给所有用户</span></div>
<div> <span style="color: #b38cff;">await</span> <span style="color: #ded47e;">manager</span>.<span style="color: #f29d79;">broadcast</span>(<span style="color: #b38cff;">f</span><span style="color: #82d99f;">"Client #</span><span style="color: #80bbff;">{</span><span style="color: #ded47e;">client_id</span><span style="color: #80bbff;">}</span><span style="color: #82d99f;"> says: </span><span style="color: #80bbff;">{</span><span style="color: #ded47e;">data</span><span style="color: #80bbff;">}</span><span style="color: #82d99f;">"</span>)</div>
<div> <span style="color: #b38cff;">except</span> <span style="color: #81cfe0;">WebSocketDisconnect</span>:</div>
<div> <span style="color: #737780;"># 4. 处理断开连接</span></div>
<div> <span style="color: #ded47e;">manager</span>.<span style="color: #f29d79;">disconnect</span>(<span style="color: #ded47e;">websocket</span>)</div>
<div> <span style="color: #b38cff;">await</span> <span style="color: #ded47e;">manager</span>.<span style="color: #f29d79;">broadcast</span>(<span style="color: #b38cff;">f</span><span style="color: #82d99f;">"Client #</span><span style="color: #80bbff;">{</span><span style="color: #ded47e;">client_id</span><span style="color: #80bbff;">}</span><span style="color: #82d99f;"> left the chat"</span>)</div>
<br />
<div><span style="color: #b38cff;">if</span> <span style="color: #ded47e;">__name__</span> <span style="color: #d5d8e0;">==</span> <span style="color: #82d99f;">"__main__"</span>:</div>
<div> <span style="color: #737780;"># 启动 uvicorn 服务器</span></div>
<div> <span style="color: #737780;"># host="0.0.0.0" 允许外部访问</span></div>
<div> <span style="color: #737780;"># port=8000 服务端口</span></div>
<div> <span style="color: #81cfe0;">uvicorn</span>.<span style="color: #f29d79;">run</span>(<span style="color: #ded47e;">app</span>, <span style="color: #ded47e;">host</span><span style="color: #d5d8e0;">=</span><span style="color: #82d99f;">"0.0.0.0"</span>, <span style="color: #ded47e;">port</span><span style="color: #d5d8e0;">=</span><span style="color: #f48cca;">8000</span>)</div>
</div> |
1 |
69 |
1 |
3/7/26, 7:39 PM |
3/7/26, 7:39 PM |
View Edit Delete |