You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

FastAPI/Starlette中websocket.close()方法不支持reason参数问题求助

解决WebSocket.close() 报"unexpected keyword argument 'reason'"的问题

这个报错的根源很直接:Starlette(以及FastAPI基于它实现的WebSocket接口)的WebSocket.close()方法根本不支持reason这个关键字参数——你可能是把它和其他WebSocket库(比如原生的websockets库)的API搞混了,Starlette的封装做了简化,没有暴露这个参数。

要让客户端知道连接被拒绝的具体原因,你可以用下面两种更可靠的方式:

方案一:先发送原因消息再关闭(推荐)

这是兼容性最好的做法,先给客户端主动发送一条文本消息说明拒绝原因,再调用关闭方法:

# 先给客户端发送拒绝原因
await websocket.send_text("Connection refused as session already exists for user")
# 选择更贴合场景的关闭码:1008 代表"Policy Violation"(违反策略),比1000(正常关闭)更合适
await websocket.close(code=1008)

客户端可以在监听消息的回调里收到这条文本,然后处理关闭逻辑,体验更友好。

方案二:手动构造ASGI关闭帧(兼容性差,不推荐)

如果一定要通过WebSocket关闭帧的reason字段传递信息,你需要绕开Starlette的封装,直接构造ASGI的关闭消息。但要注意,很多客户端框架可能不会主动解析这个reason字段,所以这种方式的兼容性不如方案一:

await websocket.send({
    "type": "websocket.close",
    "code": 1008,
    "reason": b"Connection refused as session already exists for user"  # 注意必须是字节串
})

另外补充一句:选择合适的关闭码很重要,比如你的场景是因为用户已有活跃连接而拒绝,用1008(策略违反)比默认的1000(正常关闭)更符合WebSocket协议的语义,客户端也能通过关闭码快速判断关闭类型。

内容的提问来源于stack exchange,提问作者heaVenShaker

火山引擎 最新活动