使用Python websockets实现Hasura GraphQL订阅时遇子协议不支持错误
解决websockets连接Hasura GraphQL时的"no subprotocols supported"错误
这个错误的核心原因很明确:Hasura的GraphQL WebSocket服务要求客户端必须指定graphql-ws子协议才能完成握手,而你当前的连接代码缺少这个关键参数。
第一步:添加子协议参数
修改你的连接代码,在websockets.connect中加入subprotocols=["graphql-ws"],这是让Hasura识别并接受WebSocket连接的必要条件:
async def user_listener(): headers = {'Content-Type': 'application/json', 'x-hasura-access-key': 'mysecretkey'} uri = "ws://localhost:8080/v1alpha1/graphql" # 新增subprotocols参数指定GraphQL WebSocket子协议 async with websockets.connect(uri, extra_headers=headers, subprotocols=["graphql-ws"]) as websocket: await websocket.send(subscription.render()) while True: greeting = await websocket.recv() print(f"< {greeting}")
第二步:修正订阅消息格式
另外要注意,Hasura遵循GraphQL WebSocket协议(subscriptions-transport-ws),要求发送的消息必须是符合规范的JSON结构,而不是直接发送订阅字符串。你当前的Template渲染后只是纯订阅查询,需要包装成包含type、id、payload的结构:
from string import Template # 调整模板为符合GraphQL WebSocket协议的JSON格式 subscription = Template(''' { "type": "start", "id": "1", "payload": { "query": "subscription { users { id name } }" } } ''')
如果不做这个调整,即使连接成功,你也无法收到Hasura推送的订阅更新。
额外检查项
- 确认你的Hasura端点是否正确:
v1alpha1是旧版本的WebSocket端点,如果你使用的是Hasura v2.x及以上版本,端点应该是ws://localhost:8080/v1/graphql - 验证
x-hasura-access-key是否和Docker Compose中Hasura配置的HASURA_GRAPHQL_ADMIN_SECRET一致 - 确保Docker Compose中的Hasura容器正常运行,WebSocket服务默认是开启的,无需额外配置
内容的提问来源于stack exchange,提问作者vishpat
相关产品推荐
相关产品推荐

