Graphql C# 应用程序“无法连接到 websokcet 端点”

问题描述

我一直在尝试获取订阅以在 dotnetcore 3 c# 项目中工作。 尝试创建订阅时

subscription
{appleAdded
    {taste}
}

我收到以下消息“”错误”:“无法连接到 websocket 端点 wss://localhost:44326/graphql。请检查端点 url 是否正确。” }" 在 chrome 调试中查看网络窗格,我可以看到与工作示例相同的 init 和 start 消息,但我自己的模板没有返回 connection_ack。

我遵循了一个示例,但是由于自示例创建以来 graphql 已经发展,因此我自己的模板使用了大多数软件包的较新版本。这些包会在这里和那里强制对代码进行细微的更改,但我想不出任何会破坏订阅功能的效果。我怀疑的是较新的版本会强制我可能缺少的某些设置。作为具有纯后端经验的开发人员,我对 websockets 没有太多的了解,如果我错过了更多的东西来获得一个有效的例子。 我希望有人知道我遗漏了什么,或者可以让我了解我应该寻找什么。

详情:

使用的包是graphqldotnet (3.2) https://github.com/graphql-dotnet/graphql-dotnet 和 graphql 服务器(4.4.0) https://github.com/graphql-dotnet/server

我下面的例子: https://github.com/baskarmib/CodeCamp2019/tree/master/aspnetcoreapp 这家伙还写了一篇博文

我自己的模板 https://github.com/larsbloch/GraphQlDockerTemplate

我的创业班

public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application,visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            // When running IIS we make sure that allowsynchronousIO is set to true as newtonsoft can disable it
            // https://graphql-dotnet.github.io/docs/migrations/migration3/
            services.Configure<IISServerOptions>(options =>
            {
                options.AllowSynchronousIO = true;
            });

            services.AddSingleton<IDocumentExecuter,DocumentExecuter>();
            services.AddSingleton<IDocumentWriter,DocumentWriter>();

            //Types
            services.AddSingleton<AppleType>();
            services.AddSingleton<AppleInputType>();

            //Repositories
            services.AddSingleton<IAppleRepository,AppleRepository>();

            //Schema
            services.AddSingleton<ISchema,GraphQLMySchema>();

            //Query and mutation
            services.AddSingleton<RootQuery>();
            services.AddSingleton<RootMutation>();
            services.AddSingleton<RootSubscription>();
            services
        .AddGraphQL((options,provider) =>
        {
        })
        // Add required services for GraphQL request/response de/serialization
        .AddSystemTextJson() // For .NET Core 3+
        .AddErrorInfoProvider(opt => opt.ExposeExceptionStackTrace = true)
        .AddWebSockets() // Add required services for web socket support
        .AddDataLoader() // Add required services for DataLoader support
        .AddGraphTypes(typeof(GraphQLMySchema)); // Add all IGraphType implementors in assembly which ChatSchema exists 

        }

        public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseWebSockets();
            app.UseGraphQLWebSockets<GraphQLMySchema>("/graphql");
            app.UseMiddleware<GraphQLMiddleware>();
            app.UseGraphQL<GraphQLMySchema,GraphQLHttpMiddleware<GraphQLMySchema>>("/graphql");


            app.UseGraphiQl("/graphql");

            app.UseGraphQLPlayground(new GraphQLPlaygroundOptions
            {
                Path = "/ui/playground",BetaUpdates = true,RequestCredentials = RequestCredentials.Omit,HideTracingResponse = false,EditorCursorShape = EditorCursorShape.Line,EditorTheme = EditorTheme.Dark,EditorFontSize = 14,EditorReuseHeaders = true,EditorFontFamily = "Consolas",PrettierPrintWidth = 80,PrettierTabWidth = 2,PrettierUseTabs = true,SchemaDisableComments = false,SchemaPollingEnabled = true,SchemaPollingEndpointFilter = "*localhost*",SchemaPollingInterval = 50000,Headers = new Dictionary<string,object>
                {
                    ["MyHeader1"] = "MyValue",["MyHeader2"] = 42,},});
            app.UseGraphiQLServer(new GraphiQLOptions
            {
                Path = "/ui/graphiql",GraphQLEndPoint = "/graphql",});
            app.UseGraphQLAltair(new GraphQLAltairOptions
            {
                Path = "/ui/altair",//Headers = new Dictionary<string,string>
                //{
                //  ["X-api-token"] = "130fh9823bd023hd892d0j238dh",//}
            });
        }
    }

我的中间件类

    public class GraphQLMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IDocumentWriter _writer;
        private readonly IDocumentExecuter _executer;

        public GraphQLMiddleware(RequestDelegate next,IDocumentWriter writer,IDocumentExecuter executer)
        {
            _next = next;
            _writer = writer;
            _executer = executer;
        }
        public async Task Invoke(HttpContext context,ISchema schema)
         {
            if (!IsGraphQLRequest(context))
            {
                await _next(context);
                return;
            }

            await ExecuteAsync(context,schema);
        }
        private async Task ExecuteAsync(HttpContext context,ISchema schema)
        {
            var request = await JsonSerializer.DeserializeAsync<GraphQLRequest>
            (
                context.Request.Body,new JsonSerializerOptions { PropertyNameCaseInsensitive = true }
            );
            
            var result = await _executer.ExecuteAsync(options =>
            {
                options.Schema = schema;
                options.Query = request?.Query;
                options.OperationName = request?.OperationName;
                options.Inputs = request.Variables.ToInputs();
                //options.UserContext = _settings.BuildUserContext?.Invoke(context);
                //options.ValidationRules = DocumentValidator.CoreRules;//.Concat(new[] { new InputValidationRule() });
                options.EnableMetrics = true;
                //options.FieldMiddleware.Use<InstrumentFieldsMiddleware>();

            });

            await WriteResponseAsync(context,result);
        }

        private async Task WriteResponseAsync(HttpContext context,ExecutionResult result)
        {
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = result.Errors?.Any() == true ? (int)HttpStatusCode.BadRequest : (int)HttpStatusCode.OK;

            await _writer.WriteAsync(context.Response.Body,result);
        }

        private bool IsGraphQLRequest(HttpContext context)
        {
            var requestPath = context.Request.Path.StartsWithSegments("/graphql");
            var requestMethod = string.Equals(context.Request.Method,"POST",StringComparison.OrdinalIgnoreCase);

            return requestPath && requestMethod;

        }
    }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...