我对 GraphQL.NET 和订阅有疑问,想听听您的意见。
我正在尝试在https://localhost:5001/graphql上运行以下查询
subscription calcRunStatus{
calcRunStatus {
billingMonth
calcRunStatus {description, id, key, name}
id
partnerRoles { id }
}
}
当我在 GraphQL Playground UI 中运行此查询时,我收到反馈“正在听...”。现在,当我运行StartCalcRun方法 II 时,不会返回 CalcRun 值。它一直在听。如果我在 GraphiQL 中执行相同的查询,它会立即返回订阅,但结果为 null。
可能的线索是我的后端正在记录以下内容:
|DEBUG|GraphQL.Server.Transports.WebSockets.GraphQLWebSocketsMiddleware|Request is not a valid websocket request
我正在使用 ASP.NETCore 3.0
你知道可能是什么问题吗?
如果您需要查看更多代码,请告诉我!
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
}
}
配置服务扩展.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));
}
---
启动.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();
}
---