public static async Task SendMessageAsync(
     this IWebSocketContext context,
     OperationMessage message,
     CancellationToken cancellationToken)
 {
     using (Stream messageStream = message.CreateMessageStream())
     {
         await context.SendMessageAsync(
             messageStream,
             cancellationToken);
     }
 }
Example #2
0
        public static byte[] Serialize(
            this OperationMessage message)
        {
            if (message is KeepConnectionAliveMessage)
            {
                return(_keepConnectionAliveMessage);
            }

            if (message is AcceptConnectionMessage)
            {
                return(_acceptConnectionMessage);
            }

            return(SerializeInternal(message));
        }
Example #3
0
        private static bool TryDeserializeDataStartMessage(
            GraphQLSocketMessage parsedMessage,
            out OperationMessage message)
        {
            if (!parsedMessage.HasPayload)
            {
                message = null;
                return(false);
            }

            IReadOnlyList <GraphQLRequest> batch =
                Utf8GraphQLRequestParser.Parse(parsedMessage.Payload);

            message = new DataStartMessage(parsedMessage.Id, batch[0]);
            return(true);
        }
        private async Task HandleMessageAsync(
            ISocketConnection connection,
            OperationMessage message,
            CancellationToken cancellationToken)
        {
            for (int i = 0; i < _messageHandlers.Length; i++)
            {
                IMessageHandler handler = _messageHandlers[i];
                if (handler.CanHandle(message))
                {
                    await handler.HandleAsync(connection, message, cancellationToken);

                    // the message is handled and we are done.
                    return;
                }
            }

            throw new NotSupportedException("The specified message type is not supported.");
        }
Example #5
0
        private static Stream CreateMessageStream(
            this OperationMessage message,
            bool largeMessage)
        {
            if (message is DataStartMessage dataStart)
            {
                string query = QuerySyntaxSerializer.Serialize(
                    dataStart.Payload.Query);

                var payload = new Dictionary <string, object>
                {
                    { "query", query },
                };

                if (dataStart.Payload.QueryName != null)
                {
                    payload["namedQuery"] = dataStart.Payload.QueryName;
                }

                if (dataStart.Payload.OperationName != null)
                {
                    payload["operationName"] = dataStart.Payload.OperationName;
                }

                if (dataStart.Payload.Variables != null)
                {
                    payload["variables"] = dataStart.Payload.Variables;
                }

                message = new HelperOperationMessage(
                    dataStart.Type, dataStart.Id, payload);
            }

            string json = JsonConvert.SerializeObject(message, _settings);

            if (largeMessage)
            {
                json += new string(' ', 1024 * 16);
            }
            return(new MemoryStream(Encoding.UTF8.GetBytes(json)));
        }
Example #6
0
        public static async Task SendMessageAsync(
            this WebSocket webSocket,
            OperationMessage message,
            bool largeMessage = false)
        {
            var buffer = new byte[_maxMessageSize];

            await using Stream stream = message.CreateMessageStream(largeMessage);
            int read;

            do
            {
                read = stream.Read(buffer, 0, buffer.Length);
                var segment        = new ArraySegment <byte>(buffer, 0, read);
                var isEndOfMessage = stream.Position == stream.Length;

                await webSocket.SendAsync(
                    segment, WebSocketMessageType.Text,
                    isEndOfMessage, CancellationToken.None);
            } while (read == _maxMessageSize);
        }
        public static async Task SendMessageAsync(
            this IWebSocketContext context,
            OperationMessage message,
            CancellationToken cancellationToken)
        {
            var buffer = new byte[_maxMessageSize];

            using (Stream stream = message.CreateMessageStream())
            {
                int read = 0;
                do
                {
                    read = stream.Read(buffer, 0, buffer.Length);
                    var  segment        = new ArraySegment <byte>(buffer, 0, read);
                    bool isEndOfMessage = stream.Position == stream.Length;

                    await context.WebSocket.SendAsync(
                        segment, WebSocketMessageType.Text,
                        isEndOfMessage, cancellationToken);
                } while (read == _maxMessageSize);
            }
        }
Example #8
0
        private static Stream CreateMessageStream(this OperationMessage message)
        {
            string json = JsonConvert.SerializeObject(message, _settings);

            return(new MemoryStream(Encoding.UTF8.GetBytes(json)));
        }
Example #9
0
        private static bool TryParseMessage(
            ReadOnlySequence <byte> slice,
            out OperationMessage message)
        {
            ReadOnlySpan <byte> messageData;

            byte[] buffer = null;

            if (slice.IsSingleSegment)
            {
                messageData = slice.First.Span;
            }
            else
            {
                buffer = ArrayPool <byte> .Shared.Rent(1024 * 4);

                int buffered = 0;

                SequencePosition      position = slice.Start;
                ReadOnlyMemory <byte> memory;

                while (slice.TryGet(ref position, out memory, true))
                {
                    ReadOnlySpan <byte> span = memory.Span;
                    var bytesRemaining       = buffer.Length - buffered;

                    if (span.Length > bytesRemaining)
                    {
                        var next = ArrayPool <byte> .Shared.Rent(
                            buffer.Length * 2);

                        Buffer.BlockCopy(buffer, 0, next, 0, buffer.Length);
                        ArrayPool <byte> .Shared.Return(buffer);

                        buffer = next;
                    }

                    for (int i = 0; i < span.Length; i++)
                    {
                        buffer[buffered++] = span[i];
                    }
                }

                messageData = buffer;
                messageData = messageData.Slice(0, buffered);
            }

            try
            {
                if (messageData.Length == 0 ||
                    (messageData.Length == 1 && messageData[0] == default))
                {
                    message = null;
                    return(false);
                }

                GraphQLSocketMessage parsedMessage =
                    Utf8GraphQLRequestParser.ParseMessage(messageData);
                return(TryDeserializeMessage(parsedMessage, out message));
            }
            catch (SyntaxException)
            {
                message = null;
                return(false);
            }
            finally
            {
                if (buffer != null)
                {
                    ArrayPool <byte> .Shared.Return(buffer);
                }
            }
        }
 public static Task SendAsync(
     this ISocketConnection connection,
     OperationMessage message,
     CancellationToken cancellationToken) =>
 connection.SendAsync(message.Serialize(), cancellationToken);
Example #11
0
 private static byte[] SerializeInternal(OperationMessage message)
 {
     return(Encoding.GetBytes(
                JsonConvert.SerializeObject(message, JsonSettings)));
 }