.Net6 + GraphQL + MongoDb 实现Subscription监听功能

介绍

查询、添加、修改我们已经演示了,我们来看下订阅。

订阅大家可以理解为音乐软件, 我们用户 => 订阅音乐频道 <= 服务发送新的音乐通知到频道。 有新的通知进入频道后,频道会推送给客户。

这个东西就和Rxjs一样,在Angular客户端用起来也是一个效果。

正文

修改PostMutation.cs新增接口

    public async Task<AddPostPayload> PublishPost(
            [Service] DbContext db,
            [Service]ITopicEventSender sender,
            AddPostInput input,
            CancellationToken cancellationToken)
        {
            var entity = new Post()
            {
                Title = input.Title,
                Abstraction = "this is an introduction post for graphql",
                Content = "some random content for post 1",
                Author = input.Author,
                PublishedAt = DateTime.Now.AddDays(-2),
                Link = "http://link-to-post-1.html",
                Comments = new List<Comment>
                {
                    new() { CreatedAt = DateTime.Now, Content = "test  comment 03 for post 1", Name = "kindUser02" }
                },
            };

            // await db.Post.InsertOneAsync(entity, cancellationToken: cancellationToken);

            await sender.SendAsync(nameof(PublishPost), entity, cancellationToken);

            return new AddPostPayload(entity);
        }

新建PostSubscription文件

        [Subscribe]
        [Topic(nameof(PostMutation.PublishPost))]
        public Post OnPublishedPost(
            [EventMessage] Post publishedPost)
        {
            return publishedPost;
        }

修改Program

builder.Services
    .AddGraphQLServer()
    .AddQueryType<PostQuery>()
    .AddMutationType<PostMutation>()
    .AddSubscriptionType<PostSubscription>()
    .AddInMemorySubscriptions()
    .AddMongoDbFiltering()
    .AddMongoDbSorting()
    .AddMongoDbProjections()
    .AddMongoDbPagingProviders()
    .SetPagingOptions(new PagingOptions
    {
        MaxPageSize = 50,
        IncludeTotalCount = true
    });




var app = builder.Build();

app.UseHttpsRedirection();

app.UseWebSockets();

app.UseRouting().UseEndpoints(endpoints =>
{
    endpoints.MapGraphQL();
});

app.UseGraphQLVoyager("/graphql-voyager", new VoyagerOptions { GraphQLEndPoint = "/graphql" });

这时候我们去https://localhost:7145/graphql/调用接口,打开2个页面,

A页面调用subscription publishedPost,调用后客户端会进入订阅状态,等待消息

B页面调用mutation publishPost,发送消息

mutation publishPost {
  publishPost(input: { title:"titl2222e test", author:" author test "}) {
    post {
      id
    }
  }
}

subscription publishedPost {
   onPublishedPost {
     id
     title
   } 
}
高级用法

修改PostSubscription.cs

        [Subscribe(With = nameof(OnPublishedStream))]
        //[Subscribe]
        //[Topic(nameof(PostMutation.PublishPost))]
        public Post OnPublishedPost(
            [EventMessage] Post publishedPost)
        {
            return publishedPost;
        }

        public async IAsyncEnumerable<Post> OnPublishedStream(
            [Service] ITopicEventReceiver eventReceiver, [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            var sourceStream =
                await eventReceiver.SubscribeAsync<string, Post>(nameof(PostMutation.PublishPost), cancellationToken);

            // 这里理解为去请求数据库拿历史消息
            yield return new Post()
            {
                Title = "subscription Title",
                Abstraction = "this is an introduction post for graphql",
                Content = "some random content for post 1",
                Author = "subscription Author",
                PublishedAt = DateTime.Now.AddDays(-2),
                Link = "http://link-to-post-1.html",
                Comments = new List<Comment>
                {
                    new() { CreatedAt = DateTime.Now, Content = "test  comment 03 for post 1", Name = "kindUser02" }
                },
            };


            await Task.Delay(5000, cancellationToken);

            await foreach (Post post in sourceStream.ReadEventsAsync())
            {
                yield return post;
            }
        }

这时候我们去https://localhost:7145/graphql/调用接口,打开2个页面,

A页面调用subscription publishedPost,调用后客户端会立马收到消息subscription Title这个是等于是历史消息,然后会继续保持订阅状态。当mutation publishPost调用后会收到发送的消息

B页面调用mutation publishPost,发送消息。

mutation publishPost {
  publishPost(input: { title:"titl2222e test", author:" author test "}) {
    post {
      id
    }
  }
}

subscription publishedPost {
   onPublishedPost {
     id
     title
   } 
}

结语

本系列主要将GraphQL的使用,示例项目不能应用于生产,后续发一些GraphQL库出来讲解生产中的实际应用

联系作者:加群:867095512 @MrChuJiu

posted @ 2023-02-16 13:18  初久的私房菜  阅读(11478)  评论(0编辑  收藏  举报
作者:初久的私房菜
好好学习,天天向上
返回顶部小火箭
好友榜:
如果愿意,把你的博客地址放这里
张弛:https://blog.zhangchi.fun/