E:\song2\fastapi_socketio_chatroom\app.py
| |
| import socketio |
| |
| |
| from fastapi import FastAPI, WebSocket, Request, WebSocketDisconnect |
| from fastapi.responses import RedirectResponse, HTMLResponse |
| from fastapi.staticfiles import StaticFiles |
| from fastapi.openapi.docs import get_swagger_ui_html |
| from fastapi.templating import Jinja2Templates |
| from fastapi.middleware.cors import CORSMiddleware |
| |
| |
| app = FastAPI(docs_url=None) |
| |
| |
| sio = socketio.AsyncServer(async_mode="asgi", cors_allowed_origins=[]) |
| app.mount("/ws", socketio.ASGIApp(sio)) |
| |
| |
| app.add_middleware( |
| CORSMiddleware, |
| allow_origins=["*"], |
| allow_credentials=True, |
| allow_methods=["*"], |
| allow_headers=["*"], |
| ) |
| |
| |
| templates = Jinja2Templates(directory="templates") |
| app.mount('/static', StaticFiles(directory='static'), name='static') |
| |
| |
| @app.get('/docs', include_in_schema=False) |
| async def custom_swagger_ui_html(): |
| return get_swagger_ui_html( |
| openapi_url=app.openapi_url, |
| title=app.title + " - Swagger UI ", |
| oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url, |
| swagger_js_url="/static/swagger-ui/swagger-ui-bundle.js", |
| swagger_css_url="/static/swagger-ui/swagger-ui.css", |
| swagger_favicon_url="/static/swagger-ui/favicon.png" |
| ) |
| |
| |
| |
| @app.get("/", tags=["Docs"]) |
| async def get_docs(): |
| return RedirectResponse("/docs") |
| |
| |
| |
| @app.get("/agv", response_class=HTMLResponse) |
| async def read_jinjia2(request: Request): |
| return templates.TemplateResponse("index.html", {"request": request }) |
| |
| |
| |
| @app.get("/websocket", response_class=HTMLResponse) |
| async def websocket_test(request: Request): |
| return templates.TemplateResponse("websocket.html", {"request": request}) |
| |
| |
| @app.websocket("/wstest") |
| async def websocket_endpoint(websocket: WebSocket): |
| await websocket.accept() |
| while True: |
| data = await websocket.receive_text() |
| await websocket.send_text(f"send from serve: {data}") |
| |
| |
| |
| |
| @sio.event |
| async def connect(sid, environ): |
| |
| print(f'~~~~sid={sid}, {environ["HTTP_ORIGIN"]},连接成功~~~~') |
| sio.enter_room(sid,'agv') |
| await sio.emit('message',f'sid={sid},进入房间',room='agv') |
| |
| |
| @sio.event |
| async def disconnect(sid): |
| print(f'~~~~sid={sid},断开连接~~~~') |
| sio.leave_room(sid,'agv') |
| await sio.emit('disconnect',f'sid={sid},离开房间',room='agv') |
| |
| |
| @sio.event |
| async def message(sid,data): |
| print(f'~~~~data = {data}, message from sid={sid}~~~~') |
| await sio.emit('message','msg from server',room='agv') |
| |
| |
| |
| |
| |
| |
| |
| |
| |
E:\song2\fastapi_socketio_chatroom\main.py
| import uvicorn |
| |
| if __name__ == '__main__': |
| uvicorn.run('app:app', host="127.0.0.1", port=9000, reload=True) |
| |
E:\song2\fastapi_socketio_chatroom\templates\index.html
| <!DOCTYPE html> |
| <html lang="en"> |
| |
| <head> |
| <meta charset="UTF-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title>AGV Path</title> |
| <script type="module" crossorigin src="{{url_for('static',path='/assets/index.85cdc1d7.js' )}}"></script> |
| <link rel="stylesheet" href="{{url_for('static',path='/assets/index.c1b68991.css' )}}"> |
| </head> |
| |
| <body> |
| <div id="app"></div> |
| |
| </body> |
| |
| </html> |
E:\song2\fastapi_socketio_chatroom\templates\websocket.html
| <!DOCTYPE html> |
| <html> |
| |
| <head> |
| <title>Chat</title> |
| </head> |
| |
| <body> |
| <h1>WebSocket Chat</h1> |
| <form action="" onsubmit="sendMessage(event)"> |
| <input type="text" id="messageText" autocomplete="off" /> |
| <button>Send</button> |
| </form> |
| <ul id='messages'> |
| </ul> |
| <script> |
| |
| const ws = new WebSocket("ws://localhost:9000/ws"); |
| |
| |
| ws.addEventListener('open', (e) => { |
| console.log(`socket 连接成功`) |
| }) |
| |
| ws.addEventListener('error', (e) => { |
| console.log(`socket 连接失败`) |
| }) |
| |
| ws.addEventListener('close', (e) => { |
| console.log(`socket 连接断开`) |
| }) |
| |
| |
| ws.onmessage = function (event) { |
| receMessage(event.data) |
| }; |
| |
| |
| function receMessage(msg) { |
| var messages = document.getElementById('messages') |
| var message = document.createElement('li') |
| var content = document.createTextNode(msg) |
| 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> |
E:\song\socketio_test\vite-project-2\index.html
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <link rel="icon" type="image/svg+xml" href="/vite.svg" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title>Vite + TS</title> |
| </head> |
| <body> |
| <div id="app"></div> |
| <script type="module" src="/src/main.ts"></script> |
| </body> |
| </html> |
| |
E:\song\socketio_test\vite-project-2\src\main.ts
| import { io } from "socket.io-client"; |
| import axios from "axios"; |
| |
| const axiosInstance = axios.create({ |
| baseURL: "http://127.0.0.1:9000", |
| timeout: 1000, |
| }); |
| |
| const socket = io("http://localhost:9000/", { path: "/ws/socket.io/" }); |
| |
| document.querySelector<HTMLDivElement>("#app")!.innerHTML = ` |
| <div> |
| <button id='send'>发送axios请求</button> |
| <hr/> |
| <button id='open-socket'>打开socket连接</button> |
| <button id='send-socket'>发送socket请求</button> |
| <button id='close-socket'>断开socket连接</button> |
| </div> |
| `; |
| |
| document.getElementById("send")!.addEventListener("click", async () => { |
| const res = await axiosInstance.get("/httptest"); |
| const oRes = document.createElement("div"); |
| oRes.innerHTML = res.data.data; |
| document.querySelector<HTMLDivElement>("#app")!.appendChild(oRes); |
| }); |
| |
| document.getElementById("open-socket")!.addEventListener("click", async () => { |
| socket.connect(); |
| }); |
| |
| document.getElementById("send-socket")!.addEventListener("click", async () => { |
| const msg = "msg from client"; |
| socket.emit("message", msg); |
| const oRes = document.createElement("div"); |
| oRes.innerHTML = `发送: ${msg}`; |
| document.querySelector<HTMLDivElement>("#app")!.appendChild(oRes); |
| }); |
| |
| document.getElementById("close-socket")!.addEventListener("click", async () => { |
| socket.close(); |
| }); |
| |
| socket.on("connect", () => { |
| console.log("~~connect success~~"); |
| }); |
| |
| socket.on("disconnect", (response: any) => { |
| console.log("~~ disconnect ~~" + response); |
| }); |
| |
| socket.on("message", (response) => { |
| console.log(`收到: ${response}`); |
| |
| const oRes = document.createElement("div"); |
| oRes.innerHTML = `收到: ${response}`; |
| document.querySelector<HTMLDivElement>("#app")!.appendChild(oRes); |
| }); |
| |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战