GraphQL.NET Subscriptions not returning anything

1.2k views Asked by At

I have problem with GraphQL.NET and Subscriptions and would like to hear your input.

I am trying to run the following query on https://localhost:5001/graphql

subscription calcRunStatus{
    calcRunStatus {
      billingMonth
      calcRunStatus {description, id, key, name}
      id
      partnerRoles { id }
    }
  }

When I run this query in the GraphQL Playground UI I get the feedback "Listening...". Now when I run the StartCalcRun method I I don't get the CalcRun value returned. It stays on listening forever. If I do the same query in GraphiQL it returns the subscription instantly but with null as a result.

What could be a clue is that my backend is logging the following:

|DEBUG|GraphQL.Server.Transports.WebSockets.GraphQLWebSocketsMiddleware|Request is not a valid websocket request 

I am using ASP.NETCore 3.0

Do you have an idea what could be the problem?

If you need to see more code, let me know!

TESTSubscription.cs

using System;
using System.Reactive.Linq;
using test.backend.Business.Services;
using test.backend.Data.Entities;
using test.backend.GraphQLModels.Types;
using GraphQL.Resolvers;
using GraphQL.Subscription;
using GraphQL.Types;


namespace test.backend.GraphQLModels.Subscription
{
    public class TESTSubscription : ObjectGraphType
    {
        private readonly ICalcRunsService _calcRunsService;

        public TESTSubscription(ICalcRunsService calcRunsService)
        {
            _calcRunsService = calcRunsService;
            Name = nameof(TESTSubscription);

            AddField(new EventStreamFieldType
            {
                Name = "calcRunStatus",
                Type = typeof(CalcRunsType),
                Resolver = new FuncFieldResolver<CalcRuns>(ResolverHandler),
                Subscriber = new EventStreamResolver<CalcRuns>(Subscribe)
            });
        }

        private CalcRuns ResolverHandler(ResolveFieldContext context)
        {
             return context.Source as CalcRuns;
        }

        private IObservable<CalcRuns> Subscribe(ResolveEventStreamContext context)
        {
            return  _calcRunsService.CalcRunsObservable().Where(x => true);
        }
    }
}

iCalcRunsService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading.Tasks;
using test.backend.data;
using test.backend.Data.Entities;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;

namespace test.backend.Business.Services
{
    #region Interface

    public interface ICalcRunsService
    {
        IEnumerable<CalcRuns> GetCalcRuns();
        CalcRuns StartCalcRun(int id);
        IObservable<CalcRuns> CalcRunsObservable();
        void CreateCalcRunEvent(CalcRuns calcRun);

    }

    #endregion

    public class CalcRunsService : ICalcRunsService
    {

        private readonly TESTDBContext _dbContext;
        private readonly ISubject<CalcRuns> _onCalcRunChange = new ReplaySubject<CalcRuns>(1);



        public CalcRunsService(TESTDBContext dbContext)
        {
            _dbContext = dbContext;
        }

        #region Implementation

        public IEnumerable<CalcRuns> GetCalcRuns()
        {
            return _dbContext.CalcRuns.Include(x => x.CalcRunStatus);
        }

        public CalcRuns StartCalcRun(int id)
        {
            CalcRuns calcRuns = _dbContext.CalcRuns.Find(id);
            CreateCalcRunEvent(calcRuns);
            return calcRuns;

        }

        public void CreateCalcRunEvent(CalcRuns calcRun) 
        {
             _onCalcRunChange.OnNext(calcRun);
        }
        public IObservable<CalcRuns> CalcRunsObservable() 
        {
            return _onCalcRunChange.AsObservable();
        }


        #endregion
    }
}

CalcRuns.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace test.backend.Data.Entities
{
    public class CalcRuns
    {
        #region Fields

        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        public CalcRunStatuses CalcRunStatus { get; set; }

        public PartnerRoles PartnerRole { get; set; }

        [StringLength(7)]
        public string BillingMonth { get; set; }

        #endregion

        #region Constructor

        public CalcRuns()
        {

        }

        #endregion
    }
}

ConfigureServiceExtension.cs

---
public static void AddCustomGraphQLServices(this IServiceCollection services)
        {
            // GraphQL services
            services.AddScoped<IServiceProvider>(c => new FuncServiceProvider(type => c.GetRequiredService(type)));
            services.AddGraphQL(options =>
            {
                options.EnableMetrics = true;
                options.ExposeExceptions = false; // false prints message only, true will ToString
                options.UnhandledExceptionDelegate = context =>
                {
                    Console.WriteLine("Error: " + context.OriginalException.Message);
                };
            })
            .AddUserContextBuilder(httpContext => new GraphQLUserContext { User = httpContext.User })
            .AddWebSockets()
            .AddDataLoader()
            .AddGraphTypes(typeof(TESTSchema));
        }
---

Startup.cs

---
public void Configure(IApplicationBuilder app, TESTDBContext dbContext)
        {
            if (HostingEnvironment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseCors("AllowAllOrigins");
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });

            dbContext.EnsureDataSeeding();
            app.UseWebSockets();
            app.UseGraphQLWebSockets<TESTSchema>();
            app.UseGraphQL<TESTSchema>();
            app.UseGraphQLPlayground();
        }
---
0

There are 0 answers