diff --git a/.github/workflows/build_publish_master.yml b/.github/workflows/build_publish_master.yml new file mode 100644 index 0000000..1a7fe10 --- /dev/null +++ b/.github/workflows/build_publish_master.yml @@ -0,0 +1,33 @@ +name: Build Master +on: + push: + paths-ignore: + - "**/*.md" + branches: [ master ] + +jobs: + build: + + strategy: + matrix: + os: ['ubuntu-latest'] + dotnet-version: ['3.1.201'] + project : ['Json-Rpc'] + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v2 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{matrix.dotnet-version}} + - name: Install dependencies + run: dotnet restore + - name: Build + run: dotnet build ${{matrix.project}} --configuration Release + - name: Test + run: dotnet test AustinHarris.JsonRpcTestN + # Publish + - name: publish nuget version change + run: dotnet nuget push Json-Rpc/bin/Release/*.nupkg --skip-duplicate --source "https://www.nuget.org" --api-key ${{secrets.NugetKey}} # API key for the NuGet feed diff --git a/.github/workflows/build_pull_request.yml b/.github/workflows/build_pull_request.yml new file mode 100644 index 0000000..f3e06e9 --- /dev/null +++ b/.github/workflows/build_pull_request.yml @@ -0,0 +1,35 @@ +name: Pull Reqest +on: + pull_request: + paths-ignore: + - "**/*.md" + branches: [ master ] + +jobs: + build: + + strategy: + matrix: + os: ['windows-latest','ubuntu-latest'] + dotnet-version: ['3.1.201'] + project : ['Json-Rpc'] + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v2 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{matrix.dotnet-version}} + - name: Install dependencies + run: dotnet restore + - name: Build + run: dotnet build ${{matrix.project}} --configuration Release --version-suffix ci-${{ github.run_id }}-${{ github.run_number }} + - name: Test + run: dotnet test AustinHarris.JsonRpcTestN + # Publish + - name: publish nuget version change + if: ${{matrix.os == 'ubuntu-latest'}} + run: dotnet nuget push Json-Rpc/bin/Release/*.nupkg --skip-duplicate --source "https://www.nuget.org" --api-key ${{secrets.NugetKey}} # API key for the NuGet feed + \ No newline at end of file diff --git a/.gitignore b/.gitignore index 11908c9..6ea46be 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,4 @@ _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML .nuget/NuGet.exe +.vs/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index f6ab2fa..0000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: csharp -solution: AustinHarris.JsonRpc.sln -mono: - - latest - - 3.12.0 - - 3.10.0 - - 3.8.0 -install: - - nuget restore AustinHarris.JsonRpc.sln - - nuget install NUnit.Runners -Version 2.6.4 -OutputDirectory testrunner -script: - - xbuild /p:Configuration=Release AustinHarris.JsonRpc.sln - - mono ./testrunner/NUnit.Runners.2.6.4/tools/nunit-console.exe ./AustinHarris.JsonRpcTestN/bin/Release/AustinHarris.JsonRpcTestN.dll \ No newline at end of file diff --git a/AustinHarris.JsonRpc.AspNet/AustinHarris.JsonRpc.AspNet.csproj b/AustinHarris.JsonRpc.AspNet/AustinHarris.JsonRpc.AspNet.csproj index f026b13..3470e2c 100644 --- a/AustinHarris.JsonRpc.AspNet/AustinHarris.JsonRpc.AspNet.csproj +++ b/AustinHarris.JsonRpc.AspNet/AustinHarris.JsonRpc.AspNet.csproj @@ -36,8 +36,8 @@ 4 - - ..\packages\Newtonsoft.Json.9.0.1\lib\net40\Newtonsoft.Json.dll + + ..\packages\Newtonsoft.Json.12.0.3\lib\net40\Newtonsoft.Json.dll True diff --git a/AustinHarris.JsonRpc.AspNet/packages.config b/AustinHarris.JsonRpc.AspNet/packages.config index 7c276ed..0fa4e01 100644 --- a/AustinHarris.JsonRpc.AspNet/packages.config +++ b/AustinHarris.JsonRpc.AspNet/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/AustinHarris.JsonRpc.sln b/AustinHarris.JsonRpc.sln index 858a102..6cf1c28 100644 --- a/AustinHarris.JsonRpc.sln +++ b/AustinHarris.JsonRpc.sln @@ -4,17 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 12.0.40629.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BBFBBA8A-2F75-422C-ACCD-D05A6EF7244C}" - ProjectSection(SolutionItems) = preProject - AustinHarris.JsonRpc.vsmdi = AustinHarris.JsonRpc.vsmdi - Local.testsettings = Local.testsettings - Performance1.psess = Performance1.psess - TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings - EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AustinHarris.JsonRpc", "Json-Rpc\AustinHarris.JsonRpc.csproj", "{24FC1A2A-0BC3-43A7-9BFE-B628C2C4A307}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AustinHarris.JsonRpc.AspNet", "AustinHarris.JsonRpc.AspNet\AustinHarris.JsonRpc.AspNet.csproj", "{FFFDEBBC-93F5-4A22-9EC5-D86A4A792DBB}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AustinHarris.JsonRpcTestN", "AustinHarris.JsonRpcTestN\AustinHarris.JsonRpcTestN.csproj", "{8569B076-5A8B-4D6A-B75D-EF75A390AA5F}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestServer_Console", "TestServer_Console\TestServer_Console.csproj", "{31AE59FC-B6F6-4AC7-A7B9-1E07630AE42B}" @@ -45,18 +37,6 @@ Global {24FC1A2A-0BC3-43A7-9BFE-B628C2C4A307}.Release|Mixed Platforms.Build.0 = Release|x86 {24FC1A2A-0BC3-43A7-9BFE-B628C2C4A307}.Release|x86.ActiveCfg = Release|x86 {24FC1A2A-0BC3-43A7-9BFE-B628C2C4A307}.Release|x86.Build.0 = Release|x86 - {FFFDEBBC-93F5-4A22-9EC5-D86A4A792DBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FFFDEBBC-93F5-4A22-9EC5-D86A4A792DBB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FFFDEBBC-93F5-4A22-9EC5-D86A4A792DBB}.Debug|ARM.ActiveCfg = Debug|Any CPU - {FFFDEBBC-93F5-4A22-9EC5-D86A4A792DBB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {FFFDEBBC-93F5-4A22-9EC5-D86A4A792DBB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {FFFDEBBC-93F5-4A22-9EC5-D86A4A792DBB}.Debug|x86.ActiveCfg = Debug|Any CPU - {FFFDEBBC-93F5-4A22-9EC5-D86A4A792DBB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FFFDEBBC-93F5-4A22-9EC5-D86A4A792DBB}.Release|Any CPU.Build.0 = Release|Any CPU - {FFFDEBBC-93F5-4A22-9EC5-D86A4A792DBB}.Release|ARM.ActiveCfg = Release|Any CPU - {FFFDEBBC-93F5-4A22-9EC5-D86A4A792DBB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {FFFDEBBC-93F5-4A22-9EC5-D86A4A792DBB}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {FFFDEBBC-93F5-4A22-9EC5-D86A4A792DBB}.Release|x86.ActiveCfg = Release|Any CPU {8569B076-5A8B-4D6A-B75D-EF75A390AA5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8569B076-5A8B-4D6A-B75D-EF75A390AA5F}.Debug|Any CPU.Build.0 = Debug|Any CPU {8569B076-5A8B-4D6A-B75D-EF75A390AA5F}.Debug|ARM.ActiveCfg = Debug|Any CPU diff --git a/AustinHarris.JsonRpcTestN/AustinHarris.JsonRpcTestN.csproj b/AustinHarris.JsonRpcTestN/AustinHarris.JsonRpcTestN.csproj index fe8c6d8..c5db038 100644 --- a/AustinHarris.JsonRpcTestN/AustinHarris.JsonRpcTestN.csproj +++ b/AustinHarris.JsonRpcTestN/AustinHarris.JsonRpcTestN.csproj @@ -1,69 +1,21 @@ - - + + - Debug - AnyCPU - {8569B076-5A8B-4D6A-B75D-EF75A390AA5F} - Library - AustinHarris.JsonRpcTestN - AustinHarris.JsonRpcTestN - v4.5 - ..\ - true + Austin Harris + netcoreapp3.0;netcoreapp3.1 - - true - full - false - bin\Debug - DEBUG; - prompt - 4 - false - - - full - true - bin\Release - prompt - 4 - false - - - - ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll - True - - - ..\packages\NUnit.2.6.4\lib\nunit.framework.dll - True - - - - - - - - - - - Designer - - + + - - {24FC1A2A-0BC3-43A7-9BFE-B628C2C4A307} - AustinHarris.JsonRpc - + + + + + + - + - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - + \ No newline at end of file diff --git a/AustinHarris.JsonRpcTestN/Test.cs b/AustinHarris.JsonRpcTestN/Test.cs index 3fd2e7f..ed46543 100644 --- a/AustinHarris.JsonRpcTestN/Test.cs +++ b/AustinHarris.JsonRpcTestN/Test.cs @@ -1379,6 +1379,18 @@ public void TestOptionalParametersBoolsAndStrings() Assert.IsFalse(result.Result.Contains("error")); Assert.AreEqual(expectedResult, result.Result); } + + [TestCase("{method:\"TestDifferentOptionalParameters\",params:{location:\"loc1\", uid:\"abc123\", wavelengths: [0.0], traces: [0.0]},id:1}", ExpectedResult = "{\"jsonrpc\":\"2.0\",\"result\":\"this is the requested measurement\",\"id\":1}")] + [TestCase("{method:\"TestDifferentOptionalParameters\",params:{uid:\"abc123\", wavelengths: [0.0], traces: [0.0]},id:1}", ExpectedResult = "{\"jsonrpc\":\"2.0\",\"result\":\"this is the requested measurement\",\"id\":1}")] + [TestCase("{method:\"TestDifferentOptionalParameters\",params:{location:\"loc1\", uid:\"abc123\", traces: [0.0]},id:1}", ExpectedResult = "{\"jsonrpc\":\"2.0\",\"result\":\"this is the requested measurement\",\"id\":1}")] + [TestCase("{method:\"TestDifferentOptionalParameters\",params:{location:\"loc1\", uid:\"abc123\", wavelengths: [0.0]},id:1}", ExpectedResult = "{\"jsonrpc\":\"2.0\",\"result\":\"this is the requested measurement\",\"id\":1}")] + [TestCase("{method:\"TestDifferentOptionalParameters\",params:{uid:\"abc123\", wavelengths: [0.0]},id:1}", ExpectedResult = "{\"jsonrpc\":\"2.0\",\"result\":\"this is the requested measurement\",\"id\":1}")] + public string TestDifferentOptionalParametersNamedWorking(string request) + { + var result = JsonRpcProcessor.Process(request); + result.Wait(); + return result.Result; + } [Test()] public void TestBatchResultWrongRequests() @@ -1843,6 +1855,16 @@ public void TestExtraParameters() Assert.IsTrue(result.Result.Contains("\"code\":-32602")); } + [Test()] + public void TestExtraPositionalParameters() + { + string request = @"{method:'ReturnsDateTime',params:[1,2,'mytext'],id:1}"; + var result = JsonRpcProcessor.Process(request); + result.Wait(); + Assert.IsTrue(result.Result.Contains("error")); + Assert.IsTrue(result.Result.Contains("\"code\":-32602")); + } + [Test()] public void TestCustomParameterName() { @@ -1879,6 +1901,26 @@ public void TestNestedReturnType() Assert.AreEqual(expected, result.Result); } + [Test()] + public void TestWrongParamType() + { + string request = @"{method:'TestOptionalParamdouble',params:{input:'mytext'},id:1}"; + var result = JsonRpcProcessor.Process(request); + result.Wait(); + Assert.IsTrue(result.Result.Contains("error")); + Assert.IsTrue(result.Result.Contains("\"code\":-32603")); + } + + [Test()] + public void TestWrongIdType() + { + string request = @"{method:'TestOptionalParamdouble',params:{input:5},id:{what:4,that:3}}"; + var result = JsonRpcProcessor.Process(request); + result.Wait(); + Assert.IsTrue(result.Result.Contains("error")); + Assert.IsTrue(result.Result.Contains("\"code\":-32600")); + } + private static void AssertJsonAreEqual(string expectedJson, string actualJson) { Newtonsoft.Json.Linq.JObject expected = (Newtonsoft.Json.Linq.JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(expectedJson); diff --git a/AustinHarris.JsonRpcTestN/packages.config b/AustinHarris.JsonRpcTestN/packages.config deleted file mode 100644 index 3632280..0000000 --- a/AustinHarris.JsonRpcTestN/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/AustinHarris.JsonRpcTestN/service.cs b/AustinHarris.JsonRpcTestN/service.cs index 623a0e8..b34d957 100644 --- a/AustinHarris.JsonRpcTestN/service.cs +++ b/AustinHarris.JsonRpcTestN/service.cs @@ -389,6 +389,12 @@ public TreeNode TestNestedReturnType() } }; } + + [JsonRpcMethod] + private string TestDifferentOptionalParameters(string uid, string location = null, List traces = null, List wavelengths = null) + { + return "this is the requested measurement"; + } } } diff --git a/Json-Rpc/AustinHarris.JsonRpc.csproj b/Json-Rpc/AustinHarris.JsonRpc.csproj index 9d97aeb..f6a680d 100644 --- a/Json-Rpc/AustinHarris.JsonRpc.csproj +++ b/Json-Rpc/AustinHarris.JsonRpc.csproj @@ -1,100 +1,27 @@ - - - - Debug - x86 - {24FC1A2A-0BC3-43A7-9BFE-B628C2C4A307} - Library - Properties - AustinHarris.JsonRpc - AustinHarris.JsonRpc - - - 512 - SAK - SAK - SAK - SAK - ..\..\CoiniumServ\build\ - true - v4.0 - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - - AnyCPU - pdbonly - true - bin\Release\ - - - prompt - 4 - false - - - AnyCPU - bin\Debug\ - TRACE;DEBUG - 4 - false - - - AnyCPU - bin\Release\ - 4 - true - false - - - - - - - - - - - - - - - - - - - - - ..\packages\Newtonsoft.Json.9.0.1\lib\net40\Newtonsoft.Json.dll - True - - - - - - - - - + + - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + Austin Harris + Json-Rpc.Net Core + Core functionality for JsonRpc.Net + 1.2.3 + $(VersionSuffix) + Austin Harris + https://github.com/Astn/JSON-RPC.NET + https://raw.githubusercontent.com/Astn/JSON-RPC.NET/master/LICENSE + + Improves support for optional parameters - @HoMS1987 https://github.com/HoMS1987 + Fixes protocol validation of the ID property - @pedrolcl https://github.com/pedrolcl + DotNet Core support - @astn https://github.com/astn + + netstandard2.0;netstandard2.1;netcoreapp3.1 + true + - - - + + + + + + \ No newline at end of file diff --git a/Json-Rpc/AustinHarris.JsonRpc.nuspec b/Json-Rpc/AustinHarris.JsonRpc.nuspec index 0922df6..ad36f62 100644 --- a/Json-Rpc/AustinHarris.JsonRpc.nuspec +++ b/Json-Rpc/AustinHarris.JsonRpc.nuspec @@ -12,7 +12,7 @@ false The fastest .Net JSON RPC Server JSON-RPC.Net is a high performance Json-Rpc 2.0 server, leveraging the popular JSON.NET library. Easily create a JSON RPC server for your Angular javascript apps, also supports sockets and pipes, oh my! - Named Parameters via attributes -rommar. Fix nuget dependency requirements -jbreens. Cleaner service registration -xmedeko + Optional JsonSerializer Settings - @hovi. ProcessSync is now public - @astn en-US fast json rpc server socket javascript json-rpc.net json-rpc jsonrpc json.net web services webapi service angular server angularjs diff --git a/Json-Rpc/Handler.cs b/Json-Rpc/Handler.cs index 474ff91..095bacb 100644 --- a/Json-Rpc/Handler.cs +++ b/Json-Rpc/Handler.cs @@ -250,7 +250,7 @@ public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null) if (Rpc.Params is Newtonsoft.Json.Linq.JArray) { var jarr = ((Newtonsoft.Json.Linq.JArray)Rpc.Params); - for (int i = 0; i < loopCt; i++) + for (int i = 0; i < loopCt && i < metadata.parameters.Length; i++) { parameters[i] = CleanUpParameter(jarr[i], metadata.parameters[i]); } @@ -267,6 +267,14 @@ public JsonResponse Handle(JsonRequest Rpc, Object RpcContext = null) } else { + var foundDefault = metadata.defaultValues + .FirstOrDefault(defaul => defaul.Name == metadata.parameters[i].Name); + if (foundDefault != null) + { + parameters[i] = foundDefault.Value; + continue; + } + JsonResponse response = new JsonResponse() { Error = ProcessException(Rpc, @@ -431,34 +439,34 @@ private object CleanUpParameter(object p, SMDAdditionalParameters metaData) return bob.Value; } - // Avoid calling DeserializeObject on types that JValue has an explicit converter for - // try to optimize for the most common types - if (metaData.ObjectType == typeof(string)) return (string)bob; - if (metaData.ObjectType == typeof(int)) return (int)bob; - if (metaData.ObjectType == typeof(double)) return (double)bob; - if (metaData.ObjectType == typeof(float)) return (float)bob; - //if (metaData.ObjectType == typeof(long)) return (long)bob; - //if (metaData.ObjectType == typeof(uint)) return (uint)bob; - //if (metaData.ObjectType == typeof(ulong)) return (ulong)bob; - //if (metaData.ObjectType == typeof(byte[])) return (byte[])bob; - //if (metaData.ObjectType == typeof(Guid)) return (Guid)bob; - if (metaData.ObjectType == typeof(decimal)) return (decimal)bob; - //if (metaData.ObjectType == typeof(TimeSpan)) return (TimeSpan)bob; - //if (metaData.ObjectType == typeof(short)) return (short)bob; - //if (metaData.ObjectType == typeof(ushort)) return (ushort)bob; - //if (metaData.ObjectType == typeof(char)) return (char)bob; - //if (metaData.ObjectType == typeof(DateTime)) return (DateTime)bob; - //if (metaData.ObjectType == typeof(bool)) return (bool)bob; - //if (metaData.ObjectType == typeof(DateTimeOffset)) return (DateTimeOffset)bob; - - if (metaData.ObjectType.IsAssignableFrom(typeof(JValue))) - return bob; - try { + // Avoid calling DeserializeObject on types that JValue has an explicit converter for + // try to optimize for the most common types + if (metaData.ObjectType == typeof(string)) return (string)bob; + if (metaData.ObjectType == typeof(int)) return (int)bob; + if (metaData.ObjectType == typeof(double)) return (double)bob; + if (metaData.ObjectType == typeof(float)) return (float)bob; + //if (metaData.ObjectType == typeof(long)) return (long)bob; + //if (metaData.ObjectType == typeof(uint)) return (uint)bob; + //if (metaData.ObjectType == typeof(ulong)) return (ulong)bob; + //if (metaData.ObjectType == typeof(byte[])) return (byte[])bob; + //if (metaData.ObjectType == typeof(Guid)) return (Guid)bob; + if (metaData.ObjectType == typeof(decimal)) return (decimal)bob; + //if (metaData.ObjectType == typeof(TimeSpan)) return (TimeSpan)bob; + //if (metaData.ObjectType == typeof(short)) return (short)bob; + //if (metaData.ObjectType == typeof(ushort)) return (ushort)bob; + //if (metaData.ObjectType == typeof(char)) return (char)bob; + //if (metaData.ObjectType == typeof(DateTime)) return (DateTime)bob; + //if (metaData.ObjectType == typeof(bool)) return (bool)bob; + //if (metaData.ObjectType == typeof(DateTimeOffset)) return (DateTimeOffset)bob; + + if (metaData.ObjectType.IsAssignableFrom(typeof(JValue))) + return bob; + return bob.ToObject(metaData.ObjectType); } - catch (Exception ex) + catch (Exception) { // no need to throw here, they will // get an invalid cast exception right after this. @@ -472,7 +480,7 @@ private object CleanUpParameter(object p, SMDAdditionalParameters metaData) return JsonConvert.DeserializeObject((string)p, metaData.ObjectType); return JsonConvert.DeserializeObject(p.ToString(), metaData.ObjectType); } - catch (Exception ex) + catch (Exception) { // no need to throw here, they will // get an invalid cast exception right after this. @@ -484,7 +492,7 @@ private object CleanUpParameter(object p, SMDAdditionalParameters metaData) private JsonRpcException PreProcess(JsonRequest request, object context) { - return externalPreProcessingHandler == null ? null : externalPreProcessingHandler(request, context); + return externalPreProcessingHandler?.Invoke(request, context); } private JsonResponse PostProcess(JsonRequest request, JsonResponse response, object context) diff --git a/Json-Rpc/JsonResponse.cs b/Json-Rpc/JsonResponse.cs index d16a64b..941de82 100644 --- a/Json-Rpc/JsonResponse.cs +++ b/Json-Rpc/JsonResponse.cs @@ -13,7 +13,7 @@ namespace AustinHarris.JsonRpc public class JsonResponse { [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "jsonrpc")] - public string JsonRpc { get { return "2.0"; } } + public string JsonRpc { get; set; } = "2.0"; [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "result")] public object Result { get; set; } @@ -32,7 +32,7 @@ public class JsonResponse public class JsonResponse { [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "jsonrpc")] - public string JsonRpc { get { return "2.0"; } } + public string JsonRpc { get; set; } = "2.0"; [JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "result")] public T Result { get; set; } diff --git a/Json-Rpc/JsonRpcProcessor.cs b/Json-Rpc/JsonRpcProcessor.cs index fd2126f..5020e88 100644 --- a/Json-Rpc/JsonRpcProcessor.cs +++ b/Json-Rpc/JsonRpcProcessor.cs @@ -13,34 +13,41 @@ namespace AustinHarris.JsonRpc { public static class JsonRpcProcessor { - public static void Process(JsonRpcStateAsync async, object context = null) + public static void Process(JsonRpcStateAsync async, object context = null, + JsonSerializerSettings settings = null) { - Process(Handler.DefaultSessionId(), async, context); + Process(Handler.DefaultSessionId(), async, context, settings); } - public static void Process(string sessionId, JsonRpcStateAsync async, object context = null) + public static void Process(string sessionId, JsonRpcStateAsync async, object context = null, + JsonSerializerSettings settings = null) { - Process(sessionId, async.JsonRpc, context) + Process(sessionId, async.JsonRpc, context, settings) .ContinueWith(t => - { - async.Result = t.Result; - async.SetCompleted(); - }); + { + async.Result = t.Result; + async.SetCompleted(); + }); } - public static Task Process(string jsonRpc, object context = null) + + public static Task Process(string jsonRpc, object context = null, + JsonSerializerSettings settings = null) { - return Process(Handler.DefaultSessionId(), jsonRpc, context); + return Process(Handler.DefaultSessionId(), jsonRpc, context, settings); } - public static Task Process(string sessionId, string jsonRpc, object context = null) - { + + public static Task Process(string sessionId, string jsonRpc, object context = null, + JsonSerializerSettings settings = null) + { return Task.Factory.StartNew((_) => { - var tuple = (Tuple)_; - return ProcessInternal(tuple.Item1, tuple.Item2, tuple.Item3); - }, new Tuple(sessionId, jsonRpc, context)); + var tuple = (Tuple)_; + return ProcessSync(tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4); + }, new Tuple(sessionId, jsonRpc, context, settings)); } - private static string ProcessInternal(string sessionId, string jsonRpc, object jsonRpcContext) + public static string ProcessSync(string sessionId, string jsonRpc, object jsonRpcContext, + JsonSerializerSettings settings = null) { var handler = Handler.GetSessionHandler(sessionId); @@ -50,12 +57,12 @@ private static string ProcessInternal(string sessionId, string jsonRpc, object j { if (isSingleRpc(jsonRpc)) { - var foo = JsonConvert.DeserializeObject(jsonRpc); + var foo = JsonConvert.DeserializeObject(jsonRpc, settings); batch = new[] { foo }; } else { - batch = JsonConvert.DeserializeObject(jsonRpc); + batch = JsonConvert.DeserializeObject(jsonRpc, settings); } } catch (Exception ex) @@ -63,7 +70,7 @@ private static string ProcessInternal(string sessionId, string jsonRpc, object j return Newtonsoft.Json.JsonConvert.SerializeObject(new JsonResponse { Error = handler.ProcessParseException(jsonRpc, new JsonRpcException(-32700, "Parse error", ex)) - }); + }, settings); } if (batch.Length == 0) @@ -72,7 +79,7 @@ private static string ProcessInternal(string sessionId, string jsonRpc, object j { Error = handler.ProcessParseException(jsonRpc, new JsonRpcException(3200, "Invalid Request", "Batch of calls was empty.")) - }); + }, settings); } var singleBatch = batch.Length == 1; @@ -93,6 +100,11 @@ private static string ProcessInternal(string sessionId, string jsonRpc, object j jsonResponse.Error = handler.ProcessParseException(jsonRpc, new JsonRpcException(-32600, "Invalid Request", "Missing property 'method'")); } + else if (!isSimpleValueType(jsonRequest.Id)) + { + jsonResponse.Error = handler.ProcessParseException(jsonRpc, + new JsonRpcException(-32600, "Invalid Request", "Id property must be either null or string or integer.")); + } else { jsonResponse.Id = jsonRequest.Id; @@ -101,6 +113,7 @@ private static string ProcessInternal(string sessionId, string jsonRpc, object j if (data == null) continue; + jsonResponse.JsonRpc = data.JsonRpc; jsonResponse.Error = data.Error; jsonResponse.Result = data.Result; @@ -119,15 +132,17 @@ private static string ProcessInternal(string sessionId, string jsonRpc, object j StringWriter sw = new StringWriter(); JsonTextWriter writer = new JsonTextWriter(sw); writer.WriteStartObject(); - writer.WritePropertyName("jsonrpc"); writer.WriteValue("2.0"); - + if (!string.IsNullOrEmpty(jsonResponse.JsonRpc)) + { + writer.WritePropertyName("jsonrpc"); writer.WriteValue(jsonResponse.JsonRpc); + } if (jsonResponse.Error != null) { - writer.WritePropertyName("error"); writer.WriteRawValue(JsonConvert.SerializeObject(jsonResponse.Error)); + writer.WritePropertyName("error"); writer.WriteRawValue(JsonConvert.SerializeObject(jsonResponse.Error, settings)); } else { - writer.WritePropertyName("result"); writer.WriteRawValue(JsonConvert.SerializeObject(jsonResponse.Result)); + writer.WritePropertyName("result"); writer.WriteRawValue(JsonConvert.SerializeObject(jsonResponse.Result, settings)); } writer.WritePropertyName("id"); writer.WriteValue(jsonResponse.Id); writer.WriteEndObject(); @@ -148,7 +163,7 @@ private static string ProcessInternal(string sessionId, string jsonRpc, object j sbResult = new StringBuilder("["); } - sbResult.Append(JsonConvert.SerializeObject(jsonResponse)); + sbResult.Append(JsonConvert.SerializeObject(jsonResponse, settings)); if (i < batch.Length - 1) { sbResult.Append(','); @@ -171,5 +186,15 @@ private static bool isSingleRpc(string json) } return true; } + + private static bool isSimpleValueType(object property) + { + if (property == null) + return true; + return property.GetType() == typeof(System.String) || + property.GetType() == typeof(System.Int64) || + property.GetType() == typeof(System.Int32) || + property.GetType() == typeof(System.Int16); + } } } diff --git a/Json-Rpc/Properties/AssemblyInfo.cs b/Json-Rpc/Properties/AssemblyInfo.cs deleted file mode 100644 index 802d0fd..0000000 --- a/Json-Rpc/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Json-Rpc.Net Core")] -[assembly: AssemblyDescription("Core functionality for JsonRpc.Net")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Austin Harris")] -[assembly: AssemblyProduct("Json-Rpc.Net Core")] -[assembly: AssemblyCopyright("Austin Harris")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("2f8036b2-223d-4b90-b6a9-fadddeb3ac0d")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -[assembly: AssemblyVersion("1.0.5.0")] -[assembly: AssemblyFileVersion("1.0.5.0")] diff --git a/Json-Rpc/packages.config b/Json-Rpc/packages.config deleted file mode 100644 index 7c276ed..0000000 --- a/Json-Rpc/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/README.md b/README.md index 553edd8..7847e23 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,35 @@ json-rpc.net ============ -.Net [![astn-jsonrpc MyGet Build Status](https://www.myget.org/BuildSource/Badge/astn-jsonrpc?identifier=fbc64a4a-f9a7-4306-87ba-de0bb9d23cb7)](https://www.myget.org/feed/Activity/astn-jsonrpc) Mono [![Build Status](https://travis-ci.org/Astn/JSON-RPC.NET.svg?branch=master)](https://travis-ci.org/Astn/JSON-RPC.NET) +![Build Master](https://github.com/Astn/JSON-RPC.NET/workflows/Build%20Master/badge.svg) ![NuGet Badge](https://buildstats.info/nuget/AustinHarris.JsonRpc) JSON-RPC.Net is a high performance Json-Rpc 2.0 server, leveraging the popular JSON.NET library. Host in ASP.NET, also supports sockets and pipes, oh my! +## Performance + +These are results from running the TestServer_Console project. + +##### Xeon E-2176M @ 2.70GHz 64.0 GB (Date: Thu Apr 30 17:34:22 2020 -0600) + +``` +Starting benchmark +processed 50 rpc in 137ms for 364.96 rpc/sec +processed 100 rpc in 0ms for ∞ rpc/sec +processed 300 rpc in 1ms for 300,000.00 rpc/sec +processed 1,200 rpc in 7ms for 171,428.57 rpc/sec +processed 6,000 rpc in 26ms for 230,769.23 rpc/sec +processed 36,000 rpc in 166ms for 216,867.47 rpc/sec +processed 252,000 rpc in 1,121ms for 224,799.29 rpc/sec +Finished benchmark... +``` + +## Do you like this? + +[![https://www.buymeacoffee.com/Ekati](https://cdn.buymeacoffee.com/buttons/default-blue.png)](https://www.buymeacoffee.com/Ekati) + + ##### Requirements -* dotnet 4.0 or mono +* dotnet-standard (dotnet core | mono | .net framework) ##### License JSON-RPC.net is licensed under The MIT License (MIT), check the [LICENSE](https://github.com/CoiniumServ/JSON-RPC.NET/blob/master/LICENSE) file for details. @@ -29,28 +52,8 @@ To install JSON-RPC.NET AspNet, run the following command in the Package Manager PM> Install-Package AustinHarris.JsonRpc.AspNet ``` -##### Performance - -Under ideal conditions > 120k rpc/sec (cpu i7-2600, console test server) - -> -``` -Starting benchmark -processed 50 rpc in 0ms for ∞ rpc/sec -processed 100 rpc in 2ms for 50,000 rpc/sec -processed 300 rpc in 1ms for 300,000 rpc/sec -processed 1,200 rpc in 6ms for 200,000 rpc/sec -processed 6,000 rpc in 37ms for 162,162 rpc/sec -processed 36,000 rpc in 228ms for 157,894 rpc/sec -processed 252,000 rpc in 1,688ms for 149,289 rpc/sec -processed 2,016,000 rpc in 13,930ms for 144,723 rpc/sec -Finished benchmark... -``` -###### Test machine -i7 920 @ 2.67 GHz -12.0 GB diff --git a/TestServer_Console/Program.cs b/TestServer_Console/Program.cs index 6d9c125..df3152f 100644 --- a/TestServer_Console/Program.cs +++ b/TestServer_Console/Program.cs @@ -68,7 +68,7 @@ private static void Benchmark() } Task.WaitAll(tasks); sw.Stop(); - Console.WriteLine("processed {0} rpc in {1}ms for {2} rpc/sec", cnt, sw.ElapsedMilliseconds, (double)cnt * 1000d / sw.ElapsedMilliseconds); + Console.WriteLine("processed {0:N0} rpc in \t {1:N0}ms for \t {2:N} rpc/sec", cnt, sw.ElapsedMilliseconds, (double)cnt * 1000d / sw.ElapsedMilliseconds); } diff --git a/TestServer_Console/Properties/AssemblyInfo.cs b/TestServer_Console/Properties/AssemblyInfo.cs deleted file mode 100644 index fdd1edf..0000000 --- a/TestServer_Console/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("TestServer_Console")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("TestServer_Console")] -[assembly: AssemblyCopyright("Copyright © 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("5e7696bc-52cc-48f8-a575-40b17165ee20")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/TestServer_Console/TestServer_Console.csproj b/TestServer_Console/TestServer_Console.csproj index be9574b..ba5f427 100644 --- a/TestServer_Console/TestServer_Console.csproj +++ b/TestServer_Console/TestServer_Console.csproj @@ -1,98 +1,24 @@ - - + + - Debug - x86 - {31AE59FC-B6F6-4AC7-A7B9-1E07630AE42B} + Austin Harris Exe - Properties - TestServer_Console - TestServer_Console - v4.0 - Client - 512 - SAK - SAK - SAK - SAK - ..\ - true + netcoreapp3.1 - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - x86 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - AnyCPU - bin\Debug\ - 4 - false - - - AnyCPU - bin\Release\ - 4 - true - false - - - - ..\packages\Newtonsoft.Json.9.0.1\lib\net40\Newtonsoft.Json.dll - True - - - - - - - - - - ..\packages\Newtonsoft.Json.7.0.1\lib\net40\Newtonsoft.Json.dll - - + + - - - + + + - - {24FC1A2A-0BC3-43A7-9BFE-B628C2C4A307} - AustinHarris.JsonRpc - + + + - + - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - + \ No newline at end of file diff --git a/TestServer_Console/packages.config b/TestServer_Console/packages.config deleted file mode 100644 index e307e1c..0000000 --- a/TestServer_Console/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file