在Godot C#中使用GraphQL.Client消费GraphQL订阅失败求助
问题分析与解决方案
你的问题核心是协议不匹配:后端用的是subscription-transport-ws(基于WebSocket的GraphQL订阅协议),但你当前用的GraphQL.Client默认采用SSE(Server-Sent Events)处理订阅,两种协议不兼容,导致连接失败。Altair能正常使用是因为它自动适配了WebSocket协议的订阅端点。
解决步骤:
1. 安装WebSocket订阅依赖
给你的Godot C#项目安装GraphQL.Client.Websocket.Subscriptions NuGet包,这个包专门处理基于WebSocket的GraphQL订阅。
2. 替换客户端实例
不要用普通的GraphQLHttpClient,改用GraphQLWebSocketClient连接后端的WebSocket订阅端点。注意URL要改成ws://或wss://开头(对应HTTP/HTTPS),比如后端地址是http://localhost:3000/graphql,那WebSocket地址就是ws://localhost:3000/graphql(NestJS的GraphQL通常复用同一个端点处理HTTP和WebSocket请求)。
3. 修改订阅代码
调整后的代码示例:
// 创建WebSocket客户端实例 var webSocketClient = new GraphQLWebSocketClient( new Uri("ws://localhost:3000/graphql"), // 替换成你的后端WebSocket端点 new NewtonsoftJsonSerializer()); // 保持和Mutation使用的序列化器一致 // 定义订阅请求 var userJoinedRequest = new GraphQLRequest { Query = @" subscription { userJoined{ displayName id } }" }; // 先打开WebSocket连接 await webSocketClient.InitializeWebSocketConnectionAsync(); // 创建订阅流 var subscriptionStream = webSocketClient.CreateSubscriptionStream<UserJoinedSubscriptionResult>(userJoinedRequest); // 订阅流,Godot中日志操作需在主线程,用CallDeferred处理 var subscription = subscriptionStream.Subscribe( response => { if (response.Data?.UserJoined != null) { GD.Print($"user {response.Data.UserJoined.DisplayName} joined"); } }, error => { GD.PrintErr($"订阅错误: {error.Message}"); }, () => { GD.Print("订阅已结束"); } ); // 节点销毁时记得清理资源 // subscription.Dispose(); // await webSocketClient.CloseWebSocketConnectionAsync();
额外注意事项:
- 确认后端WebSocket端点和Altair中使用的一致,比如Altair填的是
ws://localhost:3000/graphql,客户端也要用这个地址。 - Godot中异步操作需注意线程问题,比如
_Ready方法要改成async void _Ready()才能使用await。 - 确保
UserJoinedSubscriptionResult类结构和后端返回字段匹配:
public class UserJoinedSubscriptionResult { public UserJoined UserJoined { get; set; } } public class UserJoined { public string DisplayName { get; set; } public string Id { get; set; } }
内容的提问来源于stack exchange,提问作者thealiraza
相关产品推荐
相关产品推荐

