private CancelInvocationMessage BindCancelInvocationMessage(JObject json) { var invocationId = JsonUtils.GetRequiredProperty <string>(json, InvocationIdPropertyName, JTokenType.String); var metadata = JsonUtils.GetOptionalMetadataDictionary(json, MetadataPropertyName); return(new CancelInvocationMessage(invocationId, metadata)); }
private InvocationMessage BindInvocationMessage(JObject json, IInvocationBinder binder) { var invocationId = JsonUtils.GetRequiredProperty <string>(json, InvocationIdPropertyName, JTokenType.String); var target = JsonUtils.GetRequiredProperty <string>(json, TargetPropertyName, JTokenType.String); var nonBlocking = JsonUtils.GetOptionalProperty <bool>(json, NonBlockingPropertyName, JTokenType.Boolean); var args = JsonUtils.GetRequiredProperty <JArray>(json, ArgumentsPropertyName, JTokenType.Array); var paramTypes = binder.GetParameterTypes(target); var arguments = new object[args.Count]; if (paramTypes.Length != arguments.Length) { throw new FormatException($"Invocation provides {arguments.Length} argument(s) but target expects {paramTypes.Length}."); } for (var i = 0; i < paramTypes.Length; i++) { var paramType = paramTypes[i]; // TODO(anurse): We can add some DI magic here to allow users to provide their own serialization // Related Bug: https://github.com/aspnet/SignalR/issues/261 arguments[i] = args[i].ToObject(paramType, _payloadSerializer); } return(new InvocationMessage(invocationId, nonBlocking, target, arguments)); }
private CancelInvocationMessage BindCancelInvocationMessage(JObject json) { var invocationId = JsonUtils.GetRequiredProperty <string>(json, InvocationIdPropertyName, JTokenType.String); var message = new CancelInvocationMessage(invocationId); ReadHeaders(json, message.Headers); return(message); }
private StreamItemMessage BindStreamItemMessage(JObject json, IInvocationBinder binder) { var invocationId = JsonUtils.GetRequiredProperty <string>(json, InvocationIdPropertyName, JTokenType.String); var result = JsonUtils.GetRequiredProperty <JToken>(json, ItemPropertyName); var returnType = binder.GetReturnType(invocationId); return(new StreamItemMessage(invocationId, result?.ToObject(returnType, _payloadSerializer))); }
private HubMessage ParseMessage(Stream input, IInvocationBinder binder) { using (var reader = new JsonTextReader(new StreamReader(input))) { try { // PERF: Could probably use the JsonTextReader directly for better perf and fewer allocations var token = JToken.ReadFrom(reader); if (token == null || token.Type != JTokenType.Object) { throw new InvalidDataException($"Unexpected JSON Token Type '{token?.Type}'. Expected a JSON Object."); } var json = (JObject)token; // Determine the type of the message var type = JsonUtils.GetRequiredProperty <int>(json, TypePropertyName, JTokenType.Integer); switch (type) { case HubProtocolConstants.InvocationMessageType: return(BindInvocationMessage(json, binder)); case HubProtocolConstants.StreamInvocationMessageType: return(BindStreamInvocationMessage(json, binder)); case HubProtocolConstants.StreamItemMessageType: return(BindStreamItemMessage(json, binder)); case HubProtocolConstants.CompletionMessageType: return(BindCompletionMessage(json, binder)); case HubProtocolConstants.CancelInvocationMessageType: return(BindCancelInvocationMessage(json)); case HubProtocolConstants.PingMessageType: return(PingMessage.Instance); default: throw new InvalidDataException($"Unknown message type: {type}"); } } catch (JsonReaderException jrex) { throw new InvalidDataException("Error reading JSON.", jrex); } } }
private StreamInvocationMessage BindStreamInvocationMessage(JObject json, IInvocationBinder binder) { var invocationId = JsonUtils.GetRequiredProperty <string>(json, InvocationIdPropertyName, JTokenType.String); var target = JsonUtils.GetRequiredProperty <string>(json, TargetPropertyName, JTokenType.String); var args = JsonUtils.GetRequiredProperty <JArray>(json, ArgumentsPropertyName, JTokenType.Array); var paramTypes = binder.GetParameterTypes(target); try { var arguments = BindArguments(args, paramTypes); return(new StreamInvocationMessage(invocationId, target, argumentBindingException: null, arguments: arguments)); } catch (Exception ex) { return(new StreamInvocationMessage(invocationId, target, ExceptionDispatchInfo.Capture(ex))); } }
private InvocationMessage BindInvocationMessage(JObject json, IInvocationBinder binder) { var invocationId = JsonUtils.GetOptionalProperty <string>(json, InvocationIdPropertyName, JTokenType.String); var metadata = JsonUtils.GetOptionalMetadataDictionary(json, MetadataPropertyName); var target = JsonUtils.GetRequiredProperty <string>(json, TargetPropertyName, JTokenType.String); var args = JsonUtils.GetRequiredProperty <JArray>(json, ArgumentsPropertyName, JTokenType.Array); var paramTypes = binder.GetParameterTypes(target); try { var arguments = BindArguments(args, paramTypes); return(new InvocationMessage(invocationId, metadata, target, arguments: arguments)); } catch (Exception ex) { return(new InvocationMessage(invocationId, metadata, target, ExceptionDispatchInfo.Capture(ex))); } }
private CompletionMessage BindCompletionMessage(JObject json, IInvocationBinder binder) { var invocationId = JsonUtils.GetRequiredProperty <string>(json, InvocationIdPropertyName, JTokenType.String); var error = JsonUtils.GetOptionalProperty <string>(json, ErrorPropertyName, JTokenType.String); var resultProp = json.Property(ResultPropertyName); if (error != null && resultProp != null) { throw new FormatException("The 'error' and 'result' properties are mutually exclusive."); } if (resultProp == null) { return(new CompletionMessage(invocationId, error, result: null, hasResult: false)); } var returnType = binder.GetReturnType(invocationId); var payload = resultProp.Value?.ToObject(returnType, _payloadSerializer); return(new CompletionMessage(invocationId, error, result: payload, hasResult: true)); }
public static bool TryParseRequestMessage(ReadOnlySequence <byte> buffer, out HandshakeRequestMessage requestMessage, out SequencePosition consumed, out SequencePosition examined) { if (!TryReadMessageIntoSingleMemory(buffer, out consumed, out examined, out var memory)) { requestMessage = null; return(false); } if (!TextMessageParser.TryParseMessage(ref memory, out var payload)) { throw new InvalidDataException("Unable to parse payload as a handshake request message."); } using (var reader = CreateJsonTextReader(payload)) { var token = JToken.ReadFrom(reader); var handshakeJObject = JsonUtils.GetObject(token); var protocol = JsonUtils.GetRequiredProperty <string>(handshakeJObject, ProtocolPropertyName); requestMessage = new HandshakeRequestMessage(protocol); } return(true); }
public static bool TryParseMessage(ReadOnlySpan <byte> input, out NegotiationMessage negotiationMessage) { if (!TextMessageParser.TryParseMessage(ref input, out var payload)) { throw new InvalidDataException("Unable to parse payload as a negotiation message."); } using (var memoryStream = new MemoryStream(payload.ToArray())) { using (var reader = new JsonTextReader(new StreamReader(memoryStream))) { var token = JToken.ReadFrom(reader); if (token == null || token.Type != JTokenType.Object) { throw new InvalidDataException($"Unexpected JSON Token Type '{token?.Type}'. Expected a JSON Object."); } var negotiationJObject = (JObject)token; var protocol = JsonUtils.GetRequiredProperty <string>(negotiationJObject, ProtocolPropertyName); negotiationMessage = new NegotiationMessage(protocol); } } return(true); }
private CancelInvocationMessage BindCancelInvocationMessage(JObject json) { var invocationId = JsonUtils.GetRequiredProperty <string>(json, InvocationIdPropertyName, JTokenType.String); return(new CancelInvocationMessage(invocationId)); }