private static bool TryDeserializeMessage( GraphQLSocketMessage parsedMessage, out OperationMessage message) { switch (parsedMessage.Type) { case MessageTypes.Connection.Initialize: message = DeserializeInitConnMessage( parsedMessage); return(true); case MessageTypes.Connection.Terminate: message = TerminateConnectionMessage.Default; return(true); case MessageTypes.Subscription.Start: return(TryDeserializeDataStartMessage( parsedMessage, out message)); case MessageTypes.Subscription.Stop: message = DeserializeDataStopMessage(parsedMessage); return(true); default: message = null; return(false); } }
private static DataCompleteMessage DeserializeSubscriptionCompleteMessage( GraphQLSocketMessage parsedMessage) { if (parsedMessage.Id is null) { // TODO : resources throw new InvalidOperationException("Invalid message structure."); } return(new DataCompleteMessage(parsedMessage.Id)); }
private static DataStopMessage DeserializeDataStopMessage( GraphQLSocketMessage parsedMessage) { if (parsedMessage.Payload.Length > 0 || parsedMessage.Id is null) { throw new InvalidOperationException("Invalid message structure."); } return(new DataStopMessage(parsedMessage.Id)); }
private static InitializeConnectionMessage DeserializeInitConnMessage( GraphQLSocketMessage parsedMessage) { if (parsedMessage.HasPayload) { object parsed = Utf8GraphQLRequestParser.ParseJson( parsedMessage.Payload); if (parsed is IReadOnlyDictionary <string, object> payload) { return(new InitializeConnectionMessage(payload)); } } return(new InitializeConnectionMessage(null)); }
private static bool TryDeserializeDataStartMessage( GraphQLSocketMessage parsedMessage, [NotNullWhen(true)] out OperationMessage?message) { if (parsedMessage.Payload.Length == 0 || parsedMessage.Id is null) { message = null; return(false); } IReadOnlyList <GraphQLRequest> batch = Parse(parsedMessage.Payload); message = new DataStartMessage(parsedMessage.Id, batch[0]); return(true); }
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 OperationMessage DeserializeMessage(GraphQLSocketMessage parsedMessage) { switch (parsedMessage.Type) { // case MessageTypes.Connection.Error: case MessageTypes.Connection.Accept: return(AcceptConnectionMessage.Default); case MessageTypes.Subscription.Data: return(DeserializeSubscriptionResultMessage(parsedMessage)); // case MessageTypes.Subscription.Error: case MessageTypes.Subscription.Complete: return(DeserializeSubscriptionCompleteMessage(parsedMessage)); default: return(KeepConnectionAliveMessage.Default); } }
private OperationMessage DeserializeSubscriptionResultMessage( GraphQLSocketMessage parsedMessage) { if (parsedMessage.Id is null || !parsedMessage.HasPayload) { // TODO : resources throw new InvalidOperationException("Invalid message structure."); } if (_subscriptionManager.TryGetSubscription( parsedMessage.Id, out ISubscription? subscription)) { IResultParser parser = subscription !.ResultParser; OperationResultBuilder resultBuilder = OperationResultBuilder.New(parser.ResultType); parser.Parse(parsedMessage.Payload, resultBuilder); return(new DataResultMessage(parsedMessage.Id, resultBuilder)); } return(KeepConnectionAliveMessage.Default); }
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); } } }
private static bool TryParseMessage( ReadOnlySequence <byte> slice, [NotNullWhen(true)] out OperationMessage?message) { ReadOnlySpan <byte> messageData; byte[]? buffer = null; if (slice.IsSingleSegment) { messageData = slice.First.Span; } else { buffer = ArrayPool <byte> .Shared.Rent(1024 * 4); var buffered = 0; SequencePosition position = slice.Start; while (slice.TryGet(ref position, out ReadOnlyMemory <byte> memory)) { ReadOnlySpan <byte> span = memory.Span; var bytesRemaining = buffer.Length - buffered; if (span.Length > bytesRemaining) { // TODO : we need to ensure that the message size is restricted like on the // http request. byte[] next = ArrayPool <byte> .Shared.Rent(buffer.Length * 2); Buffer.BlockCopy(buffer, 0, next, 0, buffer.Length); ArrayPool <byte> .Shared.Return(buffer); buffer = next; } for (var 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 = ParseMessage(messageData); return(TryDeserializeMessage(parsedMessage, out message)); } catch (SyntaxException) { message = null; return(false); } finally { if (buffer is not null) { ArrayPool <byte> .Shared.Return(buffer); } } }
private static InitializeConnectionMessage DeserializeInitConnMessage( GraphQLSocketMessage parsedMessage) => parsedMessage.Payload.Length > 0 && ParseJson(parsedMessage.Payload) is IReadOnlyDictionary <string, object?> payload
public bool TryParseMessage( ReadOnlySequence <byte> slice, out OperationMessage?message) { ReadOnlySpan <byte> messageData; byte[] buffer = Array.Empty <byte>(); if (slice.IsSingleSegment) { messageData = slice.First.Span; } else { buffer = ArrayPool <byte> .Shared.Rent(_initialBufferSize); var buffered = 0; SequencePosition position = slice.Start; while (slice.TryGet(ref position, out ReadOnlyMemory <byte> memory)) { ReadOnlySpan <byte> span = memory.Span; var bytesRemaining = buffer.Length - buffered; if (span.Length > bytesRemaining) { byte[] next = ArrayPool <byte> .Shared.Rent(buffer.Length * 2); Buffer.BlockCopy(buffer, 0, next, 0, buffer.Length); ArrayPool <byte> .Shared.Return(buffer); buffer = next; } span.CopyTo(buffer.AsSpan().Slice(buffered)); } messageData = buffer; messageData = messageData.Slice(0, buffered); } try { if (messageData.Length == 0 || (messageData.Length == 1 && messageData[0] == default)) { message = null; return(false); } GraphQLSocketMessage parsedMessage = ParseMessage(messageData); message = DeserializeMessage(parsedMessage); return(true); } catch (SyntaxException) { message = null; return(false); } finally { if (buffer.Length > 0) { ArrayPool <byte> .Shared.Return(buffer); } } }