// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.IO; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Internal; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace Microsoft.AspNetCore.SignalR { public class JsonNetInvocationAdapter : IInvocationAdapter { private JsonSerializer _serializer = new JsonSerializer(); public JsonNetInvocationAdapter() { } public Task ReadMessageAsync(Stream stream, IInvocationBinder binder, CancellationToken cancellationToken) { var reader = new JsonTextReader(new StreamReader(stream)); // REVIEW: Task.Run() return Task.Run(() => { cancellationToken.ThrowIfCancellationRequested(); var json = _serializer.Deserialize(reader); if (json == null) { return null; } // Determine the type of the message if (json["Result"] != null) { // It's a result return BindInvocationResultDescriptor(json, binder, cancellationToken); } else { return BindInvocationDescriptor(json, binder, cancellationToken); } }, cancellationToken); } public Task WriteMessageAsync(InvocationMessage message, Stream stream, CancellationToken cancellationToken) { var writer = new JsonTextWriter(new StreamWriter(stream)); _serializer.Serialize(writer, message); writer.Flush(); return TaskCache.CompletedTask; } private InvocationDescriptor BindInvocationDescriptor(JObject json, IInvocationBinder binder, CancellationToken cancellationToken) { var invocation = new InvocationDescriptor { Id = json.Value("Id"), Method = json.Value("Method"), }; var paramTypes = binder.GetParameterTypes(invocation.Method); invocation.Arguments = new object[paramTypes.Length]; var args = json.Value("Arguments"); for (var i = 0; i < paramTypes.Length; i++) { var paramType = paramTypes[i]; invocation.Arguments[i] = args[i].ToObject(paramType, _serializer); } return invocation; } private InvocationResultDescriptor BindInvocationResultDescriptor(JObject json, IInvocationBinder binder, CancellationToken cancellationToken) { var id = json.Value("Id"); var returnType = binder.GetReturnType(id); var result = new InvocationResultDescriptor() { Id = id, Result = returnType == null ? null : json["Result"].ToObject(returnType, _serializer), Error = json.Value("Error") }; return result; } } }