コード例 #1
0
 private Task WriteConnectionAckAsync(OperationMessageContext context)
 {
     return(context.MessageWriter.WriteMessageAsync(new OperationMessage
     {
         Type = MessageTypes.GQL_CONNECTION_ACK
     }));
 }
コード例 #2
0
        protected async Task HandleStartAsync(OperationMessageContext context)
        {
            var query  = context.Op.Payload.ToObject <GraphQuery>();
            var result = await SubscribeAsync(query).ConfigureAwait(false);

            await AddSubscription(context, result).ConfigureAwait(false);

            _log.LogInformation($"Subscription: {context.Op.Id} started");
        }
コード例 #3
0
 protected async Task HandleStopAsync(OperationMessageContext context)
 {
     if (Subscriptions.TryGetValue(context.ConnectionId, out var subscriptions))
     {
         if (subscriptions.TryRemove(context.Op.Id, out var subscriptionHandle))
         {
             await subscriptionHandle.CloseAsync();
         }
     }
 }
コード例 #4
0
        protected async Task HandleTerminateAsync(OperationMessageContext context)
        {
            if (Subscriptions.TryRemove(context.ConnectionId, out var subscriptions))
            {
                foreach (var subscription in subscriptions.Values)
                {
                    await subscription.CloseAsync();
                }

                subscriptions.Clear();
            }
        }
コード例 #5
0
        protected async Task HandleStartAsync(OperationMessageContext context)
        {
            var payload   = context.Op.Payload;
            var query     = payload is GraphQLQuery ? payload : context.Op.Payload.ToObject <GraphQLQuery>();
            var options   = context.Connection.Options;
            var exOptions = new ExecutionOptions
            {
                Schema           = _schema,
                OperationName    = query.OperationName,
                Inputs           = query.GetInputs(),
                Query            = query.Query,
                ExposeExceptions = options?.ExposeExceptions ?? false,
                ValidationRules  = options?.ValidationRules,
                UserContext      = options?.BuildUserContext?.Invoke(context)
            };

            var isSubscription = _determinator.IsSubscription(exOptions);

            if (isSubscription)
            {
                var result = await SubscribeAsync(exOptions).ConfigureAwait(false);

                await AddSubscription(context, result).ConfigureAwait(false);

                _log.LogInformation($"Subscription: {context.Op.Id} started");
            }
            else
            {
                var result = await ExecuteAsync(exOptions).ConfigureAwait(false);

                _log.LogInformation($"Subscription: {context.Op.Id} started");
                await context.MessageWriter.WriteMessageAsync(new OperationMessage
                {
                    Type    = MessageTypes.GQL_DATA,
                    Id      = context.Op.Id,
                    Payload = result
                });

                await context.MessageWriter.WriteMessageAsync(new OperationMessage
                {
                    Type = MessageTypes.GQL_COMPLETE,
                    Id   = context.Op.Id
                });

                _log.LogInformation($"Subscription: {context.Op.Id} completed");
            }
        }
コード例 #6
0
        private async Task WriteOperationErrorsAsync(OperationMessageContext context,
                                                     IEnumerable <ExecutionError> errors)
        {
            var error = errors?.FirstOrDefault();

            await context.MessageWriter.WriteMessageAsync(
                new OperationMessage
            {
                Type    = MessageTypes.GQL_ERROR,
                Id      = context.Op.Id,
                Payload = new
                {
                    message   = error?.Message,
                    locations = error?.Locations
                }
            }).ConfigureAwait(false);
        }
コード例 #7
0
        public Task HandleMessageAsync(OperationMessageContext context)
        {
            switch (context.Op.Type)
            {
            case MessageTypes.GQL_CONNECTION_INIT:
                return(HandleConnectionInitAsync(context));

            case MessageTypes.GQL_START:
                return(HandleStartAsync(context));

            case MessageTypes.GQL_STOP:
                return(HandleStopAsync(context));

            case MessageTypes.GQL_CONNECTION_TERMINATE:
                return(HandleTerminateAsync(context));

            default: return(Task.CompletedTask);
            }
        }
コード例 #8
0
        public Task HandleMessageAsync(OperationMessageContext context)
        {
            _log.LogDebug($"Subscription: {context.Op.Id} received message of type {context.Op.Type}");
            switch (context.Op.Type)
            {
            case MessageTypes.GQL_CONNECTION_INIT:
                return(HandleConnectionInitAsync(context));

            case MessageTypes.GQL_START:
                return(HandleStartAsync(context));

            case MessageTypes.GQL_STOP:
                return(HandleStopAsync(context));

            case MessageTypes.GQL_CONNECTION_TERMINATE:
                return(HandleTerminateAsync(context));

            default: return(Task.CompletedTask);
            }
        }
コード例 #9
0
        public async Task AddSubscription(OperationMessageContext context, SubscriptionExecutionResult result)
        {
            if (result.Errors?.Any() == true)
            {
                await WriteOperationErrorsAsync(context, result.Errors).ConfigureAwait(false);

                return;
            }

            if (result.Streams == null || !result.Streams.Any())
            {
                await WriteOperationErrorsAsync(context, new[]
                {
                    new ExecutionError(
                        $"Could not resolve subsciption stream for {context.Op}")
                }).ConfigureAwait(false);

                return;
            }

            var stream = result.Streams.Values.Single();

            Subscriptions.AddOrUpdate(context.ConnectionId, connectionId =>
            {
                var subscriptions = new ConcurrentDictionary <string, SubscriptionHandle>();

                subscriptions.TryAdd(context.Op.Id,
                                     new SubscriptionHandle(context.Op, stream, context.MessageWriter, new DocumentWriter()));

                return(subscriptions);
            }, (connectionId, subscriptions) =>
            {
                subscriptions.TryAdd(context.Op.Id,
                                     new SubscriptionHandle(context.Op, stream, context.MessageWriter, new DocumentWriter()));

                return(subscriptions);
            });
        }
コード例 #10
0
 /// <inheritdoc />
 public Task HandleConnectionClosed(OperationMessageContext context)
 {
     return(HandleTerminateAsync(context));
 }
コード例 #11
0
 protected Task HandleConnectionInitAsync(OperationMessageContext context)
 {
     _log.LogInformation($"Acknowleding GraphQL connection: {context.ConnectionId}");
     return(WriteConnectionAckAsync(context));
 }
コード例 #12
0
        private Task <SubscriptionExecutionResult> SubscribeAsync(GraphQLQuery query, OperationMessageContext op)
        {
            var options = op.Connection.Options;

            return(_subscriptionExecuter.SubscribeAsync(new ExecutionOptions
            {
                Schema = _schema,
                OperationName = query.OperationName,
                Inputs = query.GetInputs(),
                Query = query.Query,
                UserContext = options?.BuildUserContext?.Invoke(op)
            }));
        }