GraphQL .NET Core 中的订阅不向客户端发送响应

如何解决GraphQL .NET Core 中的订阅不向客户端发送响应

我正在 Asp Net Core 3.1 中构建 GraphQL API。我正在尝试添加一个 订阅,以便在添加新实体时向订阅者发送新实体。 当我从 /ui/playground 执行订阅时,与服务器的握手似乎成功了:

GraphQL http 请求 websocket:

GraphQL http request websocket - img

当我执行添加评论的突变时,它成功并在数据库上创建了一条记录,但上面的屏幕仍然如此,没有更新,没有从套接字接收到数据。

这是突变:

Field<ReviewType>(
    "createReview",arguments: new QueryArguments(
        new QueryArgument<NonNullGraphType<ReviewInput>> 
        { 
            Name = "reviewInput"
        }
    ),resolve: context =>
    {
        var review = context.GetArgument<Review>("reviewInput");
        var rev = reviewService.Add(review);
        return rev;
    }
);

ShopSubscrition.cs

public partial class ShopSubscription : ObjectGraphType
{
    private readonly IReviewService _reviewService;

    public ShopSubscription(IReviewService reviewService)
    {
        _reviewService = reviewService;
        AddField(new EventStreamFieldType
        {
            Name = "reviewAdded",Type = typeof(ReviewType),Resolver = new FuncFieldResolver<Review>((context) => context.source as Review),Subscriber = new EventStreamResolver<Review>((context) => _reviewService.ReviewAdded())
        });
    }
}

ReviewService.cs

public class ReviewService : IReviewService
{
    private readonly IReviewRepository _reviewRepository;
    private readonly ISubject<Review> _sub = new ReplaySubject<Review>(1);

    public ReviewService(IReviewRepository reviewRepository)
    {
        _reviewRepository = reviewRepository;
    }

    public Review Add(Review review)
    {
        var addedEntity = _reviewRepository.Add(review);
        _sub.OnNext(review);
        return review;
    }

    public IObservable<Review> ReviewAdded()
    {
        return _sub.AsObservable();
    }
}

我也发布了 Startup.cs,也许它会有所帮助。

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors();

        services.AddDbContext<ShopDbContext>(opt =>
            opt.UsesqlServer(Configuration.GetConnectionString("Default")));

        services.AddScoped<IsupplierRepository,supplierRepository>();
        services.AddScoped<IProductRepository,ProductRepository>();
        services.AddScoped<IReviewRepository,ReviewRepository>();

        services.AddScoped<IReviewService,ReviewService>();

        services.AddSingleton<IDataLoaderContextAccessor,DataLoaderContextAccessor>();
        services.AddSingleton<DataLoaderDocumentListener>();

        services.AddScoped<ShopSchema>();
        services.AddGraphQL(options =>
        {
            options.EnableMetrics = false;
        })
            .AddWebSockets()
            .AddSystemTextJson()
            .AddGraphTypes(typeof(ShopSchema),ServiceLifetime.Scoped).AddDataLoader();

        services.AddControllers()
            .AddNewtonsoftJson(o => o.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
    }

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

        app.UseCors("Cors");
        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseAuthorization();
        app.UseWebSockets();
        app.UseGraphQLWebSockets<ShopSchema>("/graphql");

        app.UseGraphQL<ShopSchema>();
        app.UseGraphQLPlayground(options: new GraphQLPlaygroundOptions { GraphQLEndPoint ="/graphql",SchemaPollingEnabled = false });

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

预先感谢您的帮助。

解决方法

经过深入调查后,我发现了问题所在。我发布了解决方案,也许可以帮助某人。

问题是关于依赖注入:包含订阅“通知逻辑”的类(在我的例子中是 ReviewService.cs)必须注册为 Singleton 而不是 Scoped。这引起了一种连锁反应,使存储库类注册为 Transient。 这是工作代码:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddCors(options => options.AddPolicy("Cors",builder =>
            {
                builder.AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader();
            }));

        services.AddDbContext<ShopDbContext>(opt =>
            opt.UseSqlServer(Configuration.GetConnectionString("Default")));

        services.AddTransient<ISupplierRepository,SupplierRepository>();
        services.AddTransient<IProductRepository,ProductRepository>();
        services.AddTransient<IReviewRepository,ReviewRepository>();

        services.AddSingleton<IReviewService,ReviewService>();

        services.AddSingleton<IDataLoaderContextAccessor,DataLoaderContextAccessor>();
        services.AddSingleton<DataLoaderDocumentListener>();

        services.AddScoped<ShopSchema>();
        services.AddGraphQL(options =>
        {
            options.EnableMetrics = false;  // info sulla richiesta (ms,campi richiesti,ecc)
        })
            .AddWebSockets()
            .AddSystemTextJson()
            .AddGraphTypes(typeof(ShopSchema),ServiceLifetime.Scoped).AddDataLoader();

        services.AddControllers()
            .AddNewtonsoftJson(o => o.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
    }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?