我目前正在开发一个双向API,使用Python FastAPI作为后端,ReactJS作为前端。由于API调用应该是可扩展的,我想创建多个副本,可以通过也在Docker中运行的Nginx服务器访问。以下是我的docker compose文件:
version: "3.9"
services:
api:
build:
context: api
ports:
- 8000
load_balance:
image: nginx:latest
volumes:
- ./dimer_api/nginx.conf:/etc/nginx/nginx.conf:rw
depends_on:
- api
ports:
- 8000:8000
gui:
build:
context: gui
ports:
- 80:80
depends_on:
- load_balance
FastAPI代码如下所示:
websockets = []
@router.websocket("/api/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
try:
while True:
message = await websocket.receive_text()
data = {"status": "ok", "type": "message", "message": message}
await websocket.send_text(json.dumps(data))
except WebSocketDisconnect:
websockets.remove(message)
def create_app(debug: bool = False) -> FastAPI:
app = FastAPI(debug=debug)
app.include_router(router)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
return app
这里可以看到我的ReactJS脚本的UseEffect,它试图建立一个WebSocket连接。
useEffect(() => {
const socket = new WebSocket("ws://localhost:8000/api/ws"); // ERROR
socket.onopen = () => {
console.log("WebSocket connection opened");
};
socket.onmessage = (event) => {
const newData = JSON.parse(event.data);
setData(newData);
};
return () => {
socket.close();
};
}, []);
为了提供所有信息,这里是API的配置文件:
events {
worker_connections 1024;
}
http {
server {
listen 8000;
location / {
proxy_pass http://api:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
}
ReactJS应用的.conf文件也运行在Nginx服务器上:
server {
listen 80;
location /api {
proxy_pass http://load_balance:8000;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
然而,我面临着在前端和后端之间建立WebSocket连接的问题。重要的部分是以下内容,我不知道该正确连接到什么:
const socket = new WebSocket("ws://localhost:8000/api/ws");
如何从GUI使用/api
代理连接到FastAPI的WebSocket?或者我如何建立这种联系?
1条答案
按热度按时间gmol16391#
使用load_balance代替localhost:
你也可以使用postman进行WebSocket测试。