From 76706144a570d04313edc2b7216875a4ee1e3a7f Mon Sep 17 00:00:00 2001 From: Dylan Dmitri Gray Date: Wed, 1 Aug 2018 09:31:43 -0700 Subject: [PATCH 01/30] Add support for streaming arguments to clients using Channel (#2441) --- NuGet.config | 2 +- .../TestBinder.cs | 5 + clients/ts/FunctionalTests/package-lock.json | 254 +++++++++--------- samples/ClientSample/Program.cs | 2 + samples/ClientSample/StreamingSample.cs | 46 ++++ samples/ClientSample/UploadSample.cs | 90 +++++++ samples/SignalRSamples/Hubs/UploadHub.cs | 110 ++++++++ samples/SignalRSamples/Startup.cs | 1 + src/Common/ReflectionHelper.cs | 39 +++ .../HubConnection.Log.cs | 32 +++ .../HubConnection.cs | 155 +++++++++-- ...soft.AspNetCore.SignalR.Client.Core.csproj | 1 + .../IInvocationBinder.cs | 1 + .../Protocol/HubProtocolConstants.cs | 10 + .../Protocol/StreamBindingFailureMessage.cs | 37 +++ .../Protocol/StreamCompleteMessage.cs | 41 +++ .../Protocol/StreamDataMessage.cs | 33 +++ .../Protocol/StreamPlaceholder.cs | 25 ++ .../breakingchanges.netcore.json | 5 + .../HubConnectionContext.cs | 13 + .../HubConnectionHandler.cs | 5 +- .../Internal/DefaultHubDispatcher.Log.cs | 32 +++ .../Internal/DefaultHubDispatcher.cs | 131 +++++++-- .../Internal/HubConnectionBinder.cs | 36 +++ .../Internal/HubDispatcher.cs | 5 +- .../Internal/HubMethodDescriptor.cs | 16 +- .../Microsoft.AspNetCore.SignalR.Core.csproj | 4 + .../StreamTracker.cs | 105 ++++++++ ...t.AspNetCore.SignalR.Protocols.Json.csproj | 2 +- .../Protocol/JsonHubProtocol.cs | 115 +++++++- .../Protocol/MessagePackHubProtocol.cs | 36 ++- .../HubConnectionTests.cs | 224 +++++++++++++++ .../TestConnection.cs | 5 + .../Internal/Protocol/CompositeTestBinder.cs | 5 + .../Internal/Protocol/JsonHubProtocolTests.cs | 10 +- .../Protocol/MessagePackHubProtocolTests.cs | 24 +- .../Internal/Protocol/TestBinder.cs | 8 + .../TestHubMessageEqualityComparer.cs | 59 ++-- .../TestClient.cs | 12 + .../HubConnectionHandlerTestUtils/Hubs.cs | 73 +++++ .../HubConnectionHandlerTests.cs | 210 ++++++++++++++- 41 files changed, 1797 insertions(+), 222 deletions(-) create mode 100644 samples/ClientSample/StreamingSample.cs create mode 100644 samples/ClientSample/UploadSample.cs create mode 100644 samples/SignalRSamples/Hubs/UploadHub.cs create mode 100644 src/Common/ReflectionHelper.cs create mode 100644 src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamBindingFailureMessage.cs create mode 100644 src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamCompleteMessage.cs create mode 100644 src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamDataMessage.cs create mode 100644 src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamPlaceholder.cs create mode 100644 src/Microsoft.AspNetCore.SignalR.Core/Internal/HubConnectionBinder.cs create mode 100644 src/Microsoft.AspNetCore.SignalR.Core/StreamTracker.cs diff --git a/NuGet.config b/NuGet.config index e32bddfd51..1280d2db38 100644 --- a/NuGet.config +++ b/NuGet.config @@ -2,6 +2,6 @@ - + diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/TestBinder.cs b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/TestBinder.cs index 1e25041d4f..bbcb8a1bde 100644 --- a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/TestBinder.cs +++ b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/TestBinder.cs @@ -59,5 +59,10 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks } throw new InvalidOperationException("Unexpected binder call"); } + + public Type GetStreamItemType(string streamId) + { + throw new NotImplementedException(); + } } } diff --git a/clients/ts/FunctionalTests/package-lock.json b/clients/ts/FunctionalTests/package-lock.json index 2a949153c3..9dd1fd7506 100644 --- a/clients/ts/FunctionalTests/package-lock.json +++ b/clients/ts/FunctionalTests/package-lock.json @@ -183,7 +183,7 @@ "adm-zip": { "version": "0.4.11", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.11.tgz", - "integrity": "sha512-L8vcjDTCOIJk7wFvmlEUN7AsSb8T+2JrdP7KINBjzr24TJ5Mwj590sLu3BC7zNZowvJWa/JtPmD8eJCzdtDWjA==", + "integrity": "sha1-KqVMhMSwGp0PuJuxGYKlHxPj1io=", "dev": true }, "after": { @@ -216,7 +216,7 @@ "amqplib": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz", - "integrity": "sha512-l9mCs6LbydtHqRniRwYkKdqxVa6XMz3Vw1fh+2gJaaVgTM6Jk3o8RccAKWKtlhT1US5sWrFh+KKxsVUALURSIA==", + "integrity": "sha1-0tcxPH/6pNELzx5iUt5FkbbMe2M=", "dev": true, "optional": true, "requires": { @@ -274,7 +274,7 @@ "anymatch": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=", "dev": true, "requires": { "micromatch": "^3.1.4", @@ -320,7 +320,7 @@ "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=", "dev": true }, "arr-union": { @@ -344,7 +344,7 @@ "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "integrity": "sha1-O7xCdd1YTMGxCAm4nU6LY6aednU=", "dev": true }, "arrify": { @@ -374,14 +374,14 @@ "ast-types": { "version": "0.11.5", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.5.tgz", - "integrity": "sha512-oJjo+5e7/vEc2FBK8gUalV0pba4L3VdBIs2EKhOLHLcOd2FgQIVQN9xb0eZ9IjEWyAL7vq6fGJxOvVvdCHNyMw==", + "integrity": "sha1-mJCCXWYMA8KDOfMV6foKNg4x7Cg=", "dev": true, "optional": true }, "async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "integrity": "sha1-skWiPKcZMAROxT+kaqAKPofGphA=", "dev": true, "requires": { "lodash": "^4.17.10" @@ -396,7 +396,7 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg=", "dev": true }, "asynckit": { @@ -420,7 +420,7 @@ "aws4": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", + "integrity": "sha1-1NDpudv8p3vwjusKikcVUP454ok=", "dev": true }, "axios": { @@ -470,7 +470,7 @@ "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=", "dev": true, "requires": { "cache-base": "^1.0.1", @@ -494,7 +494,7 @@ "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -503,7 +503,7 @@ "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -512,7 +512,7 @@ "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -587,7 +587,7 @@ "bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "integrity": "sha1-2VUfnemPH82h5oPRfukaBgLuLrk=", "dev": true }, "body-parser": { @@ -611,7 +611,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -641,7 +641,7 @@ "braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=", "dev": true, "requires": { "arr-flatten": "^1.1.0", @@ -670,7 +670,7 @@ "buffer-alloc": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "integrity": "sha1-iQ3ZDZI6hz4I4Q5f1RpX5bfM4Ow=", "dev": true, "requires": { "buffer-alloc-unsafe": "^1.1.0", @@ -680,7 +680,7 @@ "buffer-alloc-unsafe": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "integrity": "sha1-vX3CauKXLQ7aJTvgYdupkjScGfA=", "dev": true }, "buffer-crc32": { @@ -732,7 +732,7 @@ "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=", "dev": true, "requires": { "collection-visit": "^1.0.0", @@ -772,7 +772,7 @@ "chokidar": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "integrity": "sha1-NW/04rDo5D4yLRijckYLvPOszSY=", "dev": true, "requires": { "anymatch": "^2.0.0", @@ -799,7 +799,7 @@ "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=", "dev": true, "requires": { "arr-union": "^3.1.0", @@ -853,7 +853,7 @@ "colors": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.0.tgz", - "integrity": "sha512-EDpX3a7wHMWFA7PUHWPHNWqOxIIRSJetuwl0AS5Oi/5FMV8kWm69RTlgm00GKjBO1xFHMtBbL49yRtMMdticBw==", + "integrity": "sha1-XyDJ/vaUXLETQmCqszv73IKV4E4=", "dev": true }, "combine-lists": { @@ -943,7 +943,7 @@ "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=", "dev": true }, "cookie": { @@ -961,7 +961,7 @@ "core-js": { "version": "2.5.7", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "integrity": "sha1-+XJgj/DOrWi4QaFqky0LGDeRgU4=", "dev": true }, "core-util-is": { @@ -1013,7 +1013,7 @@ "data-uri-to-buffer": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", - "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", + "integrity": "sha1-dxY+qcINhkG0cH6PGKvfmnjzSDU=", "dev": true, "optional": true }, @@ -1048,7 +1048,7 @@ "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "integrity": "sha1-1Flono1lS6d+AqgX+HENcCyxbp0=", "dev": true, "requires": { "is-descriptor": "^1.0.2", @@ -1058,7 +1058,7 @@ "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -1067,7 +1067,7 @@ "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -1076,7 +1076,7 @@ "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -1172,7 +1172,7 @@ "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "integrity": "sha1-7SljTRm6ukY7bOa4CjchPqtx7EM=", "dev": true, "requires": { "once": "^1.4.0" @@ -1181,7 +1181,7 @@ "engine.io": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", - "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", + "integrity": "sha1-Dn751pDrCzVZfx1K0Comyi26OEU=", "dev": true, "requires": { "accepts": "~1.3.4", @@ -1196,7 +1196,7 @@ "engine.io-client": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", - "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", + "integrity": "sha1-W96xMPi5SlCsXL63JYPnpKBj3f0=", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -1215,7 +1215,7 @@ "engine.io-parser": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", - "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "integrity": "sha1-TA9M/3mq7su9z96maoI8YIVAkZY=", "dev": true, "requires": { "after": "0.8.2", @@ -1261,7 +1261,7 @@ "escodegen": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.10.0.tgz", - "integrity": "sha512-fjUOf8johsv23WuIKdNQU4P9t9jhQ4Qzx6pC2uW890OloK3Zs1ZAoCNpg/2larNF501jLl3UNy0kIRcF6VI22g==", + "integrity": "sha1-9kc5XeIlGfvQ2Sj/zx0X4N7CYD4=", "dev": true, "optional": true, "requires": { @@ -1295,7 +1295,7 @@ "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", - "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", + "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=", "dev": true }, "expand-braces": { @@ -1413,7 +1413,7 @@ "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", "dev": true, "requires": { "is-plain-object": "^2.0.4" @@ -1424,7 +1424,7 @@ "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "integrity": "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM=", "dev": true, "requires": { "array-unique": "^0.3.2", @@ -1458,7 +1458,7 @@ "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -1467,7 +1467,7 @@ "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -1476,7 +1476,7 @@ "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -1514,7 +1514,7 @@ "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "integrity": "sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90=", "dev": true, "optional": true }, @@ -1626,7 +1626,7 @@ "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "integrity": "sha1-a+Dem+mYzhavivwkSXue6bfM2a0=", "dev": true }, "fs.realpath": { @@ -2224,7 +2224,7 @@ "get-uri": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.2.tgz", - "integrity": "sha512-ZD325dMZOgerGqF/rF6vZXyFGTAay62svjQIT+X/oU2PtxYpFxvSkbsdi+oxIrsNxlZVd4y8wUDqkaExWTI/Cw==", + "integrity": "sha1-XHlecTJvbKEoby/IJXXNK6sq9Xg=", "dev": true, "optional": true, "requires": { @@ -2333,7 +2333,7 @@ "has-binary2": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "integrity": "sha1-d3asYn8+p3JQz8My2rfd9eT10R0=", "dev": true, "requires": { "isarray": "2.0.1" @@ -2445,7 +2445,7 @@ "http-proxy": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "integrity": "sha1-etOElGWPhGBeL220Q230EPTlvpo=", "dev": true, "requires": { "eventemitter3": "^3.0.0", @@ -2456,7 +2456,7 @@ "http-proxy-agent": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "integrity": "sha1-5IIb7vWyFCogJr1zkm/lN2McVAU=", "dev": true, "requires": { "agent-base": "4", @@ -2493,7 +2493,7 @@ "https-proxy-agent": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "integrity": "sha1-UVUpcPoE1yPgTFbQQXjD+SWSu8A=", "dev": true, "requires": { "agent-base": "^4.1.0", @@ -2503,7 +2503,7 @@ "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "integrity": "sha1-KXhx9jvlB63Pv8pxXQzQ7thOmmM=", "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" @@ -2575,7 +2575,7 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=", "dev": true }, "is-data-descriptor": { @@ -2601,7 +2601,7 @@ "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "requires": { "is-accessor-descriptor": "^0.1.6", @@ -2612,7 +2612,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true } } @@ -2641,14 +2641,14 @@ "is-my-ip-valid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "integrity": "sha1-ezUbjo7dTTmV1NBmaA5mTZRpaCQ=", "dev": true, "optional": true }, "is-my-json-valid": { "version": "2.17.2", "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz", - "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==", + "integrity": "sha1-ayEDoojpTvPeXPFdKd2F/Et41lw=", "dev": true, "optional": true, "requires": { @@ -2682,7 +2682,7 @@ "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", "dev": true, "requires": { "isobject": "^3.0.1" @@ -2711,7 +2711,7 @@ "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=", "dev": true }, "isarray": { @@ -2806,7 +2806,7 @@ "karma": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/karma/-/karma-2.0.4.tgz", - "integrity": "sha512-32yhTwoi6BZgJZhR78GwhzyFABbYG/1WwQqYgY7Vh96Demvua2jM3+FyRltIMTUH/Kd5xaQvDw2L7jTvkYFeXg==", + "integrity": "sha1-s5l4X1fpurHTxDhNsz/vTeyK40k=", "dev": true, "requires": { "bluebird": "^3.3.0", @@ -2841,7 +2841,7 @@ "karma-chrome-launcher": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", - "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "integrity": "sha1-zxudBxNswY/iOTJ9JGVMPbw2is8=", "dev": true, "requires": { "fs-access": "^1.0.0", @@ -2851,7 +2851,7 @@ "karma-edge-launcher": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/karma-edge-launcher/-/karma-edge-launcher-0.4.2.tgz", - "integrity": "sha512-YAJZb1fmRcxNhMIWYsjLuxwODBjh2cSHgTW/jkVmdpGguJjLbs9ZgIK/tEJsMQcBLUkO+yO4LBbqYxqgGW2HIw==", + "integrity": "sha1-PZUpsJsTyQnF887uEtAOf5qYmz0=", "dev": true, "requires": { "edge-launcher": "1.2.2" @@ -2860,7 +2860,7 @@ "karma-firefox-launcher": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.1.0.tgz", - "integrity": "sha512-LbZ5/XlIXLeQ3cqnCbYLn+rOVhuMIK9aZwlP6eOLGzWdo1UVp7t6CN3DP4SafiRLjexKwHeKHDm0c38Mtd3VxA==", + "integrity": "sha1-LEcDBFLwRTHrfRPU/HZpYwu5Mzk=", "dev": true }, "karma-ie-launcher": { @@ -2898,7 +2898,7 @@ "karma-sauce-launcher": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/karma-sauce-launcher/-/karma-sauce-launcher-1.2.0.tgz", - "integrity": "sha512-lEhtGRGS+3Yw6JSx/vJY9iQyHNtTjcojrSwNzqNUOaDceKDu9dPZqA/kr69bUO9G2T6GKbu8AZgXqy94qo31Jg==", + "integrity": "sha1-byVY3e889Wh5+idUDIrp+L/Ra8o=", "dev": true, "requires": { "q": "^1.5.0", @@ -2928,7 +2928,7 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true }, "lazystream": { @@ -2985,7 +2985,7 @@ "lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "integrity": "sha1-G3eTz3JZ6jj7NmHU04syYK+K5Oc=", "dev": true }, "lodash.debounce": { @@ -2997,7 +2997,7 @@ "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "integrity": "sha1-V0Dhxdbw39pK2TI7UzIQfva0xAo=", "dev": true, "requires": { "chalk": "^2.0.1" @@ -3006,7 +3006,7 @@ "log4js": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.10.0.tgz", - "integrity": "sha512-NnhN9PjFF9zhxinAjlmDYvkqqrIW+yA3LLJAoTJ3fs6d1zru86OqQHfsxiUcc1kRq3z+faGR4DeyXUfiNbVxKQ==", + "integrity": "sha1-SYC9kUigMNafnt3jKlsZwKVR4sQ=", "dev": true, "requires": { "amqplib": "^0.5.2", @@ -3227,7 +3227,7 @@ "lru-cache": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "integrity": "sha1-oRdc80lt/IQ2wVbDNLSVWZK85pw=", "dev": true, "optional": true, "requires": { @@ -3249,7 +3249,7 @@ "mailgun-js": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/mailgun-js/-/mailgun-js-0.18.1.tgz", - "integrity": "sha512-lvuMP14u24HS2uBsJEnzSyPMxzU2b99tQsIx1o6QNjqxjk8b3WvR+vq5oG1mjqz/IBYo+5gF+uSoDS0RkMVHmg==", + "integrity": "sha1-7jmqGNe7WYpc6e3oSvtoHe/IprA=", "dev": true, "optional": true, "requires": { @@ -3294,7 +3294,7 @@ "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=", "dev": true, "requires": { "arr-diff": "^4.0.0", @@ -3315,19 +3315,19 @@ "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", "dev": true }, "mime-db": { "version": "1.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "integrity": "sha1-o0kgUKXLm2NFBUHjnZeI0icng9s=", "dev": true }, "mime-types": { "version": "2.1.18", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "integrity": "sha1-bzI/YKg9ERRvgx/xH9ZuL+VQO7g=", "dev": true, "requires": { "mime-db": "~1.33.0" @@ -3351,7 +3351,7 @@ "mixin-deep": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "integrity": "sha1-pJ5yaNzhoNlpjkUybFYm3zVD0P4=", "dev": true, "requires": { "for-in": "^1.0.2", @@ -3361,7 +3361,7 @@ "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", "dev": true, "requires": { "is-plain-object": "^2.0.4" @@ -3395,7 +3395,7 @@ "msgpack5": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/msgpack5/-/msgpack5-4.2.0.tgz", - "integrity": "sha512-tQkRlwO4f3/E8Kq5qm6PcVw+J+K4+U/XNqeD9Ebo1qVsrjkcKb2FfmdtuuIslw42CGT+K3ZVKAvKfSPp3QRplQ==", + "integrity": "sha1-4AXsiTtx4RQLsXfy0fS38pAWlhE=", "requires": { "bl": "^2.0.0", "inherits": "^2.0.3", @@ -3406,7 +3406,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" } } }, @@ -3420,7 +3420,7 @@ "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "integrity": "sha1-uHqKpPwN6P5r6IiVs4mD/yZb0Rk=", "dev": true, "requires": { "arr-diff": "^4.0.0", @@ -3676,7 +3676,7 @@ "pac-proxy-agent": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-2.0.2.tgz", - "integrity": "sha512-cDNAN1Ehjbf5EHkNY5qnRhGPUCp6SnpyVof5fRzN800QV1Y2OkzbH9rmjZkbBRa8igof903yOnjIl6z0SlAhxA==", + "integrity": "sha1-kNn2cwqw9NJgfc3NTT1kGqJsOJY=", "dev": true, "optional": true, "requires": { @@ -3693,7 +3693,7 @@ "pac-resolver": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", - "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", + "integrity": "sha1-auoweH2wqJFwTet4AKcip2FabyY=", "dev": true, "optional": true, "requires": { @@ -3809,7 +3809,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=" }, "promisify-call": { "version": "2.0.4", @@ -3824,7 +3824,7 @@ "proxy-agent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-3.0.0.tgz", - "integrity": "sha512-g6n6vnk8fRf705ShN+FEXFG/SDJaW++lSs0d9KaJh4uBWW/wi7en4Cpo5VYQW3SZzAE121lhB/KLQrbURoubZw==", + "integrity": "sha1-9naOICiJsihdOZBtOpR2hBb49xM=", "dev": true, "optional": true, "requires": { @@ -3867,13 +3867,13 @@ "qjobs": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "integrity": "sha1-xF6cYYAL0IfviNfiVkI73Unl0HE=", "dev": true }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=", "dev": true }, "range-parser": { @@ -3885,7 +3885,7 @@ "raw-body": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "integrity": "sha1-GzJOzmtXBuFThVvBFIxlu39uoMM=", "dev": true, "requires": { "bytes": "3.0.0", @@ -3897,7 +3897,7 @@ "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -3923,7 +3923,7 @@ "redis": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", + "integrity": "sha1-ICKI4/WMSfYHnZevehDhMDrhSwI=", "dev": true, "optional": true, "requires": { @@ -3935,7 +3935,7 @@ "redis-commands": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz", - "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==", + "integrity": "sha1-RJWIlBTx6IYmEYCxRC5ylWAtg6I=", "dev": true, "optional": true }, @@ -3949,7 +3949,7 @@ "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "integrity": "sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw=", "dev": true, "requires": { "extend-shallow": "^3.0.2", @@ -3977,7 +3977,7 @@ "request": { "version": "2.87.0", "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", - "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", + "integrity": "sha1-MvACNc0I1IK00NaNuTqCnA7VdW4=", "dev": true, "optional": true, "requires": { @@ -4006,7 +4006,7 @@ "requestretry": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz", - "integrity": "sha512-Lmh9qMvnQXADGAQxsXHP4rbgO6pffCfuR8XUBdP9aitJcLQJxhp7YZK4xAVYXnPJ5E52mwrfiKQtKonPL8xsmg==", + "integrity": "sha1-IT7BAG7rdQ6LjOVBdig9FajVXZQ=", "dev": true, "optional": true, "requires": { @@ -4031,13 +4031,13 @@ "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "integrity": "sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w=", "dev": true }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", "dev": true, "requires": { "glob": "^7.0.5" @@ -4060,13 +4060,13 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=", "dev": true }, "sauce-connect-launcher": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sauce-connect-launcher/-/sauce-connect-launcher-1.2.4.tgz", - "integrity": "sha512-X2vfwulR6brUGiicXKxPm1GJ7dBEeP1II450Uv4bHGrcGOapZNgzJvn9aioea5IC5BPp/7qjKdE3xbbTBIVXMA==", + "integrity": "sha1-jTj4UkKp++3hsjA7VZ9+IMVgmhw=", "dev": true, "requires": { "adm-zip": "~0.4.3", @@ -4079,7 +4079,7 @@ "saucelabs": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.5.0.tgz", - "integrity": "sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ==", + "integrity": "sha1-lAWnPDYNRJsjKDmRmobDltN5/Z0=", "dev": true, "requires": { "https-proxy-agent": "^2.2.1" @@ -4088,7 +4088,7 @@ "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "integrity": "sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs=", "dev": true }, "set-immediate-shim": { @@ -4100,7 +4100,7 @@ "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "integrity": "sha1-ca5KiPD+77v1LR6mBPP7MV67YnQ=", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -4123,7 +4123,7 @@ "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=", "dev": true }, "slack-node": { @@ -4155,7 +4155,7 @@ "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "integrity": "sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0=", "dev": true, "requires": { "base": "^0.11.1", @@ -4206,7 +4206,7 @@ "snapdragon-node": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=", "dev": true, "requires": { "define-property": "^1.0.0", @@ -4226,7 +4226,7 @@ "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -4235,7 +4235,7 @@ "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -4244,7 +4244,7 @@ "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -4257,7 +4257,7 @@ "snapdragon-util": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=", "dev": true, "requires": { "kind-of": "^3.2.0" @@ -4349,7 +4349,7 @@ "socket.io-parser": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", - "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", + "integrity": "sha1-7S2l7nnxCVUDbj2kE7/X8eTYbI4=", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -4379,7 +4379,7 @@ "socks-proxy-agent": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz", - "integrity": "sha512-ZwEDymm204mTzvdqyUqOdovVr2YRd2NYskrYrF2LXyZ9qDiMAoFESGK8CRphiO7rtbo2Y757k2Nia3x2hGtalA==", + "integrity": "sha1-Lq58+OKoLTRWV2FTmn+XGMVhdlk=", "dev": true, "requires": { "agent-base": "^4.1.0", @@ -4395,7 +4395,7 @@ "source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "integrity": "sha1-cuLMNAlVQ+Q7LGKyxMENSpBU8lk=", "dev": true, "requires": { "atob": "^2.1.1", @@ -4424,7 +4424,7 @@ "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=", "dev": true, "requires": { "extend-shallow": "^3.0.0" @@ -4482,7 +4482,7 @@ "streamroller": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", - "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", + "integrity": "sha1-odG3z4PTmvsNYwSaWsv5NJO99ks=", "dev": true, "requires": { "date-format": "^1.2.0", @@ -4494,7 +4494,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "requires": { "safe-buffer": "~5.1.0" } @@ -4502,7 +4502,7 @@ "stringstream": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", - "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", + "integrity": "sha1-eIAiWw1K0Q4wkn0Weh1vL9OzOnI=", "dev": true }, "strip-ansi": { @@ -4546,7 +4546,7 @@ "tar-stream": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz", - "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==", + "integrity": "sha1-+E7xaWJp1iI8pI9uHu7eP36B85U=", "dev": true, "requires": { "bl": "^1.0.0", @@ -4561,7 +4561,7 @@ "bl": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "integrity": "sha1-oWCRFxcQPAdBDO9j71Gzl8Alr5w=", "dev": true, "requires": { "readable-stream": "^2.3.5", @@ -4587,7 +4587,7 @@ "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", "dev": true, "requires": { "os-tmpdir": "~1.0.2" @@ -4602,7 +4602,7 @@ "to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "integrity": "sha1-STvUj2LXxD/N7TE6A9ytsuEhOoA=", "dev": true }, "to-object-path": { @@ -4628,7 +4628,7 @@ "to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "integrity": "sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4=", "dev": true, "requires": { "define-property": "^2.0.2", @@ -4650,7 +4650,7 @@ "tough-cookie": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "integrity": "sha1-7GDO44rGdQY//JelwYlwV47oNlU=", "dev": true, "requires": { "punycode": "^1.4.1" @@ -4721,7 +4721,7 @@ "type-is": { "version": "1.6.16", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "integrity": "sha1-+JzjQVQcZysl7nrjxz3uOyvlAZQ=", "dev": true, "requires": { "media-typer": "0.3.0", @@ -4731,7 +4731,7 @@ "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "integrity": "sha1-n+FTahCmZKZSZqHjzPhf02MCvJw=", "dev": true }, "underscore": { @@ -4834,7 +4834,7 @@ "upath": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "integrity": "sha1-NSVll+RqWB20eT0M5H+prr/J+r0=", "dev": true }, "urix": { @@ -4846,7 +4846,7 @@ "use": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", - "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", + "integrity": "sha1-FHFr8D/f79AwQK71jYtLhfOnxUQ=", "dev": true, "requires": { "kind-of": "^6.0.2" @@ -4890,7 +4890,7 @@ "uws": { "version": "9.14.0", "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", - "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", + "integrity": "sha1-+sg4a+/DOno3BcvVjcR7Qwyk3ZU=", "dev": true, "optional": true }, @@ -4972,7 +4972,7 @@ "boom": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "integrity": "sha1-XdnabuOl8wIHdDYpDLcX0/SlTgI=", "dev": true, "requires": { "hoek": "4.x.x" @@ -4983,7 +4983,7 @@ "hawk": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "integrity": "sha1-r02RTrBl+bXOTZ0RwcshJu7MMDg=", "dev": true, "requires": { "boom": "4.x.x", @@ -4995,7 +4995,7 @@ "hoek": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "integrity": "sha1-ljRQKqEsRF3Vp8VzS1cruHOKrLs=", "dev": true }, "q": { @@ -5007,7 +5007,7 @@ "request": { "version": "2.85.0", "resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz", - "integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==", + "integrity": "sha1-WgNhWkfGFCCz65m326IE+DYD4fo=", "dev": true, "requires": { "aws-sign2": "~0.7.0", @@ -5037,7 +5037,7 @@ "sntp": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "integrity": "sha1-LGzsFP7cIiJznK+bXD2F0cxaLMg=", "dev": true, "requires": { "hoek": "4.x.x" @@ -5055,7 +5055,7 @@ "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=", "dev": true, "requires": { "isexe": "^2.0.0" @@ -5084,7 +5084,7 @@ "ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "integrity": "sha1-8c+E/i1ekB686U767OeF8YeiKPI=", "dev": true, "requires": { "async-limiter": "~1.0.0", diff --git a/samples/ClientSample/Program.cs b/samples/ClientSample/Program.cs index d049ce921a..0a581dbe6f 100644 --- a/samples/ClientSample/Program.cs +++ b/samples/ClientSample/Program.cs @@ -26,6 +26,8 @@ namespace ClientSample RawSample.Register(app); HubSample.Register(app); + StreamingSample.Register(app); + UploadSample.Register(app); app.Command("help", cmd => { diff --git a/samples/ClientSample/StreamingSample.cs b/samples/ClientSample/StreamingSample.cs new file mode 100644 index 0000000000..9ae84da9c2 --- /dev/null +++ b/samples/ClientSample/StreamingSample.cs @@ -0,0 +1,46 @@ +// 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; +using System.Threading.Tasks; +using Microsoft.AspNetCore.SignalR.Client; +using Microsoft.Extensions.CommandLineUtils; + +namespace ClientSample +{ + internal class StreamingSample + { + internal static void Register(CommandLineApplication app) + { + app.Command("streaming", cmd => + { + cmd.Description = "Tests a streaming connection to a hub"; + + var baseUrlArgument = cmd.Argument("", "The URL to the Chat Hub to test"); + + cmd.OnExecute(() => ExecuteAsync(baseUrlArgument.Value)); + }); + } + + public static async Task ExecuteAsync(string baseUrl) + { + var connection = new HubConnectionBuilder() + .WithUrl(baseUrl) + .Build(); + + await connection.StartAsync(); + + var reader = await connection.StreamAsChannelAsync("ChannelCounter", 10, 2000); + + while (await reader.WaitToReadAsync()) + { + while (reader.TryRead(out var item)) + { + Console.WriteLine($"received: {item}"); + } + } + + return 0; + } + } +} diff --git a/samples/ClientSample/UploadSample.cs b/samples/ClientSample/UploadSample.cs new file mode 100644 index 0000000000..b1b173b746 --- /dev/null +++ b/samples/ClientSample/UploadSample.cs @@ -0,0 +1,90 @@ +// 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.Collections.Generic; +using System.Diagnostics; +using System.Threading.Channels; +using System.Threading.Tasks; +using Microsoft.AspNetCore.SignalR.Client; +using Microsoft.Extensions.CommandLineUtils; + +namespace ClientSample +{ + internal class UploadSample + { + internal static void Register(CommandLineApplication app) + { + app.Command("uploading", cmd => + { + cmd.Description = "Tests a streaming invocation from client to hub"; + + var baseUrlArgument = cmd.Argument("", "The URL to the Chat Hub to test"); + + cmd.OnExecute(() => ExecuteAsync(baseUrlArgument.Value)); + }); + } + + public static async Task ExecuteAsync(string baseUrl) + { + var connection = new HubConnectionBuilder() + .WithUrl(baseUrl) + .Build(); + await connection.StartAsync(); + + await BasicInvoke(connection); + //await MultiParamInvoke(connection); + //await AdditionalArgs(connection); + + return 0; + } + + public static async Task BasicInvoke(HubConnection connection) + { + var channel = Channel.CreateUnbounded(); + var invokeTask = connection.InvokeAsync("UploadWord", channel.Reader); + + foreach (var c in "hello") + { + await channel.Writer.WriteAsync(c.ToString()); + } + channel.Writer.TryComplete(); + + var result = await invokeTask; + Debug.WriteLine($"You message was: {result}"); + } + + private static async Task WriteStreamAsync(IEnumerable sequence, ChannelWriter writer) + { + foreach (T element in sequence) + { + await writer.WriteAsync(element); + await Task.Delay(100); + } + + writer.TryComplete(); + } + + public static async Task MultiParamInvoke(HubConnection connection) + { + var letters = Channel.CreateUnbounded(); + var numbers = Channel.CreateUnbounded(); + + _ = WriteStreamAsync(new[] { "h", "i", "!" }, letters.Writer); + _ = WriteStreamAsync(new[] { 1, 2, 3, 4, 5 }, numbers.Writer); + + var result = await connection.InvokeAsync("DoubleStreamUpload", letters.Reader, numbers.Reader); + + Debug.WriteLine(result); + } + + public static async Task AdditionalArgs(HubConnection connection) + { + var channel = Channel.CreateUnbounded(); + _ = WriteStreamAsync("main message".ToCharArray(), channel.Writer); + + var result = await connection.InvokeAsync("UploadWithSuffix", channel.Reader, " + wooh I'm a suffix"); + Debug.WriteLine($"Your message was: {result}"); + } + } +} + diff --git a/samples/SignalRSamples/Hubs/UploadHub.cs b/samples/SignalRSamples/Hubs/UploadHub.cs new file mode 100644 index 0000000000..bd821b5066 --- /dev/null +++ b/samples/SignalRSamples/Hubs/UploadHub.cs @@ -0,0 +1,110 @@ +// 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; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Channels; +using System.Threading.Tasks; +using Microsoft.AspNetCore.SignalR; + +namespace SignalRSamples.Hubs +{ + public class UploadHub : Hub + { + public async Task DoubleStreamUpload(ChannelReader letters, ChannelReader numbers) + { + var total = await Sum(numbers); + var word = await UploadWord(letters); + + return string.Format("You sent over <{0}> <{1}s>", total, word); + } + + public async Task Sum(ChannelReader source) + { + var total = 0; + while (await source.WaitToReadAsync()) + { + while (source.TryRead(out var item)) + { + total += item; + } + } + return total; + } + + public async Task LocalSum(ChannelReader source) + { + var total = 0; + while (await source.WaitToReadAsync()) + { + while (source.TryRead(out var item)) + { + total += item; + } + } + Debug.WriteLine(String.Format("Complete, your total is <{0}>.", total)); + } + + public async Task UploadWord(ChannelReader source) + { + var sb = new StringBuilder(); + + // receiving a StreamCompleteMessage should cause this WaitToRead to return false + while (await source.WaitToReadAsync()) + { + while (source.TryRead(out var item)) + { + Debug.WriteLine($"received: {item}"); + Console.WriteLine($"received: {item}"); + sb.Append(item); + } + } + + // method returns, somewhere else returns a CompletionMessage with any errors + return sb.ToString(); + } + + public async Task UploadWithSuffix(ChannelReader source, string suffix) + { + var sb = new StringBuilder(); + + while (await source.WaitToReadAsync()) + { + while (source.TryRead(out var item)) + { + await Task.Delay(50); + Debug.WriteLine($"received: {item}"); + sb.Append(item); + } + } + + sb.Append(suffix); + + return sb.ToString(); + } + + public async Task UploadFile(ChannelReader source, string filepath) + { + var result = Enumerable.Empty(); + int chunk = 1; + + while (await source.WaitToReadAsync()) + { + while (source.TryRead(out var item)) + { + Debug.WriteLine($"received chunk #{chunk++}"); + result = result.Concat(item); // atrocious + await Task.Delay(50); + } + } + + File.WriteAllBytes(filepath, result.ToArray()); + + Debug.WriteLine("returning status code"); + return $"file written to '{filepath}'"; + } + } +} diff --git a/samples/SignalRSamples/Startup.cs b/samples/SignalRSamples/Startup.cs index e2cbd56b6a..89593f21cd 100644 --- a/samples/SignalRSamples/Startup.cs +++ b/samples/SignalRSamples/Startup.cs @@ -60,6 +60,7 @@ namespace SignalRSamples routes.MapHub("/dynamic"); routes.MapHub("/default"); routes.MapHub("/streaming"); + routes.MapHub("/uploading"); routes.MapHub("/hubT"); }); diff --git a/src/Common/ReflectionHelper.cs b/src/Common/ReflectionHelper.cs new file mode 100644 index 0000000000..eb11f635c1 --- /dev/null +++ b/src/Common/ReflectionHelper.cs @@ -0,0 +1,39 @@ +// 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; +using System.Collections.Generic; +using System.Text; +using System.Threading.Channels; + +namespace Microsoft.AspNetCore.SignalR +{ + internal static class ReflectionHelper + { + public static bool IsStreamingType(Type type) + { + // IMPORTANT !! + // All valid types must be generic + // because HubConnectionContext gets the generic argument and uses it to determine the expected item type of the stream + // The long-term solution is making a (streaming type => expected item type) method. + + if (!type.IsGenericType) + { + return false; + } + + // walk up inheritance chain, until parent is either null or a ChannelReader + // TODO #2594 - add Streams here, to make sending files easy + while (type != null) + { + if (type.GetGenericTypeDefinition() == typeof(ChannelReader<>)) + { + return true; + } + + type = type.BaseType; + } + return false; + } + } +} diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.Log.cs b/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.Log.cs index ed713cf001..8eafaedb20 100644 --- a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.Log.cs +++ b/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.Log.cs @@ -186,6 +186,18 @@ namespace Microsoft.AspNetCore.SignalR.Client private static readonly Action _unableToAcquireConnectionLockForPing = LoggerMessage.Define(LogLevel.Trace, new EventId(62, "UnableToAcquireConnectionLockForPing"), "Skipping ping because a send is already in progress."); + private static readonly Action _startingStream = + LoggerMessage.Define(LogLevel.Trace, new EventId(63, "StartingStream"), "Initiating stream '{StreamId}'."); + + private static readonly Action _sendingStreamItem = + LoggerMessage.Define(LogLevel.Trace, new EventId(64, "StreamItemSent"), "Sending item for stream '{StreamId}'."); + + private static readonly Action _cancelingStream = + LoggerMessage.Define(LogLevel.Trace, new EventId(65, "CancelingStream"), "Stream '{StreamId}' has been canceled by client."); + + private static readonly Action _completingStream = + LoggerMessage.Define(LogLevel.Trace, new EventId(66, "CompletingStream"), "Sending completion message for stream '{StreamId}'."); + public static void PreparingNonBlockingInvocation(ILogger logger, string target, int count) { _preparingNonBlockingInvocation(logger, target, count, null); @@ -496,6 +508,26 @@ namespace Microsoft.AspNetCore.SignalR.Client { _unableToAcquireConnectionLockForPing(logger, null); } + + public static void StartingStream(ILogger logger, string streamId) + { + _startingStream(logger, streamId, null); + } + + public static void SendingStreamItem(ILogger logger, string streamId) + { + _sendingStreamItem(logger, streamId, null); + } + + public static void CancelingStream(ILogger logger, string streamId) + { + _cancelingStream(logger, streamId, null); + } + + public static void CompletingStream(ILogger logger, string streamId) + { + _completingStream(logger, streamId, null); + } } } } diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.cs b/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.cs index 47f4adf4c6..634c5b8849 100644 --- a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.cs +++ b/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.cs @@ -7,6 +7,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; +using System.Linq; +using System.Reflection; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Channels; @@ -37,6 +39,8 @@ namespace Microsoft.AspNetCore.SignalR.Client // This lock protects the connection state. private readonly SemaphoreSlim _connectionLock = new SemaphoreSlim(1, 1); + private static readonly MethodInfo _sendStreamItemsMethod = typeof(HubConnection).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).Single(m => m.Name.Equals("SendStreamItems")); + // Persistent across all connections private readonly ILoggerFactory _loggerFactory; private readonly ILogger _logger; @@ -44,10 +48,13 @@ namespace Microsoft.AspNetCore.SignalR.Client private readonly IServiceProvider _serviceProvider; private readonly IConnectionFactory _connectionFactory; private readonly ConcurrentDictionary _handlers = new ConcurrentDictionary(StringComparer.Ordinal); + private long _nextActivationServerTimeout; private long _nextActivationSendPing; private bool _disposed; + private CancellationToken _uploadStreamToken; + private readonly ConnectionLogScope _logScope; // Transient state to a connection @@ -419,6 +426,7 @@ namespace Microsoft.AspNetCore.SignalR.Client CheckDisposed(); CheckConnectionActive(nameof(StreamAsChannelCoreAsync)); + // I just want an excuse to use 'irq' as a variable name... var irq = InvocationRequest.Stream(cancellationToken, returnType, _connectionState.GetNextId(), _loggerFactory, this, out channel); await InvokeStreamCore(methodName, irq, args, cancellationToken); @@ -435,9 +443,84 @@ namespace Microsoft.AspNetCore.SignalR.Client return channel; } + private Dictionary PackageStreamingParams(object[] args) + { + // lazy initialized, to avoid allocation unecessary dictionaries + Dictionary readers = null; + + for (var i = 0; i < args.Length; i++) + { + if (ReflectionHelper.IsStreamingType(args[i].GetType())) + { + if (readers == null) + { + readers = new Dictionary(); + } + + var id = _connectionState.GetNextStreamId(); + readers[id] = args[i]; + args[i] = new StreamPlaceholder(id); + + Log.StartingStream(_logger, id); + } + } + + return readers; + } + + private void LaunchStreams(Dictionary readers, CancellationToken cancellationToken) + { + if (readers == null) + { + // if there were no streaming parameters then readers is never initialized + return; + } + foreach (var kvp in readers) + { + var reader = kvp.Value; + + // For each stream that needs to be sent, run a "send items" task in the background. + // This reads from the channel, attaches streamId, and sends to server. + // A single background thread here quickly gets messy. + _ = _sendStreamItemsMethod + .MakeGenericMethod(reader.GetType().GetGenericArguments()) + .Invoke(this, new object[] { kvp.Key.ToString(), reader, cancellationToken }); + } + } + + // this is called via reflection using the `_sendStreamItems` field + private async Task SendStreamItems(string streamId, ChannelReader reader, CancellationToken token) + { + Log.StartingStream(_logger, streamId); + + var combinedToken = CancellationTokenSource.CreateLinkedTokenSource(_uploadStreamToken, token).Token; + + string responseError = null; + try + { + while (await reader.WaitToReadAsync(combinedToken)) + { + while (!combinedToken.IsCancellationRequested && reader.TryRead(out var item)) + { + await SendWithLock(new StreamDataMessage(streamId, item)); + Log.SendingStreamItem(_logger, streamId); + } + } + } + catch (OperationCanceledException) + { + Log.CancelingStream(_logger, streamId); + responseError = $"Stream canceled by client."; + } + + Log.CompletingStream(_logger, streamId); + await SendWithLock(new StreamCompleteMessage(streamId, responseError)); + } private async Task InvokeCoreAsyncCore(string methodName, Type returnType, object[] args, CancellationToken cancellationToken) { + var readers = PackageStreamingParams(args); + CheckDisposed(); await WaitConnectionLockAsync(); @@ -455,21 +538,20 @@ namespace Microsoft.AspNetCore.SignalR.Client ReleaseConnectionLock(); } - // Wait for this outside the lock, because it won't complete until the server responds. + LaunchStreams(readers, cancellationToken); + + // Wait for this outside the lock, because it won't complete until the server responds return await invocationTask; } private async Task InvokeCore(string methodName, InvocationRequest irq, object[] args, CancellationToken cancellationToken) { - AssertConnectionValid(); - Log.PreparingBlockingInvocation(_logger, irq.InvocationId, methodName, irq.ResultType.FullName, args.Length); // Client invocations are always blocking var invocationMessage = new InvocationMessage(irq.InvocationId, methodName, args); Log.RegisteringInvocation(_logger, invocationMessage.InvocationId); - _connectionState.AddInvocation(irq); // Trace the full invocation @@ -495,7 +577,6 @@ namespace Microsoft.AspNetCore.SignalR.Client var invocationMessage = new StreamInvocationMessage(irq.InvocationId, methodName, args); - // I just want an excuse to use 'irq' as a variable name... Log.RegisteringInvocation(_logger, invocationMessage.InvocationId); _connectionState.AddInvocation(irq); @@ -525,28 +606,33 @@ namespace Microsoft.AspNetCore.SignalR.Client // REVIEW: If a token is passed in and is canceled during FlushAsync it seems to break .Complete()... await _connectionState.Connection.Transport.Output.FlushAsync(); + Log.MessageSent(_logger, hubMessage); // We've sent a message, so don't ping for a while ResetSendPing(); - - Log.MessageSent(_logger, hubMessage); } private async Task SendCoreAsyncCore(string methodName, object[] args, CancellationToken cancellationToken) { - CheckDisposed(); + var readers = PackageStreamingParams(args); + Log.PreparingNonBlockingInvocation(_logger, methodName, args.Length); + + var invocationMessage = new InvocationMessage(null, methodName, args); + await SendWithLock(invocationMessage, callerName: nameof(SendCoreAsync)); + + LaunchStreams(readers, cancellationToken); + } + + private async Task SendWithLock(HubMessage message, CancellationToken cancellationToken = default, [CallerMemberName] string callerName = "") + { + CheckDisposed(); await WaitConnectionLockAsync(); try { + CheckConnectionActive(callerName); CheckDisposed(); - CheckConnectionActive(nameof(SendCoreAsync)); - - Log.PreparingNonBlockingInvocation(_logger, methodName, args.Length); - - var invocationMessage = new InvocationMessage(null, methodName, args); - - await SendHubMessage(invocationMessage, cancellationToken); + await SendHubMessage(message, cancellationToken); } finally { @@ -575,15 +661,15 @@ namespace Microsoft.AspNetCore.SignalR.Client if (!connectionState.TryRemoveInvocation(completion.InvocationId, out irq)) { Log.DroppedCompletionMessage(_logger, completion.InvocationId); + break; } - else - { - DispatchInvocationCompletion(completion, irq); - irq.Dispose(); - } + + DispatchInvocationCompletion(completion, irq); + irq.Dispose(); + break; case StreamItemMessage streamItem: - // Complete the invocation with an error, we don't support streaming (yet) + // if there's no open StreamInvocation with the given id, then complete with an error if (!connectionState.TryGetInvocation(streamItem.InvocationId, out irq)) { Log.DroppedStreamMessage(_logger, streamItem.InvocationId); @@ -767,6 +853,9 @@ namespace Microsoft.AspNetCore.SignalR.Client var timer = new TimerAwaitable(TickRate, TickRate); _ = TimerLoop(timer); + var uploadStreamSource = new CancellationTokenSource(); + _uploadStreamToken = uploadStreamSource.Token; + try { while (true) @@ -834,6 +923,7 @@ namespace Microsoft.AspNetCore.SignalR.Client finally { timer.Stop(); + uploadStreamSource.Cancel(); } // Clear the connectionState field @@ -916,11 +1006,6 @@ namespace Microsoft.AspNetCore.SignalR.Client private void OnServerTimeout() { - if (Debugger.IsAttached) - { - return; - } - _connectionState.CloseException = new TimeoutException( $"Server timeout ({ServerTimeout.TotalMilliseconds:0.00}ms) elapsed without receiving a message from the server."); _connectionState.Connection.Transport.Input.CancelPendingRead(); @@ -1104,7 +1189,8 @@ namespace Microsoft.AspNetCore.SignalR.Client private TaskCompletionSource _stopTcs; private readonly object _lock = new object(); private readonly Dictionary _pendingCalls = new Dictionary(StringComparer.Ordinal); - private int _nextId; + private int _nextInvocationId; + private int _nextStreamId; public ConnectionContext Connection { get; } public Task ReceiveTask { get; set; } @@ -1125,7 +1211,8 @@ namespace Microsoft.AspNetCore.SignalR.Client Connection = connection; } - public string GetNextId() => Interlocked.Increment(ref _nextId).ToString(CultureInfo.InvariantCulture); + public string GetNextId() => Interlocked.Increment(ref _nextInvocationId).ToString(CultureInfo.InvariantCulture); + public string GetNextStreamId() => Interlocked.Increment(ref _nextStreamId).ToString(CultureInfo.InvariantCulture); public void AddInvocation(InvocationRequest irq) { @@ -1232,6 +1319,18 @@ namespace Microsoft.AspNetCore.SignalR.Client return irq.ResultType; } + Type IInvocationBinder.GetStreamItemType(string invocationId) + { + // previously, streaming was only server->client, and used GetReturnType for StreamItems + // literally the same code as the above method + if (!TryGetInvocation(invocationId, out var irq)) + { + Log.ReceivedUnexpectedResponse(_hubConnection._logger, invocationId); + return null; + } + return irq.ResultType; + } + IReadOnlyList IInvocationBinder.GetParameterTypes(string methodName) { if (!_hubConnection._handlers.TryGetValue(methodName, out var invocationHandlerList)) diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/Microsoft.AspNetCore.SignalR.Client.Core.csproj b/src/Microsoft.AspNetCore.SignalR.Client.Core/Microsoft.AspNetCore.SignalR.Client.Core.csproj index 8cbe6845a4..bc9ad15161 100644 --- a/src/Microsoft.AspNetCore.SignalR.Client.Core/Microsoft.AspNetCore.SignalR.Client.Core.csproj +++ b/src/Microsoft.AspNetCore.SignalR.Client.Core/Microsoft.AspNetCore.SignalR.Client.Core.csproj @@ -10,6 +10,7 @@ + diff --git a/src/Microsoft.AspNetCore.SignalR.Common/IInvocationBinder.cs b/src/Microsoft.AspNetCore.SignalR.Common/IInvocationBinder.cs index 4e8fd1bcb5..2f1ba139c3 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/IInvocationBinder.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/IInvocationBinder.cs @@ -10,5 +10,6 @@ namespace Microsoft.AspNetCore.SignalR { Type GetReturnType(string invocationId); IReadOnlyList GetParameterTypes(string methodName); + Type GetStreamItemType(string streamId); } } diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolConstants.cs b/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolConstants.cs index ce1e3cbfd5..25fbf6dbbc 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolConstants.cs +++ b/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolConstants.cs @@ -42,5 +42,15 @@ namespace Microsoft.AspNetCore.SignalR.Protocol /// Represents the close message type. /// public const int CloseMessageType = 7; + + /// + /// Represents the stream complete message type. + /// + public const int StreamCompleteMessageType = 8; + + /// + /// Same as StreamItemMessage, except + /// + public const int StreamDataMessageType = 9; } } diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamBindingFailureMessage.cs b/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamBindingFailureMessage.cs new file mode 100644 index 0000000000..571e1fdc39 --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamBindingFailureMessage.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Runtime.ExceptionServices; +using System.Text; + +namespace Microsoft.AspNetCore.SignalR.Protocol +{ + /// + /// Represents a failure to bind arguments for a StreamDataMessage. This does not represent an actual + /// message that is sent on the wire, it is returned by + /// to indicate that a binding failure occurred when parsing a StreamDataMessage. The stream ID is associated + /// so that the error can be sent to the relevant hub method. + /// + public class StreamBindingFailureMessage : HubMessage + { + /// + /// Gets the id of the relevant stream + /// + public string Id { get; } + + /// + /// Gets the exception thrown during binding. + /// + public ExceptionDispatchInfo BindingFailure { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The stream ID. + /// The exception thrown during binding. + public StreamBindingFailureMessage(string id, ExceptionDispatchInfo bindingFailure) + { + Id = id; + BindingFailure = bindingFailure; + } + } +} diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamCompleteMessage.cs b/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamCompleteMessage.cs new file mode 100644 index 0000000000..587764aa72 --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamCompleteMessage.cs @@ -0,0 +1,41 @@ +// 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; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.AspNetCore.SignalR.Protocol +{ + /// + /// A message for indicating that a particular stream has ended. + /// + public class StreamCompleteMessage : HubMessage + { + /// + /// Gets the stream id. + /// + public string StreamId { get; } + + /// + /// Gets the error. Will be null if there is no error. + /// + public string Error { get; } + + /// + /// Whether the message has an error. + /// + public bool HasError { get => Error != null; } + + /// + /// Initializes a new instance of + /// + /// The streamId of the stream to complete. + /// An optional error field. + public StreamCompleteMessage(string streamId, string error = null) + { + StreamId = streamId; + Error = error; + } + } +} diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamDataMessage.cs b/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamDataMessage.cs new file mode 100644 index 0000000000..6862ed96a2 --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamDataMessage.cs @@ -0,0 +1,33 @@ +// 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. + +namespace Microsoft.AspNetCore.SignalR.Protocol +{ + /// + /// Sent to parameter streams. + /// Similar to , except the data is sent to a parameter stream, rather than in response to an invocation. + /// + public class StreamDataMessage : HubMessage + { + /// + /// The piece of data this message carries. + /// + public object Item { get; } + + /// + /// The stream to which to deliver data. + /// + public string StreamId { get; } + + public StreamDataMessage(string streamId, object item) + { + StreamId = streamId; + Item = item; + } + + public override string ToString() + { + return $"StreamDataMessage {{ {nameof(StreamId)}: \"{StreamId}\", {nameof(Item)}: {Item ?? "<>"} }}"; + } + } +} diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamPlaceholder.cs b/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamPlaceholder.cs new file mode 100644 index 0000000000..f111e90cba --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamPlaceholder.cs @@ -0,0 +1,25 @@ +// 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; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.AspNetCore.SignalR.Protocol +{ + /// + /// Used by protocol serializers/deserializers to transfer information about streaming parameters. + /// Is packed as an argument in the form `{"streamId": "42"}`, and sent over wire. + /// Is then unpacked on the other side, and a new channel is created and saved under the streamId. + /// Then, each is routed to the appropiate channel based on streamId. + /// + public class StreamPlaceholder + { + public string StreamId { get; private set; } + + public StreamPlaceholder(string streamId) + { + StreamId = streamId; + } + } +} diff --git a/src/Microsoft.AspNetCore.SignalR.Common/breakingchanges.netcore.json b/src/Microsoft.AspNetCore.SignalR.Common/breakingchanges.netcore.json index 3cd71f82e7..ac9bc43e9f 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/breakingchanges.netcore.json +++ b/src/Microsoft.AspNetCore.SignalR.Common/breakingchanges.netcore.json @@ -8,5 +8,10 @@ "TypeId": "public interface Microsoft.AspNetCore.SignalR.Protocol.IHubProtocol", "MemberId": "System.Int32 get_MinorVersion()", "Kind": "Addition" + }, + { + "TypeId": "public interface Microsoft.AspNetCore.SignalR.IInvocationBinder", + "MemberId": "System.Type GetStreamItemType(System.String streamId)", + "Kind": "Addition" } ] \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs b/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs index 5aaa164cea..14a2fa6ac4 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs @@ -21,6 +21,7 @@ namespace Microsoft.AspNetCore.SignalR { public class HubConnectionContext { + private StreamTracker _streamTracker; private static readonly WaitCallback _abortedCallback = AbortConnection; private readonly ConnectionContext _connectionContext; @@ -54,6 +55,18 @@ namespace Microsoft.AspNetCore.SignalR _clientTimeoutInterval = clientTimeoutInterval.Ticks; } + internal StreamTracker StreamTracker + { + get + { + // lazy for performance reasons + if (_streamTracker == null) + { + _streamTracker = new StreamTracker(); + } + return _streamTracker; + } + } /// /// Initializes a new instance of the class. /// diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionHandler.cs b/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionHandler.cs index 9211fda589..85e765571c 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionHandler.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionHandler.cs @@ -186,6 +186,9 @@ namespace Microsoft.AspNetCore.SignalR { var input = connection.Input; var protocol = connection.Protocol; + + var binder = new HubConnectionBinder(_dispatcher, connection); + while (true) { var result = await input.ReadAsync(); @@ -202,7 +205,7 @@ namespace Microsoft.AspNetCore.SignalR { connection.ResetClientTimeout(); - while (protocol.TryParseMessage(ref buffer, _dispatcher, out var message)) + while (protocol.TryParseMessage(ref buffer, binder, out var message)) { await _dispatcher.DispatchMessageAsync(connection, message); } diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.Log.cs b/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.Log.cs index 9e05de55d2..096b4ec229 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.Log.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.Log.cs @@ -57,6 +57,18 @@ namespace Microsoft.AspNetCore.SignalR.Internal private static readonly Action _invalidReturnValueFromStreamingMethod = LoggerMessage.Define(LogLevel.Error, new EventId(15, "InvalidReturnValueFromStreamingMethod"), "A streaming method returned a value that cannot be used to build enumerator {HubMethod}."); + private static readonly Action _receivedStreamItem = + LoggerMessage.Define(LogLevel.Trace, new EventId(16, "ReceivedStreamItem"), "Received item for stream '{StreamId}'."); + + private static readonly Action _startingParameterStream = + LoggerMessage.Define(LogLevel.Trace, new EventId(17, "StartingParameterStream"), "Creating streaming parameter channel '{StreamId}'."); + + private static readonly Action _completingStream = + LoggerMessage.Define(LogLevel.Trace, new EventId(18, "CompletingStream"), "Stream '{StreamId}' has been completed by client."); + + private static readonly Action _closingStreamWithBindingError = + LoggerMessage.Define(LogLevel.Warning, new EventId(19, "ClosingStreamWithBindingError"), "Stream '{StreamId}' closed with error '{Error}'."); + public static void ReceivedHubInvocation(ILogger logger, InvocationMessage invocationMessage) { _receivedHubInvocation(logger, invocationMessage, null); @@ -133,6 +145,26 @@ namespace Microsoft.AspNetCore.SignalR.Internal { _invalidReturnValueFromStreamingMethod(logger, hubMethod, null); } + + public static void ReceivedStreamItem(ILogger logger, StreamDataMessage message) + { + _receivedStreamItem(logger, message.StreamId, null); + } + + public static void StartingParameterStream(ILogger logger, string streamId) + { + _startingParameterStream(logger, streamId, null); + } + + public static void CompletingStream(ILogger logger, StreamCompleteMessage message) + { + _completingStream(logger, message.StreamId, null); + } + + public static void ClosingStreamWithBindingError(ILogger logger, StreamCompleteMessage message) + { + _closingStreamWithBindingError(logger, message.StreamId, message.Error, null); + } } } } diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.cs b/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.cs index 4f1fc15668..5a927ffc71 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.cs @@ -81,15 +81,18 @@ namespace Microsoft.AspNetCore.SignalR.Internal switch (hubMessage) { case InvocationBindingFailureMessage bindingFailureMessage: - return ProcessBindingFailure(connection, bindingFailureMessage); + return ProcessInvocationBindingFailure(connection, bindingFailureMessage); + + case StreamBindingFailureMessage bindingFailureMessage: + return ProcessStreamBindingFailure(connection, bindingFailureMessage); case InvocationMessage invocationMessage: Log.ReceivedHubInvocation(_logger, invocationMessage); - return ProcessInvocation(connection, invocationMessage, isStreamedInvocation: false); + return ProcessInvocation(connection, invocationMessage, isStreamResponse: false); case StreamInvocationMessage streamInvocationMessage: Log.ReceivedStreamHubInvocation(_logger, streamInvocationMessage); - return ProcessInvocation(connection, streamInvocationMessage, isStreamedInvocation: true); + return ProcessInvocation(connection, streamInvocationMessage, isStreamResponse: true); case CancelInvocationMessage cancelInvocationMessage: // Check if there is an associated active stream and cancel it if it exists. @@ -110,6 +113,17 @@ namespace Microsoft.AspNetCore.SignalR.Internal connection.StartClientTimeout(); break; + case StreamDataMessage streamItem: + Log.ReceivedStreamItem(_logger, streamItem); + return ProcessStreamItem(connection, streamItem); + + case StreamCompleteMessage streamCompleteMessage: + // closes channels, removes from Lookup dict + // user's method can see the channel is complete and begin wrapping up + Log.CompletingStream(_logger, streamCompleteMessage); + connection.StreamTracker.Complete(streamCompleteMessage); + break; + // Other kind of message we weren't expecting default: Log.UnsupportedMessageReceived(_logger, hubMessage.GetType().FullName); @@ -119,30 +133,37 @@ namespace Microsoft.AspNetCore.SignalR.Internal return Task.CompletedTask; } - private Task ProcessBindingFailure(HubConnectionContext connection, InvocationBindingFailureMessage bindingFailureMessage) + private Task ProcessInvocationBindingFailure(HubConnectionContext connection, InvocationBindingFailureMessage bindingFailureMessage) { Log.FailedInvokingHubMethod(_logger, bindingFailureMessage.Target, bindingFailureMessage.BindingFailure.SourceException); + + var errorMessage = ErrorMessageHelper.BuildErrorMessage($"Failed to invoke '{bindingFailureMessage.Target}' due to an error on the server.", bindingFailureMessage.BindingFailure.SourceException, _enableDetailedErrors); return SendInvocationError(bindingFailureMessage.InvocationId, connection, errorMessage); } - public override Type GetReturnType(string invocationId) + private Task ProcessStreamBindingFailure(HubConnectionContext connection, StreamBindingFailureMessage bindingFailureMessage) { - return typeof(object); + var errorString = ErrorMessageHelper.BuildErrorMessage( + $"Failed to bind Stream Item arguments to proper type.", + bindingFailureMessage.BindingFailure.SourceException, _enableDetailedErrors); + + var message = new StreamCompleteMessage(bindingFailureMessage.Id, errorString); + Log.ClosingStreamWithBindingError(_logger, message); + connection.StreamTracker.Complete(message); + + return Task.CompletedTask; } - public override IReadOnlyList GetParameterTypes(string methodName) + private Task ProcessStreamItem(HubConnectionContext connection, StreamDataMessage message) { - if (!_methods.TryGetValue(methodName, out var descriptor)) - { - return Type.EmptyTypes; - } - return descriptor.ParameterTypes; + Log.ReceivedStreamItem(_logger, message); + return connection.StreamTracker.ProcessItem(message); } private Task ProcessInvocation(HubConnectionContext connection, - HubMethodInvocationMessage hubMethodInvocationMessage, bool isStreamedInvocation) + HubMethodInvocationMessage hubMethodInvocationMessage, bool isStreamResponse) { if (!_methods.TryGetValue(hubMethodInvocationMessage.Target, out var descriptor)) { @@ -153,12 +174,17 @@ namespace Microsoft.AspNetCore.SignalR.Internal } else { - return Invoke(descriptor, connection, hubMethodInvocationMessage, isStreamedInvocation); + bool isStreamCall = descriptor.HasStreamingParameters; + if (isStreamResponse && isStreamCall) + { + throw new NotSupportedException("Streaming responses for streaming uploads are not supported."); + } + return Invoke(descriptor, connection, hubMethodInvocationMessage, isStreamResponse, isStreamCall); } } private async Task Invoke(HubMethodDescriptor descriptor, HubConnectionContext connection, - HubMethodInvocationMessage hubMethodInvocationMessage, bool isStreamedInvocation) + HubMethodInvocationMessage hubMethodInvocationMessage, bool isStreamResponse, bool isStreamCall) { var methodExecutor = descriptor.MethodExecutor; @@ -176,7 +202,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal return; } - if (!await ValidateInvocationMode(descriptor, isStreamedInvocation, hubMethodInvocationMessage, connection)) + if (!await ValidateInvocationMode(descriptor, isStreamResponse, hubMethodInvocationMessage, connection)) { return; } @@ -184,33 +210,73 @@ namespace Microsoft.AspNetCore.SignalR.Internal hubActivator = scope.ServiceProvider.GetRequiredService>(); hub = hubActivator.Create(); + if (isStreamCall) + { + // swap out placeholders for channels + var args = hubMethodInvocationMessage.Arguments; + for (int i = 0; i < args.Length; i++) + { + var placeholder = args[i] as StreamPlaceholder; + if (placeholder == null) + { + continue; + } + + Log.StartingParameterStream(_logger, placeholder.StreamId); + var itemType = methodExecutor.MethodParameters[i].ParameterType.GetGenericArguments()[0]; + args[i] = connection.StreamTracker.AddStream(placeholder.StreamId, itemType); + } + } + try { InitializeHub(hub, connection); + Task invocation = null; - var result = await ExecuteHubMethod(methodExecutor, hub, hubMethodInvocationMessage.Arguments); - - if (isStreamedInvocation) + if (isStreamResponse) { + var result = await ExecuteHubMethod(methodExecutor, hub, hubMethodInvocationMessage.Arguments); + if (!TryGetStreamingEnumerator(connection, hubMethodInvocationMessage.InvocationId, descriptor, result, out var enumerator, out var streamCts)) { Log.InvalidReturnValueFromStreamingMethod(_logger, methodExecutor.MethodInfo.Name); - await SendInvocationError(hubMethodInvocationMessage.InvocationId, connection, $"The value returned by the streaming method '{methodExecutor.MethodInfo.Name}' is not a ChannelReader<>."); return; } - disposeScope = false; Log.StreamingResult(_logger, hubMethodInvocationMessage.InvocationId, methodExecutor); - // Fire-and-forget stream invocations, otherwise they would block other hub invocations from being able to run _ = StreamResultsAsync(hubMethodInvocationMessage.InvocationId, connection, enumerator, scope, hubActivator, hub, streamCts); } - // Non-empty/null InvocationId ==> Blocking invocation that needs a response - else if (!string.IsNullOrEmpty(hubMethodInvocationMessage.InvocationId)) + + else if (string.IsNullOrEmpty(hubMethodInvocationMessage.InvocationId)) { - Log.SendingResult(_logger, hubMethodInvocationMessage.InvocationId, methodExecutor); - await connection.WriteAsync(CompletionMessage.WithResult(hubMethodInvocationMessage.InvocationId, result)); + // Send Async, no response expected + invocation = ExecuteHubMethod(methodExecutor, hub, hubMethodInvocationMessage.Arguments); + } + + else + { + // Invoke Async, one reponse expected + async Task ExecuteInvocation() + { + var result = await ExecuteHubMethod(methodExecutor, hub, hubMethodInvocationMessage.Arguments); + Log.SendingResult(_logger, hubMethodInvocationMessage.InvocationId, methodExecutor); + await connection.WriteAsync(CompletionMessage.WithResult(hubMethodInvocationMessage.InvocationId, result)); + } + invocation = ExecuteInvocation(); + } + + if (isStreamCall || isStreamResponse) + { + // don't await streaming invocations + // leave them running in the background, allowing dispatcher to process other messages between streaming items + disposeScope = false; + } + else + { + // complete the non-streaming calls now + await invocation; } } catch (TargetInvocationException ex) @@ -236,7 +302,8 @@ namespace Microsoft.AspNetCore.SignalR.Internal } } - private async Task StreamResultsAsync(string invocationId, HubConnectionContext connection, IAsyncEnumerator enumerator, IServiceScope scope, IHubActivator hubActivator, THub hub, CancellationTokenSource streamCts) + private async Task StreamResultsAsync(string invocationId, HubConnectionContext connection, IAsyncEnumerator enumerator, IServiceScope scope, + IHubActivator hubActivator, THub hub, CancellationTokenSource streamCts) { string error = null; @@ -424,5 +491,15 @@ namespace Microsoft.AspNetCore.SignalR.Internal Log.HubMethodBound(_logger, hubName, methodName); } } + + public override IReadOnlyList GetParameterTypes(string methodName) + { + if (!_methods.TryGetValue(methodName, out var descriptor)) + { + return Type.EmptyTypes; + } + + return descriptor.ParameterTypes; + } } } diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubConnectionBinder.cs b/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubConnectionBinder.cs new file mode 100644 index 0000000000..dcd4bd5c7d --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubConnectionBinder.cs @@ -0,0 +1,36 @@ +// 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; +using System.Collections.Generic; +using Microsoft.AspNetCore.SignalR.Internal; + +namespace Microsoft.AspNetCore.SignalR.Internal +{ + internal class HubConnectionBinder : IInvocationBinder where THub : Hub + { + private HubDispatcher _dispatcher; + private HubConnectionContext _connection; + + public HubConnectionBinder(HubDispatcher dispatcher, HubConnectionContext connection) + { + _dispatcher = dispatcher; + _connection = connection; + } + + public IReadOnlyList GetParameterTypes(string methodName) + { + return _dispatcher.GetParameterTypes(methodName); + } + + public Type GetReturnType(string invocationId) + { + return typeof(object); + } + + public Type GetStreamItemType(string streamId) + { + return _connection.StreamTracker.GetStreamItemType(streamId); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubDispatcher.cs b/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubDispatcher.cs index 5d787fb476..9bd545da50 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubDispatcher.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubDispatcher.cs @@ -8,12 +8,11 @@ using Microsoft.AspNetCore.SignalR.Protocol; namespace Microsoft.AspNetCore.SignalR.Internal { - public abstract class HubDispatcher : IInvocationBinder where THub : Hub + public abstract class HubDispatcher where THub : Hub { public abstract Task OnConnectedAsync(HubConnectionContext connection); public abstract Task OnDisconnectedAsync(HubConnectionContext connection, Exception exception); public abstract Task DispatchMessageAsync(HubConnectionContext connection, HubMessage hubMessage); - public abstract IReadOnlyList GetParameterTypes(string methodName); - public abstract Type GetReturnType(string invocationId); + public abstract IReadOnlyList GetParameterTypes(string name); } } diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubMethodDescriptor.cs b/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubMethodDescriptor.cs index a15dce772e..b942279e46 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubMethodDescriptor.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubMethodDescriptor.cs @@ -9,6 +9,7 @@ using System.Reflection; using System.Threading; using System.Threading.Channels; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.SignalR.Protocol; using Microsoft.Extensions.Internal; namespace Microsoft.AspNetCore.SignalR.Internal @@ -22,7 +23,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal public HubMethodDescriptor(ObjectMethodExecutor methodExecutor, IEnumerable policies) { MethodExecutor = methodExecutor; - ParameterTypes = methodExecutor.MethodParameters.Select(p => p.ParameterType).ToArray(); + ParameterTypes = methodExecutor.MethodParameters.Select(GetParameterType).ToArray(); Policies = policies.ToArray(); NonAsyncReturnType = (MethodExecutor.IsMethodAsync) @@ -36,6 +37,8 @@ namespace Microsoft.AspNetCore.SignalR.Internal } } + public bool HasStreamingParameters { get; private set; } + private Func> _convertToEnumerator; public ObjectMethodExecutor MethodExecutor { get; } @@ -52,6 +55,17 @@ namespace Microsoft.AspNetCore.SignalR.Internal public IList Policies { get; } + private Type GetParameterType(ParameterInfo p) + { + var type = p.ParameterType; + if (ReflectionHelper.IsStreamingType(type)) + { + HasStreamingParameters = true; + return typeof(StreamPlaceholder); + } + return type; + } + private static bool IsChannelType(Type type, out Type payloadType) { var channelType = type.AllBaseTypes().FirstOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(ChannelReader<>)); diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Microsoft.AspNetCore.SignalR.Core.csproj b/src/Microsoft.AspNetCore.SignalR.Core/Microsoft.AspNetCore.SignalR.Core.csproj index d63b5aed42..012aca906c 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/Microsoft.AspNetCore.SignalR.Core.csproj +++ b/src/Microsoft.AspNetCore.SignalR.Core/Microsoft.AspNetCore.SignalR.Core.csproj @@ -6,6 +6,10 @@ Microsoft.AspNetCore.SignalR + + + + diff --git a/src/Microsoft.AspNetCore.SignalR.Core/StreamTracker.cs b/src/Microsoft.AspNetCore.SignalR.Core/StreamTracker.cs new file mode 100644 index 0000000000..3d36e38c0b --- /dev/null +++ b/src/Microsoft.AspNetCore.SignalR.Core/StreamTracker.cs @@ -0,0 +1,105 @@ +// 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; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading.Channels; +using System.Threading.Tasks; +using Microsoft.AspNetCore.SignalR.Protocol; + +namespace Microsoft.AspNetCore.SignalR +{ + internal class StreamTracker + { + private static readonly MethodInfo _buildConverterMethod = typeof(StreamTracker).GetMethods(BindingFlags.NonPublic | BindingFlags.Static).Single(m => m.Name.Equals("BuildStream")); + private ConcurrentDictionary _lookup = new ConcurrentDictionary(); + + /// + /// Creates a new stream and returns the ChannelReader for it as an object. + /// + public object AddStream(string streamId, Type itemType) + { + var newConverter = (IStreamConverter)_buildConverterMethod.MakeGenericMethod(itemType).Invoke(null, Array.Empty()); + _lookup[streamId] = newConverter; + return newConverter.GetReaderAsObject(); + } + + private IStreamConverter TryGetConverter(string streamId) + { + if (_lookup.TryGetValue(streamId, out var converter)) + { + return converter; + } + else + { + throw new KeyNotFoundException($"No stream with id '{streamId}' could be found."); + } + } + + public Task ProcessItem(StreamDataMessage message) + { + return TryGetConverter(message.StreamId).WriteToStream(message.Item); + } + + public Type GetStreamItemType(string streamId) + { + return TryGetConverter(streamId).GetItemType(); + } + + public void Complete(StreamCompleteMessage message) + { + _lookup.TryRemove(message.StreamId, out var converter); + if (converter == null) + { + throw new KeyNotFoundException($"No stream with id '{message.StreamId}' could be found."); + } + converter.TryComplete(message.HasError ? new Exception(message.Error) : null); + } + + private static IStreamConverter BuildStream() + { + return new ChannelConverter(); + } + + private interface IStreamConverter + { + Type GetItemType(); + object GetReaderAsObject(); + Task WriteToStream(object item); + void TryComplete(Exception ex); + } + + private class ChannelConverter : IStreamConverter + { + private Channel _channel; + + public ChannelConverter() + { + _channel = Channel.CreateUnbounded(); + } + + public Type GetItemType() + { + return typeof(T); + } + + public object GetReaderAsObject() + { + return _channel.Reader; + } + + public Task WriteToStream(object o) + { + return _channel.Writer.WriteAsync((T)o).AsTask(); + } + + public void TryComplete(Exception ex) + { + _channel.Writer.TryComplete(ex); + } + } + } +} diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj b/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj index 47f37af697..7daf883097 100644 --- a/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj +++ b/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj @@ -1,4 +1,4 @@ - + Implements the SignalR Hub Protocol over JSON. diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Protocol/JsonHubProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Protocol/JsonHubProtocol.cs index 54400a2199..8436d0aa68 100644 --- a/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Protocol/JsonHubProtocol.cs +++ b/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Protocol/JsonHubProtocol.cs @@ -24,6 +24,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol private const string ResultPropertyName = "result"; private const string ItemPropertyName = "item"; private const string InvocationIdPropertyName = "invocationId"; + private const string StreamIdPropertyName = "streamId"; private const string TypePropertyName = "type"; private const string ErrorPropertyName = "error"; private const string TargetPropertyName = "target"; @@ -119,6 +120,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol int? type = null; string invocationId = null; + string streamId = null; string target = null; string error = null; var hasItem = false; @@ -165,6 +167,9 @@ namespace Microsoft.AspNetCore.SignalR.Protocol case InvocationIdPropertyName: invocationId = JsonUtils.ReadAsString(reader, InvocationIdPropertyName); break; + case StreamIdPropertyName: + streamId = JsonUtils.ReadAsString(reader, StreamIdPropertyName); + break; case TargetPropertyName: target = JsonUtils.ReadAsString(reader, TargetPropertyName); break; @@ -199,15 +204,32 @@ namespace Microsoft.AspNetCore.SignalR.Protocol hasItem = true; - if (string.IsNullOrEmpty(invocationId)) + + string id = null; + if (!string.IsNullOrEmpty(invocationId)) { - // If we don't have an invocation id then we need to store it as a JToken so we can parse it later - itemToken = JToken.Load(reader); + id = invocationId; + } + else if (!string.IsNullOrEmpty(streamId)) + { + id = streamId; } else { - var returnType = binder.GetReturnType(invocationId); - item = PayloadSerializer.Deserialize(reader, returnType); + // If we don't have an id yetmthen we need to store it as a JToken to parse later + itemToken = JToken.Load(reader); + break; + } + + Type itemType = binder.GetStreamItemType(id); + + try + { + item = PayloadSerializer.Deserialize(reader, itemType); + } + catch (JsonSerializationException ex) + { + return new StreamBindingFailureMessage(id, ExceptionDispatchInfo.Capture(ex)); } break; case ArgumentsPropertyName: @@ -313,11 +335,33 @@ namespace Microsoft.AspNetCore.SignalR.Protocol : BindStreamInvocationMessage(invocationId, target, arguments, hasArguments, binder); } break; + case HubProtocolConstants.StreamDataMessageType: + if (itemToken != null) + { + var itemType = binder.GetStreamItemType(streamId); + try + { + item = itemToken.ToObject(itemType, PayloadSerializer); + } + catch (JsonSerializationException ex) + { + return new StreamBindingFailureMessage(streamId, ExceptionDispatchInfo.Capture(ex)); + } + } + message = BindParamStreamMessage(streamId, item, hasItem, binder); + break; case HubProtocolConstants.StreamItemMessageType: if (itemToken != null) { - var returnType = binder.GetReturnType(invocationId); - item = itemToken.ToObject(returnType, PayloadSerializer); + var returnType = binder.GetStreamItemType(invocationId); + try + { + item = itemToken.ToObject(returnType, PayloadSerializer); + } + catch (JsonSerializationException ex) + { + return new StreamBindingFailureMessage(invocationId, ExceptionDispatchInfo.Capture(ex)); + }; } message = BindStreamItemMessage(invocationId, item, hasItem, binder); @@ -338,6 +382,9 @@ namespace Microsoft.AspNetCore.SignalR.Protocol return PingMessage.Instance; case HubProtocolConstants.CloseMessageType: return BindCloseMessage(error); + case HubProtocolConstants.StreamCompleteMessageType: + message = BindStreamCompleteMessage(streamId, error); + break; case null: throw new InvalidDataException($"Missing required property '{TypePropertyName}'."); default: @@ -408,6 +455,10 @@ namespace Microsoft.AspNetCore.SignalR.Protocol WriteHeaders(writer, m); WriteStreamInvocationMessage(m, writer); break; + case StreamDataMessage m: + WriteMessageType(writer, HubProtocolConstants.StreamDataMessageType); + WriteStreamDataMessage(m, writer); + break; case StreamItemMessage m: WriteMessageType(writer, HubProtocolConstants.StreamItemMessageType); WriteHeaders(writer, m); @@ -430,6 +481,10 @@ namespace Microsoft.AspNetCore.SignalR.Protocol WriteMessageType(writer, HubProtocolConstants.CloseMessageType); WriteCloseMessage(m, writer); break; + case StreamCompleteMessage m: + WriteMessageType(writer, HubProtocolConstants.StreamCompleteMessageType); + WriteStreamCompleteMessage(m, writer); + break; default: throw new InvalidOperationException($"Unsupported message type: {message.GetType().FullName}"); } @@ -478,6 +533,18 @@ namespace Microsoft.AspNetCore.SignalR.Protocol WriteInvocationId(message, writer); } + private void WriteStreamCompleteMessage(StreamCompleteMessage message, JsonTextWriter writer) + { + writer.WritePropertyName(StreamIdPropertyName); + writer.WriteValue(message.StreamId); + + if (message.Error != null) + { + writer.WritePropertyName(ErrorPropertyName); + writer.WriteValue(message.Error); + } + } + private void WriteStreamItemMessage(StreamItemMessage message, JsonTextWriter writer) { WriteInvocationId(message, writer); @@ -485,6 +552,14 @@ namespace Microsoft.AspNetCore.SignalR.Protocol PayloadSerializer.Serialize(writer, message.Item); } + private void WriteStreamDataMessage(StreamDataMessage message, JsonTextWriter writer) + { + writer.WritePropertyName(StreamIdPropertyName); + writer.WriteValue(message.StreamId); + writer.WritePropertyName(ItemPropertyName); + PayloadSerializer.Serialize(writer, message.Item); + } + private void WriteInvocationMessage(InvocationMessage message, JsonTextWriter writer) { WriteInvocationId(message, writer); @@ -548,6 +623,17 @@ namespace Microsoft.AspNetCore.SignalR.Protocol return new CancelInvocationMessage(invocationId); } + private HubMessage BindStreamCompleteMessage(string streamId, string error) + { + if (string.IsNullOrEmpty(streamId)) + { + throw new InvalidDataException($"Missing required property '{StreamIdPropertyName}'."); + } + + // note : if the stream completes normally, the error should be `null` + return new StreamCompleteMessage(streamId, error); + } + private HubMessage BindCompletionMessage(string invocationId, string error, object result, bool hasResult, IInvocationBinder binder) { if (string.IsNullOrEmpty(invocationId)) @@ -568,6 +654,20 @@ namespace Microsoft.AspNetCore.SignalR.Protocol return new CompletionMessage(invocationId, error, result: null, hasResult: false); } + private HubMessage BindParamStreamMessage(string streamId, object item, bool hasItem, IInvocationBinder binder) + { + if (string.IsNullOrEmpty(streamId)) + { + throw new InvalidDataException($"Missing required property '{StreamIdPropertyName}"); + } + if (!hasItem) + { + throw new InvalidDataException($"Missing required property '{ItemPropertyName}"); + } + + return new StreamDataMessage(streamId, item); + } + private HubMessage BindStreamItemMessage(string invocationId, object item, bool hasItem, IInvocationBinder binder) { if (string.IsNullOrEmpty(invocationId)) @@ -658,7 +758,6 @@ namespace Microsoft.AspNetCore.SignalR.Protocol { if (paramIndex < paramCount) { - // Set all known arguments arguments[paramIndex] = PayloadSerializer.Deserialize(reader, paramTypes[paramIndex]); } else diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Protocol/MessagePackHubProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Protocol/MessagePackHubProtocol.cs index 6f6a76252e..ffeb7bfe75 100644 --- a/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Protocol/MessagePackHubProtocol.cs +++ b/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Protocol/MessagePackHubProtocol.cs @@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol private static HubMessage ParseMessage(byte[] input, int startOffset, IInvocationBinder binder, IFormatterResolver resolver) { - _ = MessagePackBinary.ReadArrayHeader(input, startOffset, out var readSize); + MessagePackBinary.ReadArrayHeader(input, startOffset, out var readSize); startOffset += readSize; var messageType = ReadInt32(input, ref startOffset, "messageType"); @@ -142,6 +142,8 @@ namespace Microsoft.AspNetCore.SignalR.Protocol return PingMessage.Instance; case HubProtocolConstants.CloseMessageType: return CreateCloseMessage(input, ref startOffset); + case HubProtocolConstants.StreamCompleteMessageType: + return CreateStreamCompleteMessage(input, ref startOffset); default: // Future protocol changes can add message types, old clients can ignore them return null; @@ -179,6 +181,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol var headers = ReadHeaders(input, ref offset); var invocationId = ReadInvocationId(input, ref offset); var target = ReadString(input, ref offset, "target"); + var parameterTypes = binder.GetParameterTypes(target); try @@ -196,7 +199,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol { var headers = ReadHeaders(input, ref offset); var invocationId = ReadInvocationId(input, ref offset); - var itemType = binder.GetReturnType(invocationId); + var itemType = binder.GetStreamItemType(invocationId); var value = DeserializeObject(input, ref offset, itemType, "item", resolver); return ApplyHeaders(headers, new StreamItemMessage(invocationId, value)); } @@ -244,6 +247,17 @@ namespace Microsoft.AspNetCore.SignalR.Protocol return new CloseMessage(error); } + private static StreamCompleteMessage CreateStreamCompleteMessage(byte[] input, ref int offset) + { + var streamId = ReadString(input, ref offset, "streamId"); + var error = ReadString(input, ref offset, "error"); + if (string.IsNullOrEmpty(error)) + { + error = null; + } + return new StreamCompleteMessage(streamId, error); + } + private static Dictionary ReadHeaders(byte[] input, ref int offset) { var headerCount = ReadMapLength(input, ref offset, "headers"); @@ -376,6 +390,9 @@ namespace Microsoft.AspNetCore.SignalR.Protocol case CloseMessage closeMessage: WriteCloseMessage(closeMessage, packer); break; + case StreamCompleteMessage m: + WriteStreamCompleteMessage(m, packer); + break; default: throw new InvalidDataException($"Unexpected message type: {message.GetType().Name}"); } @@ -469,6 +486,21 @@ namespace Microsoft.AspNetCore.SignalR.Protocol MessagePackBinary.WriteString(packer, message.InvocationId); } + private void WriteStreamCompleteMessage(StreamCompleteMessage message, Stream packer) + { + MessagePackBinary.WriteArrayHeader(packer, 3); + MessagePackBinary.WriteInt16(packer, HubProtocolConstants.StreamCompleteMessageType); + MessagePackBinary.WriteString(packer, message.StreamId); + if (message.HasError) + { + MessagePackBinary.WriteString(packer, message.Error); + } + else + { + MessagePackBinary.WriteNil(packer); + } + } + private void WriteCloseMessage(CloseMessage message, Stream packer) { MessagePackBinary.WriteArrayHeader(packer, 2); diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs index c95fd91df8..55bb728e3c 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs @@ -3,6 +3,9 @@ using System; using System.Buffers; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Channels; using System.Threading.Tasks; using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.SignalR.Protocol; @@ -145,6 +148,227 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests } } + [Fact] + public async Task StreamIntsToServer() + { + using (StartVerifiableLog(out var loggerFactory, LogLevel.Trace)) + { + var connection = new TestConnection(); + var hubConnection = CreateHubConnection(connection, loggerFactory: loggerFactory); + await hubConnection.StartAsync().OrTimeout(); + + var channel = Channel.CreateUnbounded(); + var invokeTask = hubConnection.InvokeAsync("SomeMethod", channel.Reader); + + var invocation = await connection.ReadSentJsonAsync().OrTimeout(); + Assert.Equal(HubProtocolConstants.InvocationMessageType, invocation["type"]); + Assert.Equal("SomeMethod", invocation["target"]); + var streamId = invocation["arguments"][0]["streamId"]; + + foreach (var number in new[] { 42, 43, 322, 3145, -1234 }) + { + await channel.Writer.WriteAsync(number).AsTask().OrTimeout(); + + var item = await connection.ReadSentJsonAsync().OrTimeout(); + Assert.Equal(HubProtocolConstants.StreamDataMessageType, item["type"]); + Assert.Equal(number, item["item"]); + Assert.Equal(streamId, item["streamId"]); + } + + channel.Writer.TryComplete(); + var completion = await connection.ReadSentJsonAsync().OrTimeout(); + Assert.Equal(HubProtocolConstants.StreamCompleteMessageType, completion["type"]); + + await connection.ReceiveJsonMessage( + new { type = HubProtocolConstants.CompletionMessageType, invocationId = invocation["invocationId"], result = 42 } + ).OrTimeout(); + var result = await invokeTask.OrTimeout(); + Assert.Equal(42, result); + } + } + + [Fact] + public async Task StreamIntsToServerViaSend() + { + using (StartVerifiableLog(out var loggerFactory, LogLevel.Trace)) + { + var connection = new TestConnection(); + var hubConnection = CreateHubConnection(connection, loggerFactory: loggerFactory); + await hubConnection.StartAsync().OrTimeout(); + + var channel = Channel.CreateUnbounded(); + var sendTask = hubConnection.SendAsync("SomeMethod", channel.Reader); + + var invocation = await connection.ReadSentJsonAsync().OrTimeout(); + Assert.Equal(HubProtocolConstants.InvocationMessageType, invocation["type"]); + Assert.Equal("SomeMethod", invocation["target"]); + Assert.Null(invocation["invocationId"]); + var streamId = invocation["arguments"][0]["streamId"]; + + foreach (var item in new[] { 2, 3, 10, 5 }) + { + await channel.Writer.WriteAsync(item); + + var received = await connection.ReadSentJsonAsync().OrTimeout(); + Assert.Equal(HubProtocolConstants.StreamDataMessageType, received["type"]); + Assert.Equal(item, received["item"]); + Assert.Equal(streamId, received["streamId"]); + } + } + } + + [Fact] + public async Task StreamsObjectsToServer() + { + using (StartVerifiableLog(out var loggerFactory, LogLevel.Trace)) + { + var connection = new TestConnection(); + var hubConnection = CreateHubConnection(connection, loggerFactory: loggerFactory); + await hubConnection.StartAsync().OrTimeout(); + + var channel = Channel.CreateUnbounded(); + var invokeTask = hubConnection.InvokeAsync("UploadMethod", channel.Reader); + + var invocation = await connection.ReadSentJsonAsync().OrTimeout(); + Assert.Equal(HubProtocolConstants.InvocationMessageType, invocation["type"]); + Assert.Equal("UploadMethod", invocation["target"]); + var id = invocation["invocationId"]; + + var items = new[] { new SampleObject("ab", 12), new SampleObject("ef", 23) }; + foreach (var item in items) + { + await channel.Writer.WriteAsync(item); + + var received = await connection.ReadSentJsonAsync().OrTimeout(); + Assert.Equal(HubProtocolConstants.StreamDataMessageType, received["type"]); + Assert.Equal(item.Foo, received["item"]["foo"]); + Assert.Equal(item.Bar, received["item"]["bar"]); + } + + channel.Writer.TryComplete(); + var completion = await connection.ReadSentJsonAsync().OrTimeout(); + Assert.Equal(HubProtocolConstants.StreamCompleteMessageType, completion["type"]); + + var expected = new SampleObject("oof", 14); + await connection.ReceiveJsonMessage( + new { type = HubProtocolConstants.CompletionMessageType, invocationId = id, result = expected } + ).OrTimeout(); + var result = await invokeTask.OrTimeout(); + + Assert.Equal(expected.Foo, result.Foo); + Assert.Equal(expected.Bar, result.Bar); + } + } + + [Fact] + public async Task UploadStreamCancelationSendsStreamComplete() + { + using (StartVerifiableLog(out var loggerFactory, LogLevel.Trace)) + { + var connection = new TestConnection(); + var hubConnection = CreateHubConnection(connection, loggerFactory: loggerFactory); + await hubConnection.StartAsync().OrTimeout(); + + var cts = new CancellationTokenSource(); + var channel = Channel.CreateUnbounded(); + var invokeTask = hubConnection.InvokeAsync("UploadMethod", channel.Reader, cts.Token); + + var invokeMessage = await connection.ReadSentJsonAsync().OrTimeout(); + Assert.Equal(HubProtocolConstants.InvocationMessageType, invokeMessage["type"]); + + cts.Cancel(); + + // after cancellation, don't send from the pipe + foreach (var number in new[] { 42, 43, 322, 3145, -1234 }) + { + + await channel.Writer.WriteAsync(number); + } + + // the next sent message should be a completion message + var complete = await connection.ReadSentJsonAsync().OrTimeout(); + Assert.Equal(HubProtocolConstants.StreamCompleteMessageType, complete["type"]); + Assert.EndsWith("canceled by client.", ((string)complete["error"])); + } + } + + [Fact] + public async Task InvocationCanCompleteBeforeStreamCompletes() + { + using (StartVerifiableLog(out var loggerFactory, LogLevel.Trace)) + { + var connection = new TestConnection(); + var hubConnection = CreateHubConnection(connection, loggerFactory: loggerFactory); + await hubConnection.StartAsync().OrTimeout(); + + var channel = Channel.CreateUnbounded(); + var invokeTask = hubConnection.InvokeAsync("UploadMethod", channel.Reader); + var invocation = await connection.ReadSentJsonAsync().OrTimeout(); + Assert.Equal(HubProtocolConstants.InvocationMessageType, invocation["type"]); + var id = invocation["invocationId"]; + + await connection.ReceiveJsonMessage(new { type = HubProtocolConstants.CompletionMessageType, invocationId = id, result = 10 }); + + var result = await invokeTask.OrTimeout(); + Assert.Equal(10L, result); + + // after the server returns, with whatever response + // the client's behavior is undefined, and the server is responsible for ignoring stray messages + } + } + + [Fact] + public async Task WrongTypeOnServerResponse() + { + bool ExpectedErrors(WriteContext writeContext) + { + return writeContext.LoggerName == typeof(HubConnection).FullName && + (writeContext.EventId.Name == "ServerDisconnectedWithError" + || writeContext.EventId.Name == "ShutdownWithError"); + } + using (StartVerifiableLog(out var loggerFactory, LogLevel.Trace, expectedErrorsFilter: ExpectedErrors)) + { + var connection = new TestConnection(); + var hubConnection = CreateHubConnection(connection, loggerFactory: loggerFactory); + await hubConnection.StartAsync().OrTimeout(); + + // we expect to get sent ints, and receive an int back + var channel = Channel.CreateUnbounded(); + var invokeTask = hubConnection.InvokeAsync("SumInts", channel.Reader); + + var invocation = await connection.ReadSentJsonAsync(); + Assert.Equal(HubProtocolConstants.InvocationMessageType, invocation["type"]); + var id = invocation["invocationId"]; + + await channel.Writer.WriteAsync(5); + await channel.Writer.WriteAsync(10); + + await connection.ReceiveJsonMessage(new { type = HubProtocolConstants.CompletionMessageType, invocationId = id, result = "humbug" }); + + try + { + await invokeTask; + } + catch (Exception ex) + { + Assert.Equal(typeof(Newtonsoft.Json.JsonSerializationException), ex.GetType()); + } + } + } + + private class SampleObject + { + public SampleObject(string foo, int bar) + { + Foo = foo; + Bar = bar; + } + + public string Foo { get; private set; } + public int Bar { get; private set; } + } + + // Moq really doesn't handle out parameters well, so to make these tests work I added a manual mock -anurse private class MockHubProtocol : IHubProtocol { diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestConnection.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestConnection.cs index 7309fdee70..432d4595a8 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestConnection.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestConnection.cs @@ -163,6 +163,11 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests } } + public async Task ReadSentJsonAsync() + { + return JObject.Parse(await ReadSentTextMessageAsync()); + } + public async Task> ReadAllSentMessagesAsync(bool ignorePings = true) { if (!Disposed.IsCompleted) diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CompositeTestBinder.cs b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CompositeTestBinder.cs index b1957dc5fa..06354680a4 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CompositeTestBinder.cs +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CompositeTestBinder.cs @@ -37,5 +37,10 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol arg is StreamItemMessage || arg is StreamInvocationMessage; } + + public Type GetStreamItemType(string streamId) + { + throw new NotImplementedException(); + } } } diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs index 8229dac321..7bd1946100 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs @@ -40,6 +40,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNullValueIgnore", new InvocationMessage(null, "Target", new object[] { new CustomObject() }), true, NullValueHandling.Ignore, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"byteArrProp\":\"AQID\"}]}"), new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNullValueIgnoreAndNoCamelCase", new InvocationMessage(null, "Target", new object[] { new CustomObject() }), false, NullValueHandling.Include, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"StringProp\":\"SignalR!\",\"DoubleProp\":6.2831853071,\"IntProp\":42,\"DateTimeProp\":\"2017-04-11T00:00:00Z\",\"NullProp\":null,\"ByteArrProp\":\"AQID\"}]}"), new JsonProtocolTestData("InvocationMessage_HasCustomArgumentWithNullValueInclude", new InvocationMessage(null, "Target", new object[] { new CustomObject() }), true, NullValueHandling.Include, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}]}"), + new JsonProtocolTestData("InvocationMessage_HasStreamPlaceholder", new InvocationMessage(null, "Target", new object[] { new StreamPlaceholder("__test_id__")}), true, NullValueHandling.Ignore, "{\"type\":1,\"target\":\"Target\",\"arguments\":[{\"streamId\":\"__test_id__\"}]}"), new JsonProtocolTestData("InvocationMessage_HasHeaders", AddHeaders(TestHeaders, new InvocationMessage("123", "Target", new object[] { 1, "Foo", 2.0f })), true, NullValueHandling.Ignore, "{\"type\":1," + SerializedHeaders + ",\"invocationId\":\"123\",\"target\":\"Target\",\"arguments\":[1,\"Foo\",2.0]}"), new JsonProtocolTestData("InvocationMessage_StringIsoDateArgument", new InvocationMessage("Method", new object[] { "2016-05-10T13:51:20+12:34" }), true, NullValueHandling.Ignore, "{\"type\":1,\"target\":\"Method\",\"arguments\":[\"2016-05-10T13:51:20+12:34\"]}"), new JsonProtocolTestData("InvocationMessage_DateTimeOffsetArgument", new InvocationMessage("Method", new object[] { DateTimeOffset.Parse("2016-05-10T13:51:20+12:34") }), true, NullValueHandling.Ignore, "{\"type\":1,\"target\":\"Method\",\"arguments\":[\"2016-05-10T13:51:20+12:34\"]}"), @@ -55,7 +56,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol new JsonProtocolTestData("StreamItemMessage_HasCustomItemWithNullValueInclude", new StreamItemMessage("123", new CustomObject()), true, NullValueHandling.Include, "{\"type\":2,\"invocationId\":\"123\",\"item\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}}"), new JsonProtocolTestData("StreamItemMessage_HasHeaders", AddHeaders(TestHeaders, new StreamItemMessage("123", new CustomObject())), true, NullValueHandling.Include, "{\"type\":2," + SerializedHeaders + ",\"invocationId\":\"123\",\"item\":{\"stringProp\":\"SignalR!\",\"doubleProp\":6.2831853071,\"intProp\":42,\"dateTimeProp\":\"2017-04-11T00:00:00Z\",\"nullProp\":null,\"byteArrProp\":\"AQID\"}}"), - new JsonProtocolTestData("CompletionMessage_HasIntergerResult", CompletionMessage.WithResult("123", 1), true, NullValueHandling.Ignore, "{\"type\":3,\"invocationId\":\"123\",\"result\":1}"), + new JsonProtocolTestData("CompletionMessage_HasIntegerResult", CompletionMessage.WithResult("123", 1), true, NullValueHandling.Ignore, "{\"type\":3,\"invocationId\":\"123\",\"result\":1}"), new JsonProtocolTestData("CompletionMessage_HasStringResult", CompletionMessage.WithResult("123", "Foo"), true, NullValueHandling.Ignore, "{\"type\":3,\"invocationId\":\"123\",\"result\":\"Foo\"}"), new JsonProtocolTestData("CompletionMessage_HasFloatResult", CompletionMessage.WithResult("123", 2.0f), true, NullValueHandling.Ignore, "{\"type\":3,\"invocationId\":\"123\",\"result\":2.0}"), new JsonProtocolTestData("CompletionMessage_HasBoolResult", CompletionMessage.WithResult("123", true), true, NullValueHandling.Ignore, "{\"type\":3,\"invocationId\":\"123\",\"result\":true}"), @@ -88,7 +89,11 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol new JsonProtocolTestData("CloseMessage", CloseMessage.Empty, false, NullValueHandling.Ignore, "{\"type\":7}"), new JsonProtocolTestData("CloseMessage_HasError", new CloseMessage("Error!"), false, NullValueHandling.Ignore, "{\"type\":7,\"error\":\"Error!\"}"), new JsonProtocolTestData("CloseMessage_HasErrorWithCamelCase", new CloseMessage("Error!"), true, NullValueHandling.Ignore, "{\"type\":7,\"error\":\"Error!\"}"), - new JsonProtocolTestData("CloseMessage_HasErrorEmptyString", new CloseMessage(""), false, NullValueHandling.Ignore, "{\"type\":7,\"error\":\"\"}") + new JsonProtocolTestData("CloseMessage_HasErrorEmptyString", new CloseMessage(""), false, NullValueHandling.Ignore, "{\"type\":7,\"error\":\"\"}"), + + new JsonProtocolTestData("StreamCompleteMessage", new StreamCompleteMessage("123"), true, NullValueHandling.Ignore, "{\"type\":8,\"streamId\":\"123\"}"), + new JsonProtocolTestData("StreamCompleteMessageWithError", new StreamCompleteMessage("123", "zoinks"), true, NullValueHandling.Ignore, "{\"type\":8,\"streamId\":\"123\",\"error\":\"zoinks\"}"), + }.ToDictionary(t => t.Name); public static IEnumerable ProtocolTestDataNames => ProtocolTestData.Keys.Select(name => new object[] { name }); @@ -101,6 +106,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol new JsonProtocolTestData("StreamInvocationMessage_IntegerArrayArgumentFirst", new StreamInvocationMessage("3", "Method", new object[] { 1, 2 }), false, NullValueHandling.Ignore, "{ \"type\":4, \"arguments\": [1,2], \"target\": \"Method\", \"invocationId\": \"3\" }"), new JsonProtocolTestData("CompletionMessage_ResultFirst", new CompletionMessage("15", null, 10, hasResult: true), false, NullValueHandling.Ignore, "{ \"type\":3, \"result\": 10, \"invocationId\": \"15\" }"), new JsonProtocolTestData("StreamItemMessage_ItemFirst", new StreamItemMessage("1a", "foo"), false, NullValueHandling.Ignore, "{ \"item\": \"foo\", \"invocationId\": \"1a\", \"type\":2 }") + }.ToDictionary(t => t.Name); public static IEnumerable OutOfOrderJsonTestDataNames => OutOfOrderJsonTestData.Keys.Select(name => new object[] { name }); diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MessagePackHubProtocolTests.cs b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MessagePackHubProtocolTests.cs index c0fbec1baf..1f8bf8c009 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MessagePackHubProtocolTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MessagePackHubProtocolTests.cs @@ -91,6 +91,11 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol name: "InvocationWithHeadersNoIdAndArrayOfCustomObjectArgs", message: AddHeaders(TestHeaders, new InvocationMessage("method", new object[] { new CustomObject(), new CustomObject() })), binary: "lQGDo0Zvb6NCYXKyS2V5V2l0aApOZXcNCkxpbmVzq1N0aWxsIFdvcmtzsVZhbHVlV2l0aE5ld0xpbmVzsEFsc28KV29ya3MNCkZpbmXApm1ldGhvZJKGqlN0cmluZ1Byb3CoU2lnbmFsUiGqRG91YmxlUHJvcMtAGSH7VELPEqdJbnRQcm9wKqxEYXRlVGltZVByb3DW/1jsHICoTnVsbFByb3DAq0J5dGVBcnJQcm9wxAMBAgOGqlN0cmluZ1Byb3CoU2lnbmFsUiGqRG91YmxlUHJvcMtAGSH7VELPEqdJbnRQcm9wKqxEYXRlVGltZVByb3DW/1jsHICoTnVsbFByb3DAq0J5dGVBcnJQcm9wxAMBAgM="), + new ProtocolTestData( + name: "InvocationWithStreamPlaceholderObject", + message: new InvocationMessage(null, "Target", new object[] { new StreamPlaceholder("__test_id__")}), + binary: "lQGAwKZUYXJnZXSRgahTdHJlYW1JZKtfX3Rlc3RfaWRfXw==" + ), // StreamItem Messages new ProtocolTestData( @@ -228,6 +233,16 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol message: AddHeaders(TestHeaders, new CancelInvocationMessage("xyz")), binary: "kwWDo0Zvb6NCYXKyS2V5V2l0aApOZXcNCkxpbmVzq1N0aWxsIFdvcmtzsVZhbHVlV2l0aE5ld0xpbmVzsEFsc28KV29ya3MNCkZpbmWjeHl6"), + // StreamComplete Messages + new ProtocolTestData( + name: "StreamComplete", + message: new StreamCompleteMessage("xyz"), + binary: "kwijeHl6wA=="), + new ProtocolTestData( + name: "StreamCompleteWithError", + message: new StreamCompleteMessage("xyz", "zoinks"), + binary: "kwijeHl6pnpvaW5rcw=="), + // Ping Messages new ProtocolTestData( name: "Ping", @@ -259,7 +274,14 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol var expectedMessage = new InvocationMessage("xyz", "method", Array.Empty()); // Verify that the input binary string decodes to the expected MsgPack primitives - var bytes = new byte[] { ArrayBytes(6), 1, 0x80, StringBytes(3), (byte)'x', (byte)'y', (byte)'z', StringBytes(6), (byte)'m', (byte)'e', (byte)'t', (byte)'h', (byte)'o', (byte)'d', ArrayBytes(0), StringBytes(2), (byte)'e', (byte)'x' }; + var bytes = new byte[] { ArrayBytes(8), + 1, + 0x80, + StringBytes(3), (byte)'x', (byte)'y', (byte)'z', + StringBytes(6), (byte)'m', (byte)'e', (byte)'t', (byte)'h', (byte)'o', (byte)'d', + ArrayBytes(0), + 0xc3, + StringBytes(2), (byte)'e', (byte)'x' }; // Parse the input fully now. bytes = Frame(bytes); diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestBinder.cs b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestBinder.cs index 1855b19f81..d7282c42a1 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestBinder.cs +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestBinder.cs @@ -58,5 +58,13 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol } throw new InvalidOperationException("Unexpected binder call"); } + + public Type GetStreamItemType(string streamId) + { + // In v1, stream items were only sent from server -> client + // and so they had items typed based on what the hub method returned. + // We just forward here for backwards compatibility. + return GetReturnType(streamId); + } } } diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestHubMessageEqualityComparer.cs b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestHubMessageEqualityComparer.cs index a7c425be0a..0682c75640 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestHubMessageEqualityComparer.cs +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestHubMessageEqualityComparer.cs @@ -34,11 +34,13 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol return StreamInvocationMessagesEqual(streamInvocationMessage, (StreamInvocationMessage)y); case CancelInvocationMessage cancelItemMessage: return string.Equals(cancelItemMessage.InvocationId, ((CancelInvocationMessage)y).InvocationId, StringComparison.Ordinal); - case PingMessage pingMessage: + case PingMessage _: // If the types are equal (above), then we're done. return true; case CloseMessage closeMessage: return string.Equals(closeMessage.Error, ((CloseMessage) y).Error); + case StreamCompleteMessage streamCompleteMessage: + return StreamCompleteMessagesEqual(streamCompleteMessage, (StreamCompleteMessage)y); default: throw new InvalidOperationException($"Unknown message type: {x.GetType().FullName}"); } @@ -46,34 +48,40 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol private bool CompletionMessagesEqual(CompletionMessage x, CompletionMessage y) { - return SequenceEqual(x.Headers, y.Headers) && - string.Equals(x.InvocationId, y.InvocationId, StringComparison.Ordinal) && - string.Equals(x.Error, y.Error, StringComparison.Ordinal) && - x.HasResult == y.HasResult && - (Equals(x.Result, y.Result) || SequenceEqual(x.Result, y.Result)); + return SequenceEqual(x.Headers, y.Headers) + && string.Equals(x.InvocationId, y.InvocationId, StringComparison.Ordinal) + && string.Equals(x.Error, y.Error, StringComparison.Ordinal) + && x.HasResult == y.HasResult + && (Equals(x.Result, y.Result) || SequenceEqual(x.Result, y.Result)); } private bool StreamItemMessagesEqual(StreamItemMessage x, StreamItemMessage y) { - return SequenceEqual(x.Headers, y.Headers) && - string.Equals(x.InvocationId, y.InvocationId, StringComparison.Ordinal) && - (Equals(x.Item, y.Item) || SequenceEqual(x.Item, y.Item)); + return SequenceEqual(x.Headers, y.Headers) + && string.Equals(x.InvocationId, y.InvocationId, StringComparison.Ordinal) + && (Equals(x.Item, y.Item) || SequenceEqual(x.Item, y.Item)); } private bool InvocationMessagesEqual(InvocationMessage x, InvocationMessage y) { - return SequenceEqual(x.Headers, y.Headers) && - string.Equals(x.InvocationId, y.InvocationId, StringComparison.Ordinal) && - string.Equals(x.Target, y.Target, StringComparison.Ordinal) && - ArgumentListsEqual(x.Arguments, y.Arguments); + return SequenceEqual(x.Headers, y.Headers) + && string.Equals(x.InvocationId, y.InvocationId, StringComparison.Ordinal) + && string.Equals(x.Target, y.Target, StringComparison.Ordinal) + && ArgumentListsEqual(x.Arguments, y.Arguments); } private bool StreamInvocationMessagesEqual(StreamInvocationMessage x, StreamInvocationMessage y) { - return SequenceEqual(x.Headers, y.Headers) && - string.Equals(x.InvocationId, y.InvocationId, StringComparison.Ordinal) && - string.Equals(x.Target, y.Target, StringComparison.Ordinal) && - ArgumentListsEqual(x.Arguments, y.Arguments); + return SequenceEqual(x.Headers, y.Headers) + && string.Equals(x.InvocationId, y.InvocationId, StringComparison.Ordinal) + && string.Equals(x.Target, y.Target, StringComparison.Ordinal) + && ArgumentListsEqual(x.Arguments, y.Arguments); + } + + private bool StreamCompleteMessagesEqual(StreamCompleteMessage x, StreamCompleteMessage y) + { + return x.StreamId == y.StreamId + && y.Error == y.Error; } private bool ArgumentListsEqual(object[] left, object[] right) @@ -90,7 +98,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol for (var i = 0; i < left.Length; i++) { - if (!(Equals(left[i], right[i]) || SequenceEqual(left[i], right[i]))) + if (!(Equals(left[i], right[i]) || SequenceEqual(left[i], right[i]) || PlaceholdersEqual(left[i], right[i]))) { return false; } @@ -98,6 +106,21 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol return true; } + private bool PlaceholdersEqual(object left, object right) + { + if (left.GetType() != right.GetType()) + { + return false; + } + switch(left) + { + case StreamPlaceholder leftPlaceholder: + return leftPlaceholder.StreamId == (right as StreamPlaceholder).StreamId; + default: + return false; + } + } + private bool SequenceEqual(object left, object right) { if (left == null && right == null) diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestClient.cs b/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestClient.cs index c76ef5e892..947a323b55 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestClient.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestClient.cs @@ -178,6 +178,12 @@ namespace Microsoft.AspNetCore.SignalR.Tests return SendHubMessageAsync(new StreamInvocationMessage(invocationId, methodName, args)); } + public Task BeginUploadStreamAsync(string invocationId, string methodName, params object[] args) + { + var message = new InvocationMessage(invocationId, methodName, args); + return SendHubMessageAsync(message); + } + public async Task SendHubMessageAsync(HubMessage message) { var payload = _protocol.GetMessageBytes(message); @@ -295,6 +301,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests } } } + private class DefaultInvocationBinder : IInvocationBinder { public IReadOnlyList GetParameterTypes(string methodName) @@ -307,6 +314,11 @@ namespace Microsoft.AspNetCore.SignalR.Tests { return typeof(object); } + + public Type GetStreamItemType(string streamId) + { + throw new NotImplementedException(); + } } } } diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Hubs.cs b/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Hubs.cs index 7eb0aec498..c1d30c5cbc 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Hubs.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Hubs.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Text; using System.Threading.Channels; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; @@ -174,6 +175,78 @@ namespace Microsoft.AspNetCore.SignalR.Tests public SelfRef Self; } + + public async Task StreamingConcat(ChannelReader source) + { + var sb = new StringBuilder(); + + while (await source.WaitToReadAsync()) + { + while (source.TryRead(out var item)) + { + sb.Append(item); + } + } + + return sb.ToString(); + } + + public async Task StreamingSum(ChannelReader source) + { + var total = 0; + while (await source.WaitToReadAsync()) + { + while (source.TryRead(out var item)) + { + total += item; + } + } + return total; + } + + public async Task> UploadArray(ChannelReader source) + { + var results = new List(); + + while (await source.WaitToReadAsync()) + { + while (source.TryRead(out var item)) + { + results.Add(item); + } + } + + return results; + } + + public async Task TestTypeCastingErrors(ChannelReader source) + { + try + { + await source.WaitToReadAsync(); + } + catch (Exception ex) + { + Console.WriteLine(ex.ToString()); + return "error identified and caught"; + } + + return "wrong type accepted, this is bad"; + } + + public async Task TestCustomErrorPassing(ChannelReader source) + { + try + { + await source.WaitToReadAsync(); + } + catch (Exception ex) + { + return ex.Message == HubConnectionHandlerTests.CustomErrorMessage; + } + + return false; + } } public abstract class TestHub : Hub diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTests.cs b/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTests.cs index 04156ad03b..5f01aad337 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTests.cs @@ -4,6 +4,7 @@ using System; using System.Buffers; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Security.Claims; using System.Text; @@ -1489,7 +1490,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(); var connectionHandler = serviceProvider.GetService>(); var invocationBinder = new Mock(); - invocationBinder.Setup(b => b.GetReturnType(It.IsAny())).Returns(typeof(string)); + invocationBinder.Setup(b => b.GetStreamItemType(It.IsAny())).Returns(typeof(string)); using (var client = new TestClient(protocol: protocol, invocationBinder: invocationBinder.Object)) { @@ -2361,6 +2362,93 @@ namespace Microsoft.AspNetCore.SignalR.Tests } } + [Fact] + public async Task UploadStringsToConcat() + { + var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(); + var connectionHandler = serviceProvider.GetService>(); + + using (var client = new TestClient()) + { + var connectionHandlerTask = await client.ConnectAsync(connectionHandler).OrTimeout(); + await client.BeginUploadStreamAsync("invocation", nameof(MethodHub.StreamingConcat), new StreamPlaceholder("id")); + + foreach (var letter in new[] { "B", "E", "A", "N", "E", "D" }) + { + await client.SendHubMessageAsync(new StreamDataMessage("id", letter)).OrTimeout(); + } + + await client.SendHubMessageAsync(new StreamCompleteMessage("id")).OrTimeout(); + var result = (CompletionMessage)await client.ReadAsync().OrTimeout(); + + Assert.Equal("BEANED", result.Result); + } + } + + [Fact] + public async Task UploadStreamedObjects() + { + var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(); + var connectionHandler = serviceProvider.GetService>(); + + using (var client = new TestClient()) + { + var connectionHandlerTask = await client.ConnectAsync(connectionHandler).OrTimeout(); + await client.BeginUploadStreamAsync("invocation", nameof(MethodHub.UploadArray), new StreamPlaceholder("id")); + + var objects = new[] { new SampleObject("solo", 322), new SampleObject("ggez", 3145) }; + foreach (var thing in objects) + { + await client.SendHubMessageAsync(new StreamDataMessage("id", thing)).OrTimeout(); + } + + await client.SendHubMessageAsync(new StreamCompleteMessage("id")).OrTimeout(); + var response = (CompletionMessage)await client.ReadAsync().OrTimeout(); + var result = ((JArray)response.Result).ToArray(); + + Assert.Equal(objects[0].Foo, ((JContainer)result[0])["foo"]); + Assert.Equal(objects[0].Bar, ((JContainer)result[0])["bar"]); + Assert.Equal(objects[1].Foo, ((JContainer)result[1])["foo"]); + Assert.Equal(objects[1].Bar, ((JContainer)result[1])["bar"]); + } + } + + [Fact] + public async Task UploadManyStreams() + { + var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(); + var connectionHandler = serviceProvider.GetService>(); + + using (var client = new TestClient()) + { + var connectionHandlerTask = await client.ConnectAsync(connectionHandler).OrTimeout(); + var ids = new[] { "0", "1", "2" }; + + foreach (string id in ids) + { + await client.BeginUploadStreamAsync("invocation_"+id, nameof(MethodHub.StreamingConcat), new StreamPlaceholder(id)); + } + + var words = new[] { "zygapophyses", "qwerty", "abcd" }; + var pos = new[] { 0, 0, 0 }; + var order = new[] { 2, 2, 0, 2, 1, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1 }; + + foreach (var spot in order) + { + await client.SendHubMessageAsync(new StreamDataMessage(spot.ToString(), words[spot][pos[spot]])).OrTimeout(); + pos[spot] += 1; + } + + foreach (string id in new[] { "0", "2", "1" }) + { + await client.SendHubMessageAsync(new StreamCompleteMessage(id)).OrTimeout(); + var response = await client.ReadAsync().OrTimeout(); + Debug.Write(response); + Assert.Equal(words[int.Parse(id)], ((CompletionMessage)response).Result); + } + } + } + [Fact] public async Task ConnectionAbortedIfSendFailsWithProtocolError() { @@ -2381,6 +2469,30 @@ namespace Microsoft.AspNetCore.SignalR.Tests } } + [Fact] + public async Task UploadStreamItemInvalidTypeAutoCasts() + { + // NOTE -- json.net is flexible here, and casts for us + + var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(); + var connectionHandler = serviceProvider.GetService>(); + + using (var client = new TestClient()) + { + var connectionHandlerTask = await client.ConnectAsync(connectionHandler).OrTimeout(); + await client.BeginUploadStreamAsync("invocation", nameof(MethodHub.StreamingConcat), new StreamPlaceholder("id")).OrTimeout(); + + // send integers that are then cast to strings + await client.SendHubMessageAsync(new StreamDataMessage("id", 5)).OrTimeout(); + await client.SendHubMessageAsync(new StreamDataMessage("id", 10)).OrTimeout(); + + await client.SendHubMessageAsync(new StreamCompleteMessage("id")).OrTimeout(); + var response = (CompletionMessage)await client.ReadAsync().OrTimeout(); + + Assert.Equal("510", response.Result); + } + } + [Fact] public async Task ServerReportsProtocolMinorVersion() { @@ -2395,7 +2507,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests using (var client = new TestClient(protocol: testProtocol.Object)) { - var connectionHandlerTask = await client.ConnectAsync(connectionHandler); + var connectionHandlerTask = await client.ConnectAsync(connectionHandler).OrTimeout(); Assert.NotNull(client.HandshakeResponseMessage); Assert.Equal(112, client.HandshakeResponseMessage.MinorVersion); @@ -2405,6 +2517,89 @@ namespace Microsoft.AspNetCore.SignalR.Tests } } + [Fact] + public async Task UploadStreamItemInvalidType() + { + var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(); + var connectionHandler = serviceProvider.GetService>(); + + using (var client = new TestClient()) + { + var connectionHandlerTask = await client.ConnectAsync(connectionHandler).OrTimeout(); + await client.BeginUploadStreamAsync("invocationId", nameof(MethodHub.TestTypeCastingErrors), new StreamPlaceholder("channelId")).OrTimeout(); + + // client is running wild, sending strings not ints. + // this error should be propogated to the user's HubMethod code + await client.SendHubMessageAsync(new StreamItemMessage("channelId", "not a number")).OrTimeout(); + var response = await client.ReadAsync().OrTimeout(); + + Assert.Equal(typeof(CompletionMessage), response.GetType()); + Assert.Equal("error identified and caught", (string)((CompletionMessage)response).Result); + } + } + + [Fact] + public async Task UploadStreamItemInvalidId() + { + var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(services => + { + services.AddSignalR(options => options.EnableDetailedErrors = true); + }); + var connectionHandler = serviceProvider.GetService>(); + + using (var client = new TestClient()) + { + var connectionHandlerTask = await client.ConnectAsync(connectionHandler).OrTimeout(); + await client.SendHubMessageAsync(new StreamItemMessage("fake_id", "not a number")).OrTimeout(); + + // Client is breaking protocol by sending an invalid id, and should be closed. + var message = client.TryRead(); + Assert.IsType(message); + Assert.Equal("Connection closed with an error. KeyNotFoundException: No stream with id 'fake_id' could be found.", ((CloseMessage)message).Error); + } + } + + [Fact] + public async Task UploadStreamCompleteInvalidId() + { + var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(services => + { + services.AddSignalR(options => options.EnableDetailedErrors = true); + }); + var connectionHandler = serviceProvider.GetService>(); + + using (var client = new TestClient()) + { + var connectionHandlerTask = await client.ConnectAsync(connectionHandler).OrTimeout(); + await client.SendHubMessageAsync(new StreamCompleteMessage("fake_id")).OrTimeout(); + + // Client is breaking protocol by sending an invalid id, and should be closed. + var message = client.TryRead(); + Assert.IsType(message); + Assert.Equal("Connection closed with an error. KeyNotFoundException: No stream with id 'fake_id' could be found.", ((CloseMessage)message).Error); + } + } + + public static string CustomErrorMessage = "custom error for testing ::::)"; + + [Fact] + public async Task UploadStreamCompleteWithError() + { + + var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(); + var connectionHandler = serviceProvider.GetService>(); + + using (var client = new TestClient()) + { + var connectionHandlerTask = await client.ConnectAsync(connectionHandler).OrTimeout(); + await client.BeginUploadStreamAsync("invocation", nameof(MethodHub.TestCustomErrorPassing), new StreamPlaceholder("id")).OrTimeout(); + await client.SendHubMessageAsync(new StreamCompleteMessage("id", CustomErrorMessage)).OrTimeout(); + + var response = (CompletionMessage)await client.ReadAsync().OrTimeout(); + Assert.True((bool)response.Result); + } + } + private class CustomHubActivator : IHubActivator where THub : Hub { public int ReleaseCount; @@ -2450,5 +2645,16 @@ namespace Microsoft.AspNetCore.SignalR.Tests public string GetUserId(HubConnectionContext connection) => _getUserId(connection); } + + private class SampleObject + { + public SampleObject(string foo, int bar) + { + Bar = bar; + Foo = foo; + } + public int Bar { get; } + public string Foo { get; } + } } } From 03a7ba4995f1e2d2c6a1b54ee60eafc661f302c4 Mon Sep 17 00:00:00 2001 From: Andrew Stanton-Nurse Date: Wed, 1 Aug 2018 13:21:26 -0700 Subject: [PATCH 02/30] remove Jenkins configs already covered by VSTS (#2706) --- build/buildpipeline/linux.groovy | 1 - build/buildpipeline/osx.groovy | 14 -------------- build/buildpipeline/pipeline.groovy | 8 -------- 3 files changed, 23 deletions(-) delete mode 100644 build/buildpipeline/linux.groovy delete mode 100644 build/buildpipeline/osx.groovy diff --git a/build/buildpipeline/linux.groovy b/build/buildpipeline/linux.groovy deleted file mode 100644 index 791d923d0c..0000000000 --- a/build/buildpipeline/linux.groovy +++ /dev/null @@ -1 +0,0 @@ -@Library('dotnet-ci') _ diff --git a/build/buildpipeline/osx.groovy b/build/buildpipeline/osx.groovy deleted file mode 100644 index 5dfa3d8a48..0000000000 --- a/build/buildpipeline/osx.groovy +++ /dev/null @@ -1,14 +0,0 @@ -@Library('dotnet-ci') _ - -// 'node' indicates to Jenkins that the enclosed block runs on a node that matches -// the label 'windows-with-vs' -simpleNode('OSX.1012.Amd64.Open') { - stage ('Checking out source') { - checkout scm - } - stage ('Build') { - def logFolder = getLogFolder() - def environment = "export ASPNETCORE_TEST_LOG_DIR=${WORKSPACE}/${logFolder}" - sh "${environment}&./build.sh -ci" - } -} diff --git a/build/buildpipeline/pipeline.groovy b/build/buildpipeline/pipeline.groovy index c6c4098d3a..76c23615e8 100644 --- a/build/buildpipeline/pipeline.groovy +++ b/build/buildpipeline/pipeline.groovy @@ -2,8 +2,6 @@ import org.dotnet.ci.pipelines.Pipeline def windowsPipeline = Pipeline.createPipeline(this, 'build/buildpipeline/windows.groovy') def windowsESPipeline = Pipeline.createPipeline(this, 'build/buildpipeline/windows-es.groovy') -def linuxPipeline = Pipeline.createPipeline(this, 'build/buildpipeline/linux.groovy') -def osxPipeline = Pipeline.createPipeline(this, 'build/buildpipeline/osx.groovy') String configuration = 'Release' def parameters = [ 'Configuration': configuration @@ -14,9 +12,3 @@ windowsPipeline.triggerPipelineOnGithubPush(parameters) windowsESPipeline.triggerPipelineOnEveryGithubPR("Windows ${configuration} Spanish Language x64 Build", parameters) windowsESPipeline.triggerPipelineOnGithubPush(parameters) - -linuxPipeline.triggerPipelineOnEveryGithubPR("Ubuntu 16.04 ${configuration} Build", parameters) -linuxPipeline.triggerPipelineOnGithubPush(parameters) - -osxPipeline.triggerPipelineOnEveryGithubPR("OSX 10.12 ${configuration} Build", parameters) -osxPipeline.triggerPipelineOnGithubPush(parameters) From 3f5b361372d8f684e604ebdc690c32f3dccd9133 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 5 Aug 2018 20:05:31 +0000 Subject: [PATCH 03/30] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 98 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index b085209c06..7c7d14ad75 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,57 +5,57 @@ 0.10.13 3.1.0 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10015 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-20180731.2 1.7.3.4 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 4.6.0-preview1-26727-04 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 - 3.0.0-alpha1-10173 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 + 3.0.0-alpha1-10221 2.2.0-preview1-26618-02 15.6.1 4.7.49 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 8c70cbad9f..fe0f897b25 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-10015 -commithash:3f36e5c2f061712f76f2766c435d2555681d5c55 +version:3.0.0-alpha1-20180731.2 +commithash:1179f1083695ac9213c8a70a4d1d6c45a52caf41 From 3b6e728b403470445a97ae00fc44f08768dfa0f3 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 12 Aug 2018 20:14:59 +0000 Subject: [PATCH 04/30] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 112 +++++++++++++++++++-------------------- korebuild-lock.txt | 4 +- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 7c7d14ad75..ddb0c704c5 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,72 +5,72 @@ 0.10.13 3.1.0 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-20180731.2 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-20180810.1 1.7.3.4 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 4.6.0-preview1-26727-04 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 - 3.0.0-alpha1-10221 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 4.6.0-preview1-26807-04 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 + 3.0.0-alpha1-10275 2.2.0-preview1-26618-02 15.6.1 4.7.49 2.0.3 11.0.2 1.2.6 - 4.6.0-preview1-26727-04 - 4.6.0-preview1-26727-04 + 4.6.0-preview1-26807-04 + 4.6.0-preview1-26807-04 4.6.0-preview1-26717-04 - 4.6.0-preview1-26727-04 + 4.6.0-preview1-26807-04 3.1.1 4.3.0 - 4.6.0-preview1-26727-04 - 4.6.0-preview1-26727-04 - 4.6.0-preview1-26727-04 + 4.6.0-preview1-26807-04 + 4.6.0-preview1-26807-04 + 4.6.0-preview1-26807-04 2.3.1 2.3.1 2.3.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index fe0f897b25..c53be3fca9 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180731.2 -commithash:1179f1083695ac9213c8a70a4d1d6c45a52caf41 +version:3.0.0-alpha1-20180810.1 +commithash:45c32b4f020e14a9295be31866051a18d293309d From b05f0fc0be2f370c3500d5f127f743f8bbca59ee Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 19 Aug 2018 19:29:36 +0000 Subject: [PATCH 05/30] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 112 +++++++++++++++++++-------------------- korebuild-lock.txt | 4 +- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index ddb0c704c5..efb11e5a6b 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,72 +5,72 @@ 0.10.13 3.1.0 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-20180810.1 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-20180817.3 1.7.3.4 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 4.6.0-preview1-26807-04 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 - 3.0.0-alpha1-10275 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 4.6.0-preview1-26816-01 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 + 3.0.0-alpha1-10321 2.2.0-preview1-26618-02 15.6.1 4.7.49 2.0.3 11.0.2 1.2.6 - 4.6.0-preview1-26807-04 - 4.6.0-preview1-26807-04 + 4.6.0-preview1-26816-01 + 4.6.0-preview1-26816-01 4.6.0-preview1-26717-04 - 4.6.0-preview1-26807-04 + 4.6.0-preview1-26816-01 3.1.1 4.3.0 - 4.6.0-preview1-26807-04 - 4.6.0-preview1-26807-04 - 4.6.0-preview1-26807-04 + 4.6.0-preview1-26816-01 + 4.6.0-preview1-26816-01 + 4.6.0-preview1-26816-01 2.3.1 2.3.1 2.3.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index c53be3fca9..7abb5ed14d 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180810.1 -commithash:45c32b4f020e14a9295be31866051a18d293309d +version:3.0.0-alpha1-20180817.3 +commithash:134cdbee9bee29dd3ccb654c67663b27b9ffa6c8 From cc84be85bde140ce172b16c2847d851e64d56d50 Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Wed, 22 Aug 2018 10:35:19 -0700 Subject: [PATCH 06/30] Add logging to transport in tests (#2836) --- .../HttpConnectionTests.ConnectionLifecycle.cs | 9 +++++---- .../ServerSentEventsTransportTests.cs | 3 ++- .../TestHttpMessageHandler.cs | 13 ++++++++++++- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.ConnectionLifecycle.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.ConnectionLifecycle.cs index a7af19c405..894e84177d 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.ConnectionLifecycle.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.ConnectionLifecycle.cs @@ -11,6 +11,7 @@ using Microsoft.AspNetCore.Http.Connections; using Microsoft.AspNetCore.Http.Connections.Client; using Microsoft.AspNetCore.Http.Connections.Client.Internal; using Microsoft.AspNetCore.SignalR.Tests; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Testing; using Xunit; using Xunit.Abstractions; @@ -332,16 +333,16 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests writeContext.EventId.Name == "ErrorStartingTransport"; } - using (StartVerifiableLog(out var loggerFactory, expectedErrorsFilter: ExpectedErrors)) + using (StartVerifiableLog(out var loggerFactory, LogLevel.Trace, expectedErrorsFilter: ExpectedErrors)) { - var httpHandler = new TestHttpMessageHandler(); + var httpHandler = new TestHttpMessageHandler(loggerFactory); httpHandler.OnGet("/?id=00000000-0000-0000-0000-000000000000", (_, __) => { return Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.InternalServerError)); }); - var sse = new ServerSentEventsTransport(new HttpClient(httpHandler)); + var sse = new ServerSentEventsTransport(new HttpClient(httpHandler), loggerFactory); await WithConnectionAsync( CreateConnection(httpHandler, loggerFactory: loggerFactory, transport: sse), @@ -367,7 +368,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests return ResponseUtils.CreateResponse(HttpStatusCode.Accepted); }); - var sse = new ServerSentEventsTransport(new HttpClient(httpHandler)); + var sse = new ServerSentEventsTransport(new HttpClient(httpHandler), loggerFactory); await WithConnectionAsync( CreateConnection(httpHandler, loggerFactory: loggerFactory, transport: sse), diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsTransportTests.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsTransportTests.cs index 0830678222..89954fa254 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsTransportTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsTransportTests.cs @@ -14,6 +14,7 @@ using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Http.Connections.Client; using Microsoft.AspNetCore.Http.Connections.Client.Internal; using Microsoft.AspNetCore.SignalR.Tests; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Testing; using Moq; using Moq.Protected; @@ -198,7 +199,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests }); using (var httpClient = new HttpClient(mockHttpHandler.Object)) - using (StartVerifiableLog(out var loggerFactory, expectedErrorsFilter: ExpectedErrors)) + using (StartVerifiableLog(out var loggerFactory, LogLevel.Trace, expectedErrorsFilter: ExpectedErrors)) { var sseTransport = new ServerSentEventsTransport(httpClient, loggerFactory); diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestHttpMessageHandler.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestHttpMessageHandler.cs index 43251e4bc1..75472a4970 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestHttpMessageHandler.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestHttpMessageHandler.cs @@ -4,6 +4,8 @@ using System.Net; using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; namespace Microsoft.AspNetCore.SignalR.Client.Tests { @@ -13,6 +15,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests { private List _receivedRequests = new List(); private RequestDelegate _app; + private readonly ILogger _logger; private List> _middleware = new List>(); @@ -29,8 +32,10 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests } } - public TestHttpMessageHandler(bool autoNegotiate = true, bool handleFirstPoll = true) + public TestHttpMessageHandler(ILoggerFactory loggerFactory, bool autoNegotiate = true, bool handleFirstPoll = true) { + _logger = loggerFactory?.CreateLogger() ?? NullLoggerFactory.Instance.CreateLogger(); + if (autoNegotiate) { OnNegotiate((_, cancellationToken) => ResponseUtils.CreateResponse(HttpStatusCode.OK, ResponseUtils.CreateNegotiationContent())); @@ -54,6 +59,11 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests } } + public TestHttpMessageHandler(bool autoNegotiate = true, bool handleFirstPoll = true) + : this(NullLoggerFactory.Instance, autoNegotiate, handleFirstPoll) + { + } + protected override void Dispose(bool disposing) { Disposed = true; @@ -62,6 +72,7 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { + _logger.LogDebug("Calling handlers for a '{Method}' going to '{Url}'.", request.Method, request.RequestUri); await Task.Yield(); lock (_receivedRequests) From ddfb2f2ea8417e4f211fc1ab789f3377b8332730 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 26 Aug 2018 19:29:18 +0000 Subject: [PATCH 07/30] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 112 +++++++++++++++++++-------------------- korebuild-lock.txt | 4 +- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 561f4765b4..ba4d50b1ac 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,72 +5,72 @@ 0.10.13 3.1.0 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-20180817.3 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-20180821.3 1.7.3.4 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 4.6.0-preview1-26816-01 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 - 3.0.0-alpha1-10321 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 4.6.0-preview1-26817-04 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 + 3.0.0-alpha1-10352 2.2.0-preview1-26618-02 15.6.1 4.7.49 2.0.3 11.0.2 1.2.6 - 4.6.0-preview1-26816-01 - 4.6.0-preview1-26816-01 + 4.6.0-preview1-26817-04 + 4.6.0-preview1-26817-04 4.6.0-preview1-26717-04 - 4.6.0-preview1-26816-01 + 4.6.0-preview1-26817-04 3.1.1 4.3.0 - 4.6.0-preview1-26816-01 - 4.6.0-preview1-26816-01 - 4.6.0-preview1-26816-01 + 4.6.0-preview1-26817-04 + 4.6.0-preview1-26817-04 + 4.6.0-preview1-26817-04 2.3.1 2.3.1 2.3.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 7abb5ed14d..74c82096f1 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180817.3 -commithash:134cdbee9bee29dd3ccb654c67663b27b9ffa6c8 +version:3.0.0-alpha1-20180821.3 +commithash:0939a90812deb1c604eb9a4768869687495fc1dd From 577f905a38145170a0e5d455655b9ec4c5ca54f2 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 2 Sep 2018 19:28:31 +0000 Subject: [PATCH 08/30] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 112 +++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index ba4d50b1ac..6d5b5c496b 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,72 +5,72 @@ 0.10.13 3.1.0 - 3.0.0-alpha1-10352 + 3.0.0-alpha1-10393 3.0.0-alpha1-20180821.3 1.7.3.4 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 4.6.0-preview1-26817-04 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 - 3.0.0-alpha1-10352 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 4.6.0-preview1-26829-04 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 + 3.0.0-alpha1-10393 2.2.0-preview1-26618-02 15.6.1 - 4.7.49 + 4.9.0 2.0.3 11.0.2 1.2.6 - 4.6.0-preview1-26817-04 - 4.6.0-preview1-26817-04 + 4.6.0-preview1-26829-04 + 4.6.0-preview1-26829-04 4.6.0-preview1-26717-04 - 4.6.0-preview1-26817-04 + 4.6.0-preview1-26829-04 3.1.1 4.3.0 - 4.6.0-preview1-26817-04 - 4.6.0-preview1-26817-04 - 4.6.0-preview1-26817-04 + 4.6.0-preview1-26829-04 + 4.6.0-preview1-26829-04 + 4.6.0-preview1-26829-04 2.3.1 2.3.1 2.3.1 From 8eb15ff029d9eff5600b2ed5ffa8193b52daa8e7 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Thu, 6 Sep 2018 00:01:14 +0000 Subject: [PATCH 09/30] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 112 +++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 6d5b5c496b..1d9470f6d1 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,72 +5,72 @@ 0.10.13 3.1.0 - 3.0.0-alpha1-10393 + 3.0.0-alpha1-10400 3.0.0-alpha1-20180821.3 1.7.3.4 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 4.6.0-preview1-26829-04 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 3.0.0-alpha1-10393 - 2.2.0-preview1-26618-02 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 4.6.0-preview1-26831-06 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 3.0.0-alpha1-10400 + 2.2.0-preview2-26905-02 15.6.1 4.9.0 2.0.3 11.0.2 1.2.6 - 4.6.0-preview1-26829-04 - 4.6.0-preview1-26829-04 + 4.6.0-preview1-26831-06 + 4.6.0-preview1-26831-06 4.6.0-preview1-26717-04 - 4.6.0-preview1-26829-04 + 4.6.0-preview1-26831-06 3.1.1 4.3.0 - 4.6.0-preview1-26829-04 - 4.6.0-preview1-26829-04 - 4.6.0-preview1-26829-04 + 4.6.0-preview1-26831-06 + 4.6.0-preview1-26831-06 + 4.6.0-preview1-26831-06 2.3.1 2.3.1 2.3.1 From 94e14783208adf99c917f21db8001abd91820c90 Mon Sep 17 00:00:00 2001 From: Ahson Khan Date: Fri, 7 Sep 2018 19:18:49 -0700 Subject: [PATCH 10/30] Add Handshake Protocol benchmarks and more Negotiate Protocol benchmark (#2930) cases --- .../HandshakeProtocolBenchmark.cs | 127 ++++++++++++++++++ .../NegotiateProtocolBenchmark.cs | 38 +++++- 2 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HandshakeProtocolBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HandshakeProtocolBenchmark.cs b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HandshakeProtocolBenchmark.cs new file mode 100644 index 0000000000..2a36dc648e --- /dev/null +++ b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HandshakeProtocolBenchmark.cs @@ -0,0 +1,127 @@ +// 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; +using System.Buffers; +using System.Text; +using BenchmarkDotNet.Attributes; +using Microsoft.AspNetCore.Internal; +using Microsoft.AspNetCore.SignalR.Protocol; + +namespace Microsoft.AspNetCore.SignalR.Microbenchmarks +{ + public class HandshakeProtocolBenchmark + { + ReadOnlySequence _requestMessage1; + ReadOnlySequence _requestMessage2; + ReadOnlySequence _requestMessage3; + ReadOnlySequence _requestMessage4; + + ReadOnlySequence _responseMessage1; + ReadOnlySequence _responseMessage2; + ReadOnlySequence _responseMessage3; + ReadOnlySequence _responseMessage4; + ReadOnlySequence _responseMessage5; + ReadOnlySequence _responseMessage6; + + [GlobalSetup] + public void GlobalSetup() + { + _requestMessage1 = new ReadOnlySequence(Encoding.UTF8.GetBytes("{\"protocol\":\"dummy\",\"version\":1}\u001e")); + _requestMessage2 = new ReadOnlySequence(Encoding.UTF8.GetBytes("{\"protocol\":\"\",\"version\":10}\u001e")); + _requestMessage3 = new ReadOnlySequence(Encoding.UTF8.GetBytes("{\"protocol\":\"\",\"version\":10,\"unknown\":null}\u001e")); + _requestMessage4 = new ReadOnlySequence(Encoding.UTF8.GetBytes("42")); + + _responseMessage1 = new ReadOnlySequence(Encoding.UTF8.GetBytes("{\"error\":\"dummy\"}\u001e")); + _responseMessage2 = new ReadOnlySequence(Encoding.UTF8.GetBytes("{\"error\":\"\"}\u001e")); + _responseMessage3 = new ReadOnlySequence(Encoding.UTF8.GetBytes("{}\u001e")); + _responseMessage4 = new ReadOnlySequence(Encoding.UTF8.GetBytes("{\"unknown\":null}\u001e")); + _responseMessage5 = new ReadOnlySequence(Encoding.UTF8.GetBytes("{\"error\":\"\",\"minorVersion\":34}\u001e")); + _responseMessage6 = new ReadOnlySequence(Encoding.UTF8.GetBytes("{\"error\":\"flump flump flump\",\"minorVersion\":112}\u001e")); + } + + [Benchmark] + public void HandShakeWriteResponseEmpty_MemoryBufferWriter() + { + var writer = MemoryBufferWriter.Get(); + try + { + HandshakeProtocol.WriteResponseMessage(HandshakeResponseMessage.Empty, writer); + } + finally + { + MemoryBufferWriter.Return(writer); + } + } + + [Benchmark] + public void HandShakeWriteResponse_MemoryBufferWriter() + { + ReadOnlyMemory result; + var memoryBufferWriter = MemoryBufferWriter.Get(); + try + { + HandshakeProtocol.WriteResponseMessage(new HandshakeResponseMessage(1), memoryBufferWriter); + result = memoryBufferWriter.ToArray(); + } + finally + { + MemoryBufferWriter.Return(memoryBufferWriter); + } + } + + [Benchmark] + public void HandShakeWriteRequest_MemoryBufferWriter() + { + var memoryBufferWriter = MemoryBufferWriter.Get(); + try + { + HandshakeProtocol.WriteRequestMessage(new HandshakeRequestMessage("json", 1), memoryBufferWriter); + } + finally + { + MemoryBufferWriter.Return(memoryBufferWriter); + } + } + + [Benchmark] + public void ParsingHandshakeRequestMessage_ValidMessage1() + => HandshakeProtocol.TryParseRequestMessage(ref _requestMessage1, out var deserializedMessage); + + [Benchmark] + public void ParsingHandshakeRequestMessage_ValidMessage2() + => HandshakeProtocol.TryParseRequestMessage(ref _requestMessage2, out var deserializedMessage); + + [Benchmark] + public void ParsingHandshakeRequestMessage_ValidMessage3() + => HandshakeProtocol.TryParseRequestMessage(ref _requestMessage3, out var deserializedMessage); + + [Benchmark] + public void ParsingHandshakeRequestMessage_NotComplete1() + => HandshakeProtocol.TryParseRequestMessage(ref _requestMessage4, out _); + + [Benchmark] + public void ParsingHandshakeResponseMessage_ValidMessages1() + => HandshakeProtocol.TryParseResponseMessage(ref _responseMessage1, out var response); + + [Benchmark] + public void ParsingHandshakeResponseMessage_ValidMessages2() + => HandshakeProtocol.TryParseResponseMessage(ref _responseMessage2, out var response); + + [Benchmark] + public void ParsingHandshakeResponseMessage_ValidMessages3() + => HandshakeProtocol.TryParseResponseMessage(ref _responseMessage3, out var response); + + [Benchmark] + public void ParsingHandshakeResponseMessage_ValidMessages4() + => HandshakeProtocol.TryParseResponseMessage(ref _responseMessage4, out var response); + + [Benchmark] + public void ParsingHandshakeResponseMessage_GivesMinorVersion1() + => HandshakeProtocol.TryParseResponseMessage(ref _responseMessage5, out var response); + + [Benchmark] + public void ParsingHandshakeResponseMessage_GivesMinorVersion2() + => HandshakeProtocol.TryParseResponseMessage(ref _responseMessage6, out var response); + } +} \ No newline at end of file diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/NegotiateProtocolBenchmark.cs b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/NegotiateProtocolBenchmark.cs index 2e4120e187..909b4217d0 100644 --- a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/NegotiateProtocolBenchmark.cs +++ b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/NegotiateProtocolBenchmark.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; +using System.Text; using System.Threading.Tasks; using BenchmarkDotNet.Attributes; using Microsoft.AspNetCore.Http.Connections; @@ -15,6 +16,12 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks private NegotiationResponse _negotiateResponse; private Stream _stream; + private byte[] _responseData1; + private byte[] _responseData2; + private byte[] _responseData3; + private byte[] _responseData4; + private byte[] _responseData5; + [GlobalSetup] public void GlobalSetup() { @@ -35,6 +42,15 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks } }; _stream = Stream.Null; + + _responseData1 = Encoding.UTF8.GetBytes("{\"connectionId\":\"123\",\"availableTransports\":[]}"); + _responseData2 = Encoding.UTF8.GetBytes("{\"url\": \"http://foo.com/chat\"}"); + _responseData3 = Encoding.UTF8.GetBytes("{\"url\": \"http://foo.com/chat\", \"accessToken\": \"token\"}"); + _responseData4 = Encoding.UTF8.GetBytes("{\"connectionId\":\"123\",\"availableTransports\":[{\"transport\":\"test\",\"transferFormats\":[]}]}"); + + var writer = new MemoryBufferWriter(); + NegotiateProtocol.WriteResponse(_negotiateResponse, writer); + _responseData5 = writer.ToArray(); } [Benchmark] @@ -51,5 +67,25 @@ namespace Microsoft.AspNetCore.SignalR.Microbenchmarks writer.Reset(); } } + + [Benchmark] + public void ParsingNegotiateResponseMessageSuccessForValid1() + => NegotiateProtocol.ParseResponse(new MemoryStream(_responseData1)); + + [Benchmark] + public void ParsingNegotiateResponseMessageSuccessForValid2() + => NegotiateProtocol.ParseResponse(new MemoryStream(_responseData2)); + + [Benchmark] + public void ParsingNegotiateResponseMessageSuccessForValid3() + => NegotiateProtocol.ParseResponse(new MemoryStream(_responseData3)); + + [Benchmark] + public void ParsingNegotiateResponseMessageSuccessForValid4() + => NegotiateProtocol.ParseResponse(new MemoryStream(_responseData4)); + + [Benchmark] + public void ParsingNegotiateResponseMessageSuccessForValid5() + => NegotiateProtocol.ParseResponse(new MemoryStream(_responseData5)); } -} +} \ No newline at end of file From 2252c0552d8bdbd43f554fcbd01d4fc750274fba Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 9 Sep 2018 19:30:46 +0000 Subject: [PATCH 11/30] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 112 +++++++++++++++++++-------------------- korebuild-lock.txt | 4 +- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 1d9470f6d1..cbd5ae5742 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,72 +5,72 @@ 0.10.13 3.1.0 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-20180821.3 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-20180907.9 1.7.3.4 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 4.6.0-preview1-26831-06 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 - 3.0.0-alpha1-10400 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 4.6.0-preview1-26905-03 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 + 3.0.0-alpha1-10419 2.2.0-preview2-26905-02 15.6.1 4.9.0 2.0.3 11.0.2 1.2.6 - 4.6.0-preview1-26831-06 - 4.6.0-preview1-26831-06 + 4.6.0-preview1-26905-03 + 4.6.0-preview1-26905-03 4.6.0-preview1-26717-04 - 4.6.0-preview1-26831-06 + 4.6.0-preview1-26905-03 3.1.1 4.3.0 - 4.6.0-preview1-26831-06 - 4.6.0-preview1-26831-06 - 4.6.0-preview1-26831-06 + 4.6.0-preview1-26905-03 + 4.6.0-preview1-26905-03 + 4.6.0-preview1-26905-03 2.3.1 2.3.1 2.3.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 74c82096f1..86de522933 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180821.3 -commithash:0939a90812deb1c604eb9a4768869687495fc1dd +version:3.0.0-alpha1-20180907.9 +commithash:f997365a8832ff0a3cbd9a98df45734ac2723fa0 From e09087e806633c4e23e80831c9b0127a87970a00 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 16 Sep 2018 19:30:05 +0000 Subject: [PATCH 12/30] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 112 +++++++++++++++++++-------------------- korebuild-lock.txt | 4 +- 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index cbd5ae5742..e67a99ad7f 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,72 +5,72 @@ 0.10.13 3.1.0 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-20180907.9 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-20180911.2 1.7.3.4 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 4.6.0-preview1-26905-03 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 - 3.0.0-alpha1-10419 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 4.6.0-preview1-26907-04 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 + 3.0.0-alpha1-10454 2.2.0-preview2-26905-02 15.6.1 4.9.0 2.0.3 11.0.2 1.2.6 - 4.6.0-preview1-26905-03 - 4.6.0-preview1-26905-03 + 4.6.0-preview1-26907-04 + 4.6.0-preview1-26907-04 4.6.0-preview1-26717-04 - 4.6.0-preview1-26905-03 + 4.6.0-preview1-26907-04 3.1.1 4.3.0 - 4.6.0-preview1-26905-03 - 4.6.0-preview1-26905-03 - 4.6.0-preview1-26905-03 + 4.6.0-preview1-26907-04 + 4.6.0-preview1-26907-04 + 4.6.0-preview1-26907-04 2.3.1 2.3.1 2.3.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 86de522933..a3511df82d 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180907.9 -commithash:f997365a8832ff0a3cbd9a98df45734ac2723fa0 +version:3.0.0-alpha1-20180911.2 +commithash:2a2b7dbea1b247930c41da497f4ea0b2bb756818 From 696a07d9e3badeacb4fd1f5f7302558b5b39d225 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 23 Sep 2018 12:28:24 -0700 Subject: [PATCH 13/30] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 103 +++++++++++++++++++-------------------- korebuild-lock.txt | 4 +- 2 files changed, 53 insertions(+), 54 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 9019beba7e..f4eb76cc2f 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,57 +5,57 @@ 0.10.13 3.1.0 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-20180911.2 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-20180919.1 1.7.3.4 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 4.6.0-preview1-26907-04 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 - 3.0.0-alpha1-10454 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 + 3.0.0-alpha1-10495 2.2.0-preview2-26905-02 15.6.1 4.9.0 @@ -64,15 +64,14 @@ 1.2.6 4.6.0-preview1-26907-04 4.6.0-preview1-26907-04 - 4.6.0-preview1-26717-04 + 4.5.0 4.6.0-preview1-26907-04 3.1.1 4.3.0 4.6.0-preview1-26907-04 + 4.6.0-preview1-26907-04 4.6.0-preview1-26907-04 4.6.0-preview1-26907-04 - 4.5.1 - 4.5.0 2.3.1 2.3.1 2.3.1 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index a3511df82d..9a87e4ccb7 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180911.2 -commithash:2a2b7dbea1b247930c41da497f4ea0b2bb756818 +version:3.0.0-alpha1-20180919.1 +commithash:3066ae0a230870ea07e3f132605b5e5493f8bbd4 From 71ba4b75e0dfdd2e2ef2d97a3c704c4afd0def55 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 30 Sep 2018 12:28:32 -0700 Subject: [PATCH 14/30] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 98 ++++++++++++++++++++-------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index f4eb76cc2f..09d4bfdd18 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,57 +5,57 @@ 0.10.13 3.1.0 - 3.0.0-alpha1-10495 + 3.0.0-alpha1-10549 3.0.0-alpha1-20180919.1 1.7.3.4 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 4.6.0-preview1-26907-04 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 - 3.0.0-alpha1-10495 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 + 3.0.0-alpha1-10549 2.2.0-preview2-26905-02 15.6.1 4.9.0 @@ -64,7 +64,7 @@ 1.2.6 4.6.0-preview1-26907-04 4.6.0-preview1-26907-04 - 4.5.0 + 4.6.0-preview1-26717-04 4.6.0-preview1-26907-04 3.1.1 4.3.0 From 2a5b42cbe36967917b39a743e939d5759b49c490 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Sun, 7 Oct 2018 12:30:10 -0700 Subject: [PATCH 15/30] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 98 ++++++++++++++++++++-------------------- korebuild-lock.txt | 4 +- 2 files changed, 51 insertions(+), 51 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 09d4bfdd18..3bb618737f 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,57 +5,57 @@ 0.10.13 3.1.0 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-20180919.1 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-20181004.7 1.7.3.4 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 4.6.0-preview1-26907-04 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 - 3.0.0-alpha1-10549 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 + 3.0.0-alpha1-10584 2.2.0-preview2-26905-02 15.6.1 4.9.0 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 9a87e4ccb7..14c4ea8ed3 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20180919.1 -commithash:3066ae0a230870ea07e3f132605b5e5493f8bbd4 +version:3.0.0-alpha1-20181004.7 +commithash:27fabdaf2b1d4753c3d2749581694ca65d78f7f2 From 48728a72ca7a8bab1bac68c0916a51737b729ff8 Mon Sep 17 00:00:00 2001 From: "ASP.NET CI" Date: Thu, 11 Oct 2018 12:26:21 -0700 Subject: [PATCH 16/30] Update dependencies.props [auto-updated: dependencies] --- build/dependencies.props | 102 +++++++++++++++++++-------------------- korebuild-lock.txt | 4 +- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 743b23172b..9f2f8bc7d9 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,64 +5,64 @@ 0.10.13 3.1.0 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-20181004.7 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-20181011.3 1.7.3.4 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 4.6.0-preview1-26907-04 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 - 3.0.0-alpha1-10584 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 + 3.0.0-alpha1-10605 2.2.0-preview2-26905-02 15.6.1 - 4.9.0 + 4.10.0 2.0.3 11.0.2 - 1.2.6 2.0.513 + 1.2.6 4.6.0-preview1-26907-04 4.6.0-preview1-26907-04 4.6.0-preview1-26717-04 diff --git a/korebuild-lock.txt b/korebuild-lock.txt index 14c4ea8ed3..b886680b23 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20181004.7 -commithash:27fabdaf2b1d4753c3d2749581694ca65d78f7f2 +version:3.0.0-alpha1-20181011.3 +commithash:e7569d931e994629267ab2646e9926140962b4ac From 44dd99fd54b75050f7bc8fc808d598ecee40a4ab Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Thu, 25 Oct 2018 09:45:04 -0700 Subject: [PATCH 17/30] Update deps --- build/dependencies.props | 96 ++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/build/dependencies.props b/build/dependencies.props index 9f2f8bc7d9..b8a6e5e7ec 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,58 +5,58 @@ 0.10.13 3.1.0 - 3.0.0-alpha1-10605 + 3.0.0-alpha1-10657 3.0.0-alpha1-20181011.3 1.7.3.4 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10657 + 3.0.0-alpha1-10660 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 2.2.0-rtm-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10657 + 3.0.0-alpha1-10660 4.6.0-preview1-26907-04 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 3.0.0-alpha1-10605 - 2.2.0-preview2-26905-02 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10657 + 3.0.0-alpha1-10657 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10657 + 3.0.0-alpha1-10660 + 3.0.0-alpha1-10657 + 3.0.0-alpha1-10657 + 3.0.0-alpha1-10657 + 2.2.0-rtm-27023-02 15.6.1 4.10.0 2.0.3 From cd4a1c036a56fc44a164a52bf7210a5539e7da8b Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Wed, 31 Oct 2018 15:16:44 -0700 Subject: [PATCH 18/30] Remove SignalR.Redis package (#3241) --- SignalR.sln | 14 - .../BenchmarkServer/BenchmarkServer.csproj | 2 +- benchmarkapps/BenchmarkServer/Startup.cs | 2 +- build/dependencies.props | 1 - samples/SignalRSamples/SignalRSamples.csproj | 4 +- samples/SignalRSamples/Startup.cs | 2 +- .../Internal/AckHandler.cs | 117 ---- .../Internal/GroupAction.cs | 15 - .../Internal/MessagePackUtil.cs | 68 -- .../Internal/RedisChannels.cs | 75 --- .../Internal/RedisGroupCommand.cs | 42 -- .../Internal/RedisInvocation.cs | 35 -- .../Internal/RedisLog.cs | 119 ---- .../Internal/RedisProtocol.cs | 208 ------- .../Internal/RedisSubscriptionManager.cs | 63 -- .../Microsoft.AspNetCore.SignalR.Redis.csproj | 23 - .../RedisDependencyInjectionExtensions.cs | 69 -- .../RedisHubLifetimeManager.cs | 587 ------------------ .../RedisOptions.cs | 50 -- .../baseline.netcore.json | 532 ---------------- .../Docker.cs | 192 ------ .../EchoHub.cs | 31 - ...soft.AspNetCore.SignalR.Redis.Tests.csproj | 27 - ...RedisDependencyInjectionExtensionsTests.cs | 41 -- .../RedisEndToEnd.cs | 198 ------ .../RedisHubLifetimeManagerTests.cs | 102 --- .../RedisProtocolTests.cs | 202 ------ .../RedisServerFixture.cs | 64 -- .../SkipIfDockerNotPresentAttribute.cs | 39 -- .../Startup.cs | 49 -- .../TestConnectionMultiplexer.cs | 350 ----------- 31 files changed, 5 insertions(+), 3318 deletions(-) delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/Internal/AckHandler.cs delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/Internal/GroupAction.cs delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/Internal/MessagePackUtil.cs delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisChannels.cs delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisGroupCommand.cs delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisInvocation.cs delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisLog.cs delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisProtocol.cs delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisSubscriptionManager.cs delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/Microsoft.AspNetCore.SignalR.Redis.csproj delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/RedisDependencyInjectionExtensions.cs delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/RedisHubLifetimeManager.cs delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/RedisOptions.cs delete mode 100644 src/Microsoft.AspNetCore.SignalR.Redis/baseline.netcore.json delete mode 100644 test/Microsoft.AspNetCore.SignalR.Redis.Tests/Docker.cs delete mode 100644 test/Microsoft.AspNetCore.SignalR.Redis.Tests/EchoHub.cs delete mode 100644 test/Microsoft.AspNetCore.SignalR.Redis.Tests/Microsoft.AspNetCore.SignalR.Redis.Tests.csproj delete mode 100644 test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisDependencyInjectionExtensionsTests.cs delete mode 100644 test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisEndToEnd.cs delete mode 100644 test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisHubLifetimeManagerTests.cs delete mode 100644 test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisProtocolTests.cs delete mode 100644 test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisServerFixture.cs delete mode 100644 test/Microsoft.AspNetCore.SignalR.Redis.Tests/SkipIfDockerNotPresentAttribute.cs delete mode 100644 test/Microsoft.AspNetCore.SignalR.Redis.Tests/Startup.cs delete mode 100644 test/Microsoft.AspNetCore.SignalR.Redis.Tests/TestConnectionMultiplexer.cs diff --git a/SignalR.sln b/SignalR.sln index 7f925af865..6f8900fb5f 100644 --- a/SignalR.sln +++ b/SignalR.sln @@ -33,8 +33,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Http.C EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Core", "src\Microsoft.AspNetCore.SignalR.Core\Microsoft.AspNetCore.SignalR.Core.csproj", "{42E76F87-92B6-45AB-BF07-6B811C0F2CAC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Redis", "src\Microsoft.AspNetCore.SignalR.Redis\Microsoft.AspNetCore.SignalR.Redis.csproj", "{59319B72-38BE-4041-8E5C-FF6938874CE8}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SocialWeather", "samples\SocialWeather\SocialWeather.csproj", "{8D789F94-CB74-45FD-ACE7-92AF6E55042E}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Tests", "test\Microsoft.AspNetCore.SignalR.Tests\Microsoft.AspNetCore.SignalR.Tests.csproj", "{1CE2B3BE-056C-41E3-A5F5-6A1EF1D288BA}" @@ -69,8 +67,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Client", "src\Microsoft.AspNetCore.SignalR.Client\Microsoft.AspNetCore.SignalR.Client.csproj", "{BE982591-F4BB-42D9-ABD4-A5D44C65971E}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SignalR.Redis.Tests", "test\Microsoft.AspNetCore.SignalR.Redis.Tests\Microsoft.AspNetCore.SignalR.Redis.Tests.csproj", "{0B083AE6-86CA-4E0B-AE02-59154D1FD005}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JwtSample", "samples\JwtSample\JwtSample.csproj", "{6A7491D3-3C97-49BD-A71C-433AED657F30}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JwtClientSample", "samples\JwtClientSample\JwtClientSample.csproj", "{1A953296-E869-4DE2-A693-FD5FCDE27057}" @@ -113,10 +109,6 @@ Global {42E76F87-92B6-45AB-BF07-6B811C0F2CAC}.Debug|Any CPU.Build.0 = Debug|Any CPU {42E76F87-92B6-45AB-BF07-6B811C0F2CAC}.Release|Any CPU.ActiveCfg = Release|Any CPU {42E76F87-92B6-45AB-BF07-6B811C0F2CAC}.Release|Any CPU.Build.0 = Release|Any CPU - {59319B72-38BE-4041-8E5C-FF6938874CE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {59319B72-38BE-4041-8E5C-FF6938874CE8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {59319B72-38BE-4041-8E5C-FF6938874CE8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {59319B72-38BE-4041-8E5C-FF6938874CE8}.Release|Any CPU.Build.0 = Release|Any CPU {8D789F94-CB74-45FD-ACE7-92AF6E55042E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {8D789F94-CB74-45FD-ACE7-92AF6E55042E}.Debug|Any CPU.Build.0 = Debug|Any CPU {8D789F94-CB74-45FD-ACE7-92AF6E55042E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -177,10 +169,6 @@ Global {BE982591-F4BB-42D9-ABD4-A5D44C65971E}.Debug|Any CPU.Build.0 = Debug|Any CPU {BE982591-F4BB-42D9-ABD4-A5D44C65971E}.Release|Any CPU.ActiveCfg = Release|Any CPU {BE982591-F4BB-42D9-ABD4-A5D44C65971E}.Release|Any CPU.Build.0 = Release|Any CPU - {0B083AE6-86CA-4E0B-AE02-59154D1FD005}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0B083AE6-86CA-4E0B-AE02-59154D1FD005}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0B083AE6-86CA-4E0B-AE02-59154D1FD005}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0B083AE6-86CA-4E0B-AE02-59154D1FD005}.Release|Any CPU.Build.0 = Release|Any CPU {6A7491D3-3C97-49BD-A71C-433AED657F30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6A7491D3-3C97-49BD-A71C-433AED657F30}.Debug|Any CPU.Build.0 = Debug|Any CPU {6A7491D3-3C97-49BD-A71C-433AED657F30}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -233,7 +221,6 @@ Global {C4AEAB04-F341-4539-B6C0-52368FB4BF9E} = {C4BC9889-B49F-41B6-806B-F84941B2549B} {AAD719D5-5E31-4ED1-A60F-6EB92EFA66D9} = {6A35B453-52EC-48AF-89CA-D4A69800F131} {42E76F87-92B6-45AB-BF07-6B811C0F2CAC} = {DA69F624-5398-4884-87E4-B816698CDE65} - {59319B72-38BE-4041-8E5C-FF6938874CE8} = {DA69F624-5398-4884-87E4-B816698CDE65} {8D789F94-CB74-45FD-ACE7-92AF6E55042E} = {C4BC9889-B49F-41B6-806B-F84941B2549B} {1CE2B3BE-056C-41E3-A5F5-6A1EF1D288BA} = {6A35B453-52EC-48AF-89CA-D4A69800F131} {BA99C2A1-48F9-4FA5-B95A-9687A73B7CC9} = {C4BC9889-B49F-41B6-806B-F84941B2549B} @@ -249,7 +236,6 @@ Global {B0243F99-2D3F-4CC6-AD71-E3F891B64724} = {DA69F624-5398-4884-87E4-B816698CDE65} {E081EE41-D95F-4AD2-BC0B-4B562C0A2A47} = {DA69F624-5398-4884-87E4-B816698CDE65} {BE982591-F4BB-42D9-ABD4-A5D44C65971E} = {DA69F624-5398-4884-87E4-B816698CDE65} - {0B083AE6-86CA-4E0B-AE02-59154D1FD005} = {6A35B453-52EC-48AF-89CA-D4A69800F131} {6A7491D3-3C97-49BD-A71C-433AED657F30} = {C4BC9889-B49F-41B6-806B-F84941B2549B} {1A953296-E869-4DE2-A693-FD5FCDE27057} = {C4BC9889-B49F-41B6-806B-F84941B2549B} {0A0A6135-EA24-4307-95C2-CE1B7E164A5E} = {6A35B453-52EC-48AF-89CA-D4A69800F131} diff --git a/benchmarkapps/BenchmarkServer/BenchmarkServer.csproj b/benchmarkapps/BenchmarkServer/BenchmarkServer.csproj index 67a14ce4e7..f9dedb7341 100644 --- a/benchmarkapps/BenchmarkServer/BenchmarkServer.csproj +++ b/benchmarkapps/BenchmarkServer/BenchmarkServer.csproj @@ -14,7 +14,7 @@ - + diff --git a/benchmarkapps/BenchmarkServer/Startup.cs b/benchmarkapps/BenchmarkServer/Startup.cs index 3363b8de58..a9f167cae9 100644 --- a/benchmarkapps/BenchmarkServer/Startup.cs +++ b/benchmarkapps/BenchmarkServer/Startup.cs @@ -28,7 +28,7 @@ namespace BenchmarkServer var redisConnectionString = _config["SignalRRedis"]; if (!string.IsNullOrEmpty(redisConnectionString)) { - signalrBuilder.AddRedis(redisConnectionString); + signalrBuilder.AddStackExchangeRedis(redisConnectionString); } } diff --git a/build/dependencies.props b/build/dependencies.props index b8a6e5e7ec..246320791f 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -62,7 +62,6 @@ 2.0.3 11.0.2 2.0.513 - 1.2.6 4.6.0-preview1-26907-04 4.6.0-preview1-26907-04 4.6.0-preview1-26717-04 diff --git a/samples/SignalRSamples/SignalRSamples.csproj b/samples/SignalRSamples/SignalRSamples.csproj index 76733a4496..5a93bdd381 100644 --- a/samples/SignalRSamples/SignalRSamples.csproj +++ b/samples/SignalRSamples/SignalRSamples.csproj @@ -10,7 +10,7 @@ - + @@ -21,8 +21,8 @@ - + diff --git a/samples/SignalRSamples/Startup.cs b/samples/SignalRSamples/Startup.cs index 89593f21cd..f8516fe9ae 100644 --- a/samples/SignalRSamples/Startup.cs +++ b/samples/SignalRSamples/Startup.cs @@ -29,7 +29,7 @@ namespace SignalRSamples options.KeepAliveInterval = TimeSpan.FromSeconds(5); }) .AddMessagePackProtocol(); - //.AddRedis(); + //.AddStackExchangeRedis(); services.AddCors(o => { diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/AckHandler.cs b/src/Microsoft.AspNetCore.SignalR.Redis/Internal/AckHandler.cs deleted file mode 100644 index c5502e28a2..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/AckHandler.cs +++ /dev/null @@ -1,117 +0,0 @@ -// 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; -using System.Collections.Concurrent; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.SignalR.Redis.Internal -{ - internal class AckHandler : IDisposable - { - private readonly ConcurrentDictionary _acks = new ConcurrentDictionary(); - private readonly Timer _timer; - private readonly TimeSpan _ackThreshold = TimeSpan.FromSeconds(30); - private readonly TimeSpan _ackInterval = TimeSpan.FromSeconds(5); - private readonly object _lock = new object(); - private bool _disposed; - - public AckHandler() - { - // Don't capture the current ExecutionContext and its AsyncLocals onto the timer - bool restoreFlow = false; - try - { - if (!ExecutionContext.IsFlowSuppressed()) - { - ExecutionContext.SuppressFlow(); - restoreFlow = true; - } - - _timer = new Timer(state => ((AckHandler)state).CheckAcks(), state: this, dueTime: _ackInterval, period: _ackInterval); - } - finally - { - // Restore the current ExecutionContext - if (restoreFlow) - { - ExecutionContext.RestoreFlow(); - } - } - } - - public Task CreateAck(int id) - { - lock (_lock) - { - if (_disposed) - { - return Task.CompletedTask; - } - - return _acks.GetOrAdd(id, _ => new AckInfo()).Tcs.Task; - } - } - - public void TriggerAck(int id) - { - if (_acks.TryRemove(id, out var ack)) - { - ack.Tcs.TrySetResult(null); - } - } - - private void CheckAcks() - { - if (_disposed) - { - return; - } - - var utcNow = DateTime.UtcNow; - - foreach (var pair in _acks) - { - var elapsed = utcNow - pair.Value.Created; - if (elapsed > _ackThreshold) - { - if (_acks.TryRemove(pair.Key, out var ack)) - { - ack.Tcs.TrySetCanceled(); - } - } - } - } - - public void Dispose() - { - lock (_lock) - { - _disposed = true; - - _timer.Dispose(); - - foreach (var pair in _acks) - { - if (_acks.TryRemove(pair.Key, out var ack)) - { - ack.Tcs.TrySetCanceled(); - } - } - } - } - - private class AckInfo - { - public TaskCompletionSource Tcs { get; private set; } - public DateTime Created { get; private set; } - - public AckInfo() - { - Created = DateTime.UtcNow; - Tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); - } - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/GroupAction.cs b/src/Microsoft.AspNetCore.SignalR.Redis/Internal/GroupAction.cs deleted file mode 100644 index 874d190f84..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/GroupAction.cs +++ /dev/null @@ -1,15 +0,0 @@ -// 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. - -namespace Microsoft.AspNetCore.SignalR.Redis.Internal -{ - // The size of the enum is defined by the protocol. Do not change it. If you need more than 255 items, - // add an additional enum. - public enum GroupAction : byte - { - // These numbers are used by the protocol, do not change them and always use explicit assignment - // when adding new items to this enum. 0 is intentionally omitted - Add = 1, - Remove = 2, - } -} diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/MessagePackUtil.cs b/src/Microsoft.AspNetCore.SignalR.Redis/Internal/MessagePackUtil.cs deleted file mode 100644 index b824d90394..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/MessagePackUtil.cs +++ /dev/null @@ -1,68 +0,0 @@ -// 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; -using System.Diagnostics; -using System.Runtime.InteropServices; -using MessagePack; - -namespace Microsoft.AspNetCore.SignalR.Redis.Internal -{ - internal static class MessagePackUtil - { - public static int ReadArrayHeader(ref ReadOnlyMemory data) - { - var arr = GetArray(data); - var val = MessagePackBinary.ReadArrayHeader(arr.Array, arr.Offset, out var readSize); - data = data.Slice(readSize); - return val; - } - - public static int ReadMapHeader(ref ReadOnlyMemory data) - { - var arr = GetArray(data); - var val = MessagePackBinary.ReadMapHeader(arr.Array, arr.Offset, out var readSize); - data = data.Slice(readSize); - return val; - } - - public static string ReadString(ref ReadOnlyMemory data) - { - var arr = GetArray(data); - var val = MessagePackBinary.ReadString(arr.Array, arr.Offset, out var readSize); - data = data.Slice(readSize); - return val; - } - - public static byte[] ReadBytes(ref ReadOnlyMemory data) - { - var arr = GetArray(data); - var val = MessagePackBinary.ReadBytes(arr.Array, arr.Offset, out var readSize); - data = data.Slice(readSize); - return val; - } - - public static int ReadInt32(ref ReadOnlyMemory data) - { - var arr = GetArray(data); - var val = MessagePackBinary.ReadInt32(arr.Array, arr.Offset, out var readSize); - data = data.Slice(readSize); - return val; - } - - public static byte ReadByte(ref ReadOnlyMemory data) - { - var arr = GetArray(data); - var val = MessagePackBinary.ReadByte(arr.Array, arr.Offset, out var readSize); - data = data.Slice(readSize); - return val; - } - - private static ArraySegment GetArray(ReadOnlyMemory data) - { - var isArray = MemoryMarshal.TryGetArray(data, out var array); - Debug.Assert(isArray); - return array; - } - } -} diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisChannels.cs b/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisChannels.cs deleted file mode 100644 index 28393b2886..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisChannels.cs +++ /dev/null @@ -1,75 +0,0 @@ -// 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.Runtime.CompilerServices; - -namespace Microsoft.AspNetCore.SignalR.Redis.Internal -{ - internal class RedisChannels - { - private readonly string _prefix; - - /// - /// Gets the name of the channel for sending to all connections. - /// - /// - /// The payload on this channel is objects containing - /// invocations to be sent to all connections - /// - public string All { get; } - - /// - /// Gets the name of the internal channel for group management messages. - /// - public string GroupManagement { get; } - - public RedisChannels(string prefix) - { - _prefix = prefix; - - All = prefix + ":all"; - GroupManagement = prefix + ":internal:groups"; - } - - /// - /// Gets the name of the channel for sending a message to a specific connection. - /// - /// The ID of the connection to get the channel for. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public string Connection(string connectionId) - { - return _prefix + ":connection:" + connectionId; - } - - /// - /// Gets the name of the channel for sending a message to a named group of connections. - /// - /// The name of the group to get the channel for. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public string Group(string groupName) - { - return _prefix + ":group:" + groupName; - } - - /// - /// Gets the name of the channel for sending a message to all collections associated with a user. - /// - /// The ID of the user to get the channel for. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public string User(string userId) - { - return _prefix + ":user:" + userId; - } - - /// - /// Gets the name of the acknowledgement channel for the specified server. - /// - /// The name of the server to get the acknowledgement channel for. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public string Ack(string serverName) - { - return _prefix + ":internal:ack:" + serverName; - } - } -} diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisGroupCommand.cs b/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisGroupCommand.cs deleted file mode 100644 index 3759da98ae..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisGroupCommand.cs +++ /dev/null @@ -1,42 +0,0 @@ -// 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. - -namespace Microsoft.AspNetCore.SignalR.Redis.Internal -{ - public readonly struct RedisGroupCommand - { - /// - /// Gets the ID of the group command. - /// - public int Id { get; } - - /// - /// Gets the name of the server that sent the command. - /// - public string ServerName { get; } - - /// - /// Gets the action to be performed on the group. - /// - public GroupAction Action { get; } - - /// - /// Gets the group on which the action is performed. - /// - public string GroupName { get; } - - /// - /// Gets the ID of the connection to be added or removed from the group. - /// - public string ConnectionId { get; } - - public RedisGroupCommand(int id, string serverName, GroupAction action, string groupName, string connectionId) - { - Id = id; - ServerName = serverName; - Action = action; - GroupName = groupName; - ConnectionId = connectionId; - } - } -} diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisInvocation.cs b/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisInvocation.cs deleted file mode 100644 index a1a8a3ee07..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisInvocation.cs +++ /dev/null @@ -1,35 +0,0 @@ -// 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.Collections.Generic; -using Microsoft.AspNetCore.SignalR.Protocol; - -namespace Microsoft.AspNetCore.SignalR.Redis.Internal -{ - public readonly struct RedisInvocation - { - /// - /// Gets a list of connections that should be excluded from this invocation. - /// May be null to indicate that no connections are to be excluded. - /// - public IReadOnlyList ExcludedConnectionIds { get; } - - /// - /// Gets the message serialization cache containing serialized payloads for the message. - /// - public SerializedHubMessage Message { get; } - - public RedisInvocation(SerializedHubMessage message, IReadOnlyList excludedConnectionIds) - { - Message = message; - ExcludedConnectionIds = excludedConnectionIds; - } - - public static RedisInvocation Create(string target, object[] arguments, IReadOnlyList excludedConnectionIds = null) - { - return new RedisInvocation( - new SerializedHubMessage(new InvocationMessage(target, null, arguments)), - excludedConnectionIds); - } - } -} diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisLog.cs b/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisLog.cs deleted file mode 100644 index ac0e5fb569..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisLog.cs +++ /dev/null @@ -1,119 +0,0 @@ -// 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; -using System.Linq; -using Microsoft.Extensions.Logging; -using StackExchange.Redis; - -namespace Microsoft.AspNetCore.SignalR.Redis.Internal -{ - // We don't want to use our nested static class here because RedisHubLifetimeManager is generic. - // We'd end up creating separate instances of all the LoggerMessage.Define values for each Hub. - internal static class RedisLog - { - private static readonly Action _connectingToEndpoints = - LoggerMessage.Define(LogLevel.Information, new EventId(1, "ConnectingToEndpoints"), "Connecting to Redis endpoints: {Endpoints}. Using Server Name: {ServerName}"); - - private static readonly Action _connected = - LoggerMessage.Define(LogLevel.Information, new EventId(2, "Connected"), "Connected to Redis."); - - private static readonly Action _subscribing = - LoggerMessage.Define(LogLevel.Trace, new EventId(3, "Subscribing"), "Subscribing to channel: {Channel}."); - - private static readonly Action _receivedFromChannel = - LoggerMessage.Define(LogLevel.Trace, new EventId(4, "ReceivedFromChannel"), "Received message from Redis channel {Channel}."); - - private static readonly Action _publishToChannel = - LoggerMessage.Define(LogLevel.Trace, new EventId(5, "PublishToChannel"), "Publishing message to Redis channel {Channel}."); - - private static readonly Action _unsubscribe = - LoggerMessage.Define(LogLevel.Trace, new EventId(6, "Unsubscribe"), "Unsubscribing from channel: {Channel}."); - - private static readonly Action _notConnected = - LoggerMessage.Define(LogLevel.Error, new EventId(7, "Connected"), "Not connected to Redis."); - - private static readonly Action _connectionRestored = - LoggerMessage.Define(LogLevel.Information, new EventId(8, "ConnectionRestored"), "Connection to Redis restored."); - - private static readonly Action _connectionFailed = - LoggerMessage.Define(LogLevel.Error, new EventId(9, "ConnectionFailed"), "Connection to Redis failed."); - - private static readonly Action _failedWritingMessage = - LoggerMessage.Define(LogLevel.Warning, new EventId(10, "FailedWritingMessage"), "Failed writing message."); - - private static readonly Action _internalMessageFailed = - LoggerMessage.Define(LogLevel.Warning, new EventId(11, "InternalMessageFailed"), "Error processing message for internal server message."); - - public static void ConnectingToEndpoints(ILogger logger, EndPointCollection endpoints, string serverName) - { - if (logger.IsEnabled(LogLevel.Information)) - { - if (endpoints.Count > 0) - { - _connectingToEndpoints(logger, string.Join(", ", endpoints.Select(e => EndPointCollection.ToString(e))), serverName, null); - } - } - } - - public static void Connected(ILogger logger) - { - _connected(logger, null); - } - - public static void Subscribing(ILogger logger, string channelName) - { - _subscribing(logger, channelName, null); - } - - public static void ReceivedFromChannel(ILogger logger, string channelName) - { - _receivedFromChannel(logger, channelName, null); - } - - public static void PublishToChannel(ILogger logger, string channelName) - { - _publishToChannel(logger, channelName, null); - } - - public static void Unsubscribe(ILogger logger, string channelName) - { - _unsubscribe(logger, channelName, null); - } - - public static void NotConnected(ILogger logger) - { - _notConnected(logger, null); - } - - public static void ConnectionRestored(ILogger logger) - { - _connectionRestored(logger, null); - } - - public static void ConnectionFailed(ILogger logger, Exception exception) - { - _connectionFailed(logger, exception); - } - - public static void FailedWritingMessage(ILogger logger, Exception exception) - { - _failedWritingMessage(logger, exception); - } - - public static void InternalMessageFailed(ILogger logger, Exception exception) - { - _internalMessageFailed(logger, exception); - } - - // This isn't DefineMessage-based because it's just the simple TextWriter logging from ConnectionMultiplexer - public static void ConnectionMultiplexerMessage(ILogger logger, string message) - { - if (logger.IsEnabled(LogLevel.Debug)) - { - // We tag it with EventId 100 though so it can be pulled out of logs easily. - logger.LogDebug(new EventId(100, "RedisConnectionLog"), message); - } - } - } -} diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisProtocol.cs deleted file mode 100644 index 6eaeb2ee79..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisProtocol.cs +++ /dev/null @@ -1,208 +0,0 @@ -// 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; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; -using MessagePack; -using Microsoft.AspNetCore.Internal; -using Microsoft.AspNetCore.SignalR.Protocol; - -namespace Microsoft.AspNetCore.SignalR.Redis.Internal -{ - public class RedisProtocol - { - private readonly IReadOnlyList _protocols; - - public RedisProtocol(IReadOnlyList protocols) - { - _protocols = protocols; - } - - // The Redis Protocol: - // * The message type is known in advance because messages are sent to different channels based on type - // * Invocations are sent to the All, Group, Connection and User channels - // * Group Commands are sent to the GroupManagement channel - // * Acks are sent to the Acknowledgement channel. - // * See the Write[type] methods for a description of the protocol for each in-depth. - // * The "Variable length integer" is the length-prefixing format used by BinaryReader/BinaryWriter: - // * https://docs.microsoft.com/en-us/dotnet/api/system.io.binarywriter.write?view=netstandard-2.0 - // * The "Length prefixed string" is the string format used by BinaryReader/BinaryWriter: - // * A 7-bit variable length integer encodes the length in bytes, followed by the encoded string in UTF-8. - - public byte[] WriteInvocation(string methodName, object[] args) => - WriteInvocation(methodName, args, excludedConnectionIds: null); - - public byte[] WriteInvocation(string methodName, object[] args, IReadOnlyList excludedConnectionIds) - { - // Written as a MessagePack 'arr' containing at least these items: - // * A MessagePack 'arr' of 'str's representing the excluded ids - // * [The output of WriteSerializedHubMessage, which is an 'arr'] - // Any additional items are discarded. - - var writer = MemoryBufferWriter.Get(); - - try - { - MessagePackBinary.WriteArrayHeader(writer, 2); - if (excludedConnectionIds != null && excludedConnectionIds.Count > 0) - { - MessagePackBinary.WriteArrayHeader(writer, excludedConnectionIds.Count); - foreach (var id in excludedConnectionIds) - { - MessagePackBinary.WriteString(writer, id); - } - } - else - { - MessagePackBinary.WriteArrayHeader(writer, 0); - } - - WriteSerializedHubMessage(writer, - new SerializedHubMessage(new InvocationMessage(methodName, args))); - return writer.ToArray(); - } - finally - { - MemoryBufferWriter.Return(writer); - } - } - - public byte[] WriteGroupCommand(RedisGroupCommand command) - { - // Written as a MessagePack 'arr' containing at least these items: - // * An 'int': the Id of the command - // * A 'str': The server name - // * An 'int': The action (likely less than 0x7F and thus a single-byte fixnum) - // * A 'str': The group name - // * A 'str': The connection Id - // Any additional items are discarded. - - var writer = MemoryBufferWriter.Get(); - try - { - MessagePackBinary.WriteArrayHeader(writer, 5); - MessagePackBinary.WriteInt32(writer, command.Id); - MessagePackBinary.WriteString(writer, command.ServerName); - MessagePackBinary.WriteByte(writer, (byte)command.Action); - MessagePackBinary.WriteString(writer, command.GroupName); - MessagePackBinary.WriteString(writer, command.ConnectionId); - - return writer.ToArray(); - } - finally - { - MemoryBufferWriter.Return(writer); - } - } - - public byte[] WriteAck(int messageId) - { - // Written as a MessagePack 'arr' containing at least these items: - // * An 'int': The Id of the command being acknowledged. - // Any additional items are discarded. - - var writer = MemoryBufferWriter.Get(); - try - { - MessagePackBinary.WriteArrayHeader(writer, 1); - MessagePackBinary.WriteInt32(writer, messageId); - - return writer.ToArray(); - } - finally - { - MemoryBufferWriter.Return(writer); - } - } - - public RedisInvocation ReadInvocation(ReadOnlyMemory data) - { - // See WriteInvocation for the format - ValidateArraySize(ref data, 2, "Invocation"); - - // Read excluded Ids - IReadOnlyList excludedConnectionIds = null; - var idCount = MessagePackUtil.ReadArrayHeader(ref data); - if (idCount > 0) - { - var ids = new string[idCount]; - for (var i = 0; i < idCount; i++) - { - ids[i] = MessagePackUtil.ReadString(ref data); - } - - excludedConnectionIds = ids; - } - - // Read payload - var message = ReadSerializedHubMessage(ref data); - return new RedisInvocation(message, excludedConnectionIds); - } - - public RedisGroupCommand ReadGroupCommand(ReadOnlyMemory data) - { - // See WriteGroupCommand for format. - ValidateArraySize(ref data, 5, "GroupCommand"); - - var id = MessagePackUtil.ReadInt32(ref data); - var serverName = MessagePackUtil.ReadString(ref data); - var action = (GroupAction)MessagePackUtil.ReadByte(ref data); - var groupName = MessagePackUtil.ReadString(ref data); - var connectionId = MessagePackUtil.ReadString(ref data); - - return new RedisGroupCommand(id, serverName, action, groupName, connectionId); - } - - public int ReadAck(ReadOnlyMemory data) - { - // See WriteAck for format - ValidateArraySize(ref data, 1, "Ack"); - return MessagePackUtil.ReadInt32(ref data); - } - - private void WriteSerializedHubMessage(Stream stream, SerializedHubMessage message) - { - // Written as a MessagePack 'map' where the keys are the name of the protocol (as a MessagePack 'str') - // and the values are the serialized blob (as a MessagePack 'bin'). - - MessagePackBinary.WriteMapHeader(stream, _protocols.Count); - - foreach (var protocol in _protocols) - { - MessagePackBinary.WriteString(stream, protocol.Name); - - var serialized = message.GetSerializedMessage(protocol); - var isArray = MemoryMarshal.TryGetArray(serialized, out var array); - Debug.Assert(isArray); - MessagePackBinary.WriteBytes(stream, array.Array, array.Offset, array.Count); - } - } - - public static SerializedHubMessage ReadSerializedHubMessage(ref ReadOnlyMemory data) - { - var count = MessagePackUtil.ReadMapHeader(ref data); - var serializations = new SerializedMessage[count]; - for (var i = 0; i < count; i++) - { - var protocol = MessagePackUtil.ReadString(ref data); - var serialized = MessagePackUtil.ReadBytes(ref data); - serializations[i] = new SerializedMessage(protocol, serialized); - } - - return new SerializedHubMessage(serializations); - } - - private static void ValidateArraySize(ref ReadOnlyMemory data, int expectedLength, string messageType) - { - var length = MessagePackUtil.ReadArrayHeader(ref data); - - if (length < expectedLength) - { - throw new InvalidDataException($"Insufficient items in {messageType} array."); - } - } - } -} diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisSubscriptionManager.cs b/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisSubscriptionManager.cs deleted file mode 100644 index f42f555dc8..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/Internal/RedisSubscriptionManager.cs +++ /dev/null @@ -1,63 +0,0 @@ -// 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; -using System.Collections.Concurrent; -using System.Threading; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.SignalR.Redis.Internal -{ - internal class RedisSubscriptionManager - { - private readonly ConcurrentDictionary _subscriptions = new ConcurrentDictionary(StringComparer.Ordinal); - private readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1); - - public async Task AddSubscriptionAsync(string id, HubConnectionContext connection, Func subscribeMethod) - { - await _lock.WaitAsync(); - - try - { - var subscription = _subscriptions.GetOrAdd(id, _ => new HubConnectionStore()); - - subscription.Add(connection); - - // Subscribe once - if (subscription.Count == 1) - { - await subscribeMethod(id, subscription); - } - } - finally - { - _lock.Release(); - } - } - - public async Task RemoveSubscriptionAsync(string id, HubConnectionContext connection, Func unsubscribeMethod) - { - await _lock.WaitAsync(); - - try - { - if (!_subscriptions.TryGetValue(id, out var subscription)) - { - return; - } - - subscription.Remove(connection); - - if (subscription.Count == 0) - { - _subscriptions.TryRemove(id, out _); - await unsubscribeMethod(id); - } - } - finally - { - _lock.Release(); - } - } - } -} diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/Microsoft.AspNetCore.SignalR.Redis.csproj b/src/Microsoft.AspNetCore.SignalR.Redis/Microsoft.AspNetCore.SignalR.Redis.csproj deleted file mode 100644 index 8862770b75..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/Microsoft.AspNetCore.SignalR.Redis.csproj +++ /dev/null @@ -1,23 +0,0 @@ - - - - Redis for ASP.NET Core SignalR. - netstandard2.0 - - - - - - - - - - - - - - - - - - diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/RedisDependencyInjectionExtensions.cs b/src/Microsoft.AspNetCore.SignalR.Redis/RedisDependencyInjectionExtensions.cs deleted file mode 100644 index 75318cde9a..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/RedisDependencyInjectionExtensions.cs +++ /dev/null @@ -1,69 +0,0 @@ -// 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; -using Microsoft.AspNetCore.SignalR; -using Microsoft.AspNetCore.SignalR.Redis; -using StackExchange.Redis; - -namespace Microsoft.Extensions.DependencyInjection -{ - /// - /// Extension methods for configuring Redis-based scale-out for a SignalR Server in an . - /// - public static class RedisDependencyInjectionExtensions - { - /// - /// Adds scale-out to a , using a shared Redis server. - /// - /// The . - /// The same instance of the for chaining. - public static ISignalRServerBuilder AddRedis(this ISignalRServerBuilder signalrBuilder) - { - return AddRedis(signalrBuilder, o => { }); - } - - /// - /// Adds scale-out to a , using a shared Redis server. - /// - /// The . - /// The connection string used to connect to the Redis server. - /// The same instance of the for chaining. - public static ISignalRServerBuilder AddRedis(this ISignalRServerBuilder signalrBuilder, string redisConnectionString) - { - return AddRedis(signalrBuilder, o => - { - o.Configuration = ConfigurationOptions.Parse(redisConnectionString); - }); - } - - /// - /// Adds scale-out to a , using a shared Redis server. - /// - /// The . - /// A callback to configure the Redis options. - /// The same instance of the for chaining. - public static ISignalRServerBuilder AddRedis(this ISignalRServerBuilder signalrBuilder, Action configure) - { - signalrBuilder.Services.Configure(configure); - signalrBuilder.Services.AddSingleton(typeof(HubLifetimeManager<>), typeof(RedisHubLifetimeManager<>)); - return signalrBuilder; - } - - /// - /// Adds scale-out to a , using a shared Redis server. - /// - /// The . - /// The connection string used to connect to the Redis server. - /// A callback to configure the Redis options. - /// The same instance of the for chaining. - public static ISignalRServerBuilder AddRedis(this ISignalRServerBuilder signalrBuilder, string redisConnectionString, Action configure) - { - return AddRedis(signalrBuilder, o => - { - o.Configuration = ConfigurationOptions.Parse(redisConnectionString); - configure(o); - }); - } - } -} diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/RedisHubLifetimeManager.cs b/src/Microsoft.AspNetCore.SignalR.Redis/RedisHubLifetimeManager.cs deleted file mode 100644 index fc15bd7132..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/RedisHubLifetimeManager.cs +++ /dev/null @@ -1,587 +0,0 @@ -// 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; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.SignalR.Protocol; -using Microsoft.AspNetCore.SignalR.Redis.Internal; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using StackExchange.Redis; - -namespace Microsoft.AspNetCore.SignalR.Redis -{ - public class RedisHubLifetimeManager : HubLifetimeManager, IDisposable where THub : Hub - { - private readonly HubConnectionStore _connections = new HubConnectionStore(); - private readonly RedisSubscriptionManager _groups = new RedisSubscriptionManager(); - private readonly RedisSubscriptionManager _users = new RedisSubscriptionManager(); - private IConnectionMultiplexer _redisServerConnection; - private ISubscriber _bus; - private readonly ILogger _logger; - private readonly RedisOptions _options; - private readonly RedisChannels _channels; - private readonly string _serverName = GenerateServerName(); - private readonly RedisProtocol _protocol; - private readonly SemaphoreSlim _connectionLock = new SemaphoreSlim(1); - - private readonly AckHandler _ackHandler; - private int _internalId; - - public RedisHubLifetimeManager(ILogger> logger, - IOptions options, - IHubProtocolResolver hubProtocolResolver) - { - _logger = logger; - _options = options.Value; - _ackHandler = new AckHandler(); - _channels = new RedisChannels(typeof(THub).FullName); - _protocol = new RedisProtocol(hubProtocolResolver.AllProtocols); - - RedisLog.ConnectingToEndpoints(_logger, options.Value.Configuration.EndPoints, _serverName); - _ = EnsureRedisServerConnection(); - } - - public override async Task OnConnectedAsync(HubConnectionContext connection) - { - await EnsureRedisServerConnection(); - var feature = new RedisFeature(); - connection.Features.Set(feature); - - var connectionTask = Task.CompletedTask; - var userTask = Task.CompletedTask; - - _connections.Add(connection); - - connectionTask = SubscribeToConnection(connection); - - if (!string.IsNullOrEmpty(connection.UserIdentifier)) - { - userTask = SubscribeToUser(connection); - } - - await Task.WhenAll(connectionTask, userTask); - } - - public override Task OnDisconnectedAsync(HubConnectionContext connection) - { - _connections.Remove(connection); - - var tasks = new List(); - - var connectionChannel = _channels.Connection(connection.ConnectionId); - RedisLog.Unsubscribe(_logger, connectionChannel); - tasks.Add(_bus.UnsubscribeAsync(connectionChannel)); - - var feature = connection.Features.Get(); - var groupNames = feature.Groups; - - if (groupNames != null) - { - // Copy the groups to an array here because they get removed from this collection - // in RemoveFromGroupAsync - foreach (var group in groupNames.ToArray()) - { - // Use RemoveGroupAsyncCore because the connection is local and we don't want to - // accidentally go to other servers with our remove request. - tasks.Add(RemoveGroupAsyncCore(connection, group)); - } - } - - if (!string.IsNullOrEmpty(connection.UserIdentifier)) - { - tasks.Add(RemoveUserAsync(connection)); - } - - return Task.WhenAll(tasks); - } - - public override Task SendAllAsync(string methodName, object[] args, CancellationToken cancellationToken = default) - { - var message = _protocol.WriteInvocation(methodName, args); - return PublishAsync(_channels.All, message); - } - - public override Task SendAllExceptAsync(string methodName, object[] args, IReadOnlyList excludedConnectionIds, CancellationToken cancellationToken = default) - { - var message = _protocol.WriteInvocation(methodName, args, excludedConnectionIds); - return PublishAsync(_channels.All, message); - } - - public override Task SendConnectionAsync(string connectionId, string methodName, object[] args, CancellationToken cancellationToken = default) - { - if (connectionId == null) - { - throw new ArgumentNullException(nameof(connectionId)); - } - - // If the connection is local we can skip sending the message through the bus since we require sticky connections. - // This also saves serializing and deserializing the message! - var connection = _connections[connectionId]; - if (connection != null) - { - return connection.WriteAsync(new InvocationMessage(methodName, args)).AsTask(); - } - - var message = _protocol.WriteInvocation(methodName, args); - return PublishAsync(_channels.Connection(connectionId), message); - } - - public override Task SendGroupAsync(string groupName, string methodName, object[] args, CancellationToken cancellationToken = default) - { - if (groupName == null) - { - throw new ArgumentNullException(nameof(groupName)); - } - - var message = _protocol.WriteInvocation(methodName, args); - return PublishAsync(_channels.Group(groupName), message); - } - - public override Task SendGroupExceptAsync(string groupName, string methodName, object[] args, IReadOnlyList excludedConnectionIds, CancellationToken cancellationToken = default) - { - if (groupName == null) - { - throw new ArgumentNullException(nameof(groupName)); - } - - var message = _protocol.WriteInvocation(methodName, args, excludedConnectionIds); - return PublishAsync(_channels.Group(groupName), message); - } - - public override Task SendUserAsync(string userId, string methodName, object[] args, CancellationToken cancellationToken = default) - { - var message = _protocol.WriteInvocation(methodName, args); - return PublishAsync(_channels.User(userId), message); - } - - public override Task AddToGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default) - { - if (connectionId == null) - { - throw new ArgumentNullException(nameof(connectionId)); - } - - if (groupName == null) - { - throw new ArgumentNullException(nameof(groupName)); - } - - var connection = _connections[connectionId]; - if (connection != null) - { - // short circuit if connection is on this server - return AddGroupAsyncCore(connection, groupName); - } - - return SendGroupActionAndWaitForAck(connectionId, groupName, GroupAction.Add); - } - - public override Task RemoveFromGroupAsync(string connectionId, string groupName, CancellationToken cancellationToken = default) - { - if (connectionId == null) - { - throw new ArgumentNullException(nameof(connectionId)); - } - - if (groupName == null) - { - throw new ArgumentNullException(nameof(groupName)); - } - - var connection = _connections[connectionId]; - if (connection != null) - { - // short circuit if connection is on this server - return RemoveGroupAsyncCore(connection, groupName); - } - - return SendGroupActionAndWaitForAck(connectionId, groupName, GroupAction.Remove); - } - - public override Task SendConnectionsAsync(IReadOnlyList connectionIds, string methodName, object[] args, CancellationToken cancellationToken = default) - { - if (connectionIds == null) - { - throw new ArgumentNullException(nameof(connectionIds)); - } - - var publishTasks = new List(connectionIds.Count); - var payload = _protocol.WriteInvocation(methodName, args); - - foreach (var connectionId in connectionIds) - { - publishTasks.Add(PublishAsync(_channels.Connection(connectionId), payload)); - } - - return Task.WhenAll(publishTasks); - } - - public override Task SendGroupsAsync(IReadOnlyList groupNames, string methodName, object[] args, CancellationToken cancellationToken = default) - { - if (groupNames == null) - { - throw new ArgumentNullException(nameof(groupNames)); - } - var publishTasks = new List(groupNames.Count); - var payload = _protocol.WriteInvocation(methodName, args); - - foreach (var groupName in groupNames) - { - if (!string.IsNullOrEmpty(groupName)) - { - publishTasks.Add(PublishAsync(_channels.Group(groupName), payload)); - } - } - - return Task.WhenAll(publishTasks); - } - - public override Task SendUsersAsync(IReadOnlyList userIds, string methodName, object[] args, CancellationToken cancellationToken = default) - { - if (userIds.Count > 0) - { - var payload = _protocol.WriteInvocation(methodName, args); - var publishTasks = new List(userIds.Count); - foreach (var userId in userIds) - { - if (!string.IsNullOrEmpty(userId)) - { - publishTasks.Add(PublishAsync(_channels.User(userId), payload)); - } - } - - return Task.WhenAll(publishTasks); - } - - return Task.CompletedTask; - } - - private async Task PublishAsync(string channel, byte[] payload) - { - await EnsureRedisServerConnection(); - RedisLog.PublishToChannel(_logger, channel); - await _bus.PublishAsync(channel, payload); - } - - private Task AddGroupAsyncCore(HubConnectionContext connection, string groupName) - { - var feature = connection.Features.Get(); - var groupNames = feature.Groups; - - lock (groupNames) - { - // Connection already in group - if (!groupNames.Add(groupName)) - { - return Task.CompletedTask; - } - } - - var groupChannel = _channels.Group(groupName); - return _groups.AddSubscriptionAsync(groupChannel, connection, SubscribeToGroupAsync); - } - - /// - /// This takes because we want to remove the connection from the - /// _connections list in OnDisconnectedAsync and still be able to remove groups with this method. - /// - private async Task RemoveGroupAsyncCore(HubConnectionContext connection, string groupName) - { - var groupChannel = _channels.Group(groupName); - - await _groups.RemoveSubscriptionAsync(groupChannel, connection, channelName => - { - RedisLog.Unsubscribe(_logger, channelName); - return _bus.UnsubscribeAsync(channelName); - }); - - var feature = connection.Features.Get(); - var groupNames = feature.Groups; - if (groupNames != null) - { - lock (groupNames) - { - groupNames.Remove(groupName); - } - } - } - - private async Task SendGroupActionAndWaitForAck(string connectionId, string groupName, GroupAction action) - { - var id = Interlocked.Increment(ref _internalId); - var ack = _ackHandler.CreateAck(id); - // Send Add/Remove Group to other servers and wait for an ack or timeout - var message = _protocol.WriteGroupCommand(new RedisGroupCommand(id, _serverName, action, groupName, connectionId)); - await PublishAsync(_channels.GroupManagement, message); - - await ack; - } - - private Task RemoveUserAsync(HubConnectionContext connection) - { - var userChannel = _channels.User(connection.UserIdentifier); - - return _users.RemoveSubscriptionAsync(userChannel, connection, channelName => - { - RedisLog.Unsubscribe(_logger, channelName); - return _bus.UnsubscribeAsync(channelName); - }); - } - - public void Dispose() - { - _bus?.UnsubscribeAll(); - _redisServerConnection?.Dispose(); - _ackHandler.Dispose(); - } - - private Task SubscribeToAll() - { - RedisLog.Subscribing(_logger, _channels.All); - return _bus.SubscribeAsync(_channels.All, async (c, data) => - { - try - { - RedisLog.ReceivedFromChannel(_logger, _channels.All); - - var invocation = _protocol.ReadInvocation((byte[])data); - - var tasks = new List(_connections.Count); - - foreach (var connection in _connections) - { - if (invocation.ExcludedConnectionIds == null || !invocation.ExcludedConnectionIds.Contains(connection.ConnectionId)) - { - tasks.Add(connection.WriteAsync(invocation.Message).AsTask()); - } - } - - await Task.WhenAll(tasks); - } - catch (Exception ex) - { - RedisLog.FailedWritingMessage(_logger, ex); - } - }); - } - - private Task SubscribeToGroupManagementChannel() - { - return _bus.SubscribeAsync(_channels.GroupManagement, async (c, data) => - { - try - { - var groupMessage = _protocol.ReadGroupCommand((byte[])data); - - var connection = _connections[groupMessage.ConnectionId]; - if (connection == null) - { - // user not on this server - return; - } - - if (groupMessage.Action == GroupAction.Remove) - { - await RemoveGroupAsyncCore(connection, groupMessage.GroupName); - } - - if (groupMessage.Action == GroupAction.Add) - { - await AddGroupAsyncCore(connection, groupMessage.GroupName); - } - - // Send an ack to the server that sent the original command. - await PublishAsync(_channels.Ack(groupMessage.ServerName), _protocol.WriteAck(groupMessage.Id)); - } - catch (Exception ex) - { - RedisLog.InternalMessageFailed(_logger, ex); - } - }); - } - - private Task SubscribeToAckChannel() - { - // Create server specific channel in order to send an ack to a single server - return _bus.SubscribeAsync(_channels.Ack(_serverName), (c, data) => - { - var ackId = _protocol.ReadAck((byte[])data); - - _ackHandler.TriggerAck(ackId); - }); - } - - private Task SubscribeToConnection(HubConnectionContext connection) - { - var connectionChannel = _channels.Connection(connection.ConnectionId); - - RedisLog.Subscribing(_logger, connectionChannel); - return _bus.SubscribeAsync(connectionChannel, async (c, data) => - { - var invocation = _protocol.ReadInvocation((byte[])data); - await connection.WriteAsync(invocation.Message); - }); - } - - private Task SubscribeToUser(HubConnectionContext connection) - { - var userChannel = _channels.User(connection.UserIdentifier); - - return _users.AddSubscriptionAsync(userChannel, connection, (channelName, subscriptions) => - { - RedisLog.Subscribing(_logger, channelName); - return _bus.SubscribeAsync(channelName, async (c, data) => - { - try - { - var invocation = _protocol.ReadInvocation((byte[])data); - - var tasks = new List(); - foreach (var userConnection in subscriptions) - { - tasks.Add(userConnection.WriteAsync(invocation.Message).AsTask()); - } - - await Task.WhenAll(tasks); - } - catch (Exception ex) - { - RedisLog.FailedWritingMessage(_logger, ex); - } - }); - }); - } - - private Task SubscribeToGroupAsync(string groupChannel, HubConnectionStore groupConnections) - { - RedisLog.Subscribing(_logger, groupChannel); - return _bus.SubscribeAsync(groupChannel, async (c, data) => - { - try - { - var invocation = _protocol.ReadInvocation((byte[])data); - - var tasks = new List(); - foreach (var groupConnection in groupConnections) - { - if (invocation.ExcludedConnectionIds?.Contains(groupConnection.ConnectionId) == true) - { - continue; - } - - tasks.Add(groupConnection.WriteAsync(invocation.Message).AsTask()); - } - - await Task.WhenAll(tasks); - } - catch (Exception ex) - { - RedisLog.FailedWritingMessage(_logger, ex); - } - }); - } - - private async Task EnsureRedisServerConnection() - { - if (_redisServerConnection == null) - { - await _connectionLock.WaitAsync(); - try - { - if (_redisServerConnection == null) - { - var writer = new LoggerTextWriter(_logger); - _redisServerConnection = await _options.ConnectAsync(writer); - _bus = _redisServerConnection.GetSubscriber(); - - _redisServerConnection.ConnectionRestored += (_, e) => - { - // We use the subscription connection type - // Ignore messages from the interactive connection (avoids duplicates) - if (e.ConnectionType == ConnectionType.Interactive) - { - return; - } - - RedisLog.ConnectionRestored(_logger); - }; - - _redisServerConnection.ConnectionFailed += (_, e) => - { - // We use the subscription connection type - // Ignore messages from the interactive connection (avoids duplicates) - if (e.ConnectionType == ConnectionType.Interactive) - { - return; - } - - RedisLog.ConnectionFailed(_logger, e.Exception); - }; - - if (_redisServerConnection.IsConnected) - { - RedisLog.Connected(_logger); - } - else - { - RedisLog.NotConnected(_logger); - } - - await SubscribeToAll(); - await SubscribeToGroupManagementChannel(); - await SubscribeToAckChannel(); - } - } - finally - { - _connectionLock.Release(); - } - } - } - - private static string GenerateServerName() - { - // Use the machine name for convenient diagnostics, but add a guid to make it unique. - // Example: MyServerName_02db60e5fab243b890a847fa5c4dcb29 - return $"{Environment.MachineName}_{Guid.NewGuid():N}"; - } - - private class LoggerTextWriter : TextWriter - { - private readonly ILogger _logger; - - public LoggerTextWriter(ILogger logger) - { - _logger = logger; - } - - public override Encoding Encoding => Encoding.UTF8; - - public override void Write(char value) - { - - } - - public override void WriteLine(string value) - { - RedisLog.ConnectionMultiplexerMessage(_logger, value); - } - } - - private interface IRedisFeature - { - HashSet Groups { get; } - } - - private class RedisFeature : IRedisFeature - { - public HashSet Groups { get; } = new HashSet(StringComparer.OrdinalIgnoreCase); - } - } -} diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/RedisOptions.cs b/src/Microsoft.AspNetCore.SignalR.Redis/RedisOptions.cs deleted file mode 100644 index 17d5890cf8..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/RedisOptions.cs +++ /dev/null @@ -1,50 +0,0 @@ -// 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; -using System.IO; -using System.Net; -using System.Threading.Tasks; -using StackExchange.Redis; - -namespace Microsoft.AspNetCore.SignalR.Redis -{ - /// - /// Options used to configure . - /// - public class RedisOptions - { - /// - /// Gets or sets configuration options exposed by StackExchange.Redis. - /// - public ConfigurationOptions Configuration { get; set; } = new ConfigurationOptions - { - // Enable reconnecting by default - AbortOnConnectFail = false - }; - - /// - /// Gets or sets the Redis connection factory. - /// - public Func> ConnectionFactory { get; set; } - - internal async Task ConnectAsync(TextWriter log) - { - // Factory is publically settable. Assigning to a local variable before null check for thread safety. - var factory = ConnectionFactory; - if (factory == null) - { - // REVIEW: Should we do this? - if (Configuration.EndPoints.Count == 0) - { - Configuration.EndPoints.Add(IPAddress.Loopback, 0); - Configuration.SetDefaultPorts(); - } - - return await ConnectionMultiplexer.ConnectAsync(Configuration, log); - } - - return await factory(log); - } - } -} diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/baseline.netcore.json b/src/Microsoft.AspNetCore.SignalR.Redis/baseline.netcore.json deleted file mode 100644 index 48c2646d0e..0000000000 --- a/src/Microsoft.AspNetCore.SignalR.Redis/baseline.netcore.json +++ /dev/null @@ -1,532 +0,0 @@ -{ - "AssemblyIdentity": "Microsoft.AspNetCore.SignalR.Redis, Version=1.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60", - "Types": [ - { - "Name": "Microsoft.Extensions.DependencyInjection.RedisDependencyInjectionExtensions", - "Visibility": "Public", - "Kind": "Class", - "Abstract": true, - "Static": true, - "Sealed": true, - "ImplementedInterfaces": [], - "Members": [ - { - "Kind": "Method", - "Name": "AddRedis", - "Parameters": [ - { - "Name": "signalrBuilder", - "Type": "Microsoft.AspNetCore.SignalR.ISignalRServerBuilder" - } - ], - "ReturnType": "Microsoft.AspNetCore.SignalR.ISignalRServerBuilder", - "Static": true, - "Extension": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "AddRedis", - "Parameters": [ - { - "Name": "signalrBuilder", - "Type": "Microsoft.AspNetCore.SignalR.ISignalRServerBuilder" - }, - { - "Name": "redisConnectionString", - "Type": "System.String" - } - ], - "ReturnType": "Microsoft.AspNetCore.SignalR.ISignalRServerBuilder", - "Static": true, - "Extension": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "AddRedis", - "Parameters": [ - { - "Name": "signalrBuilder", - "Type": "Microsoft.AspNetCore.SignalR.ISignalRServerBuilder" - }, - { - "Name": "configure", - "Type": "System.Action" - } - ], - "ReturnType": "Microsoft.AspNetCore.SignalR.ISignalRServerBuilder", - "Static": true, - "Extension": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "AddRedis", - "Parameters": [ - { - "Name": "signalrBuilder", - "Type": "Microsoft.AspNetCore.SignalR.ISignalRServerBuilder" - }, - { - "Name": "redisConnectionString", - "Type": "System.String" - }, - { - "Name": "configure", - "Type": "System.Action" - } - ], - "ReturnType": "Microsoft.AspNetCore.SignalR.ISignalRServerBuilder", - "Static": true, - "Extension": true, - "Visibility": "Public", - "GenericParameter": [] - } - ], - "GenericParameters": [] - }, - { - "Name": "Microsoft.AspNetCore.SignalR.Redis.RedisHubLifetimeManager", - "Visibility": "Public", - "Kind": "Class", - "BaseType": "Microsoft.AspNetCore.SignalR.HubLifetimeManager", - "ImplementedInterfaces": [ - "System.IDisposable" - ], - "Members": [ - { - "Kind": "Method", - "Name": "OnConnectedAsync", - "Parameters": [ - { - "Name": "connection", - "Type": "Microsoft.AspNetCore.SignalR.HubConnectionContext" - } - ], - "ReturnType": "System.Threading.Tasks.Task", - "Virtual": true, - "Override": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "OnDisconnectedAsync", - "Parameters": [ - { - "Name": "connection", - "Type": "Microsoft.AspNetCore.SignalR.HubConnectionContext" - } - ], - "ReturnType": "System.Threading.Tasks.Task", - "Virtual": true, - "Override": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "SendAllAsync", - "Parameters": [ - { - "Name": "methodName", - "Type": "System.String" - }, - { - "Name": "args", - "Type": "System.Object[]" - }, - { - "Name": "cancellationToken", - "Type": "System.Threading.CancellationToken", - "DefaultValue": "default(System.Threading.CancellationToken)" - } - ], - "ReturnType": "System.Threading.Tasks.Task", - "Virtual": true, - "Override": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "SendAllExceptAsync", - "Parameters": [ - { - "Name": "methodName", - "Type": "System.String" - }, - { - "Name": "args", - "Type": "System.Object[]" - }, - { - "Name": "excludedConnectionIds", - "Type": "System.Collections.Generic.IReadOnlyList" - }, - { - "Name": "cancellationToken", - "Type": "System.Threading.CancellationToken", - "DefaultValue": "default(System.Threading.CancellationToken)" - } - ], - "ReturnType": "System.Threading.Tasks.Task", - "Virtual": true, - "Override": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "SendConnectionAsync", - "Parameters": [ - { - "Name": "connectionId", - "Type": "System.String" - }, - { - "Name": "methodName", - "Type": "System.String" - }, - { - "Name": "args", - "Type": "System.Object[]" - }, - { - "Name": "cancellationToken", - "Type": "System.Threading.CancellationToken", - "DefaultValue": "default(System.Threading.CancellationToken)" - } - ], - "ReturnType": "System.Threading.Tasks.Task", - "Virtual": true, - "Override": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "SendGroupAsync", - "Parameters": [ - { - "Name": "groupName", - "Type": "System.String" - }, - { - "Name": "methodName", - "Type": "System.String" - }, - { - "Name": "args", - "Type": "System.Object[]" - }, - { - "Name": "cancellationToken", - "Type": "System.Threading.CancellationToken", - "DefaultValue": "default(System.Threading.CancellationToken)" - } - ], - "ReturnType": "System.Threading.Tasks.Task", - "Virtual": true, - "Override": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "SendGroupExceptAsync", - "Parameters": [ - { - "Name": "groupName", - "Type": "System.String" - }, - { - "Name": "methodName", - "Type": "System.String" - }, - { - "Name": "args", - "Type": "System.Object[]" - }, - { - "Name": "excludedConnectionIds", - "Type": "System.Collections.Generic.IReadOnlyList" - }, - { - "Name": "cancellationToken", - "Type": "System.Threading.CancellationToken", - "DefaultValue": "default(System.Threading.CancellationToken)" - } - ], - "ReturnType": "System.Threading.Tasks.Task", - "Virtual": true, - "Override": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "SendUserAsync", - "Parameters": [ - { - "Name": "userId", - "Type": "System.String" - }, - { - "Name": "methodName", - "Type": "System.String" - }, - { - "Name": "args", - "Type": "System.Object[]" - }, - { - "Name": "cancellationToken", - "Type": "System.Threading.CancellationToken", - "DefaultValue": "default(System.Threading.CancellationToken)" - } - ], - "ReturnType": "System.Threading.Tasks.Task", - "Virtual": true, - "Override": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "AddToGroupAsync", - "Parameters": [ - { - "Name": "connectionId", - "Type": "System.String" - }, - { - "Name": "groupName", - "Type": "System.String" - }, - { - "Name": "cancellationToken", - "Type": "System.Threading.CancellationToken", - "DefaultValue": "default(System.Threading.CancellationToken)" - } - ], - "ReturnType": "System.Threading.Tasks.Task", - "Virtual": true, - "Override": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "RemoveFromGroupAsync", - "Parameters": [ - { - "Name": "connectionId", - "Type": "System.String" - }, - { - "Name": "groupName", - "Type": "System.String" - }, - { - "Name": "cancellationToken", - "Type": "System.Threading.CancellationToken", - "DefaultValue": "default(System.Threading.CancellationToken)" - } - ], - "ReturnType": "System.Threading.Tasks.Task", - "Virtual": true, - "Override": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "SendConnectionsAsync", - "Parameters": [ - { - "Name": "connectionIds", - "Type": "System.Collections.Generic.IReadOnlyList" - }, - { - "Name": "methodName", - "Type": "System.String" - }, - { - "Name": "args", - "Type": "System.Object[]" - }, - { - "Name": "cancellationToken", - "Type": "System.Threading.CancellationToken", - "DefaultValue": "default(System.Threading.CancellationToken)" - } - ], - "ReturnType": "System.Threading.Tasks.Task", - "Virtual": true, - "Override": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "SendGroupsAsync", - "Parameters": [ - { - "Name": "groupNames", - "Type": "System.Collections.Generic.IReadOnlyList" - }, - { - "Name": "methodName", - "Type": "System.String" - }, - { - "Name": "args", - "Type": "System.Object[]" - }, - { - "Name": "cancellationToken", - "Type": "System.Threading.CancellationToken", - "DefaultValue": "default(System.Threading.CancellationToken)" - } - ], - "ReturnType": "System.Threading.Tasks.Task", - "Virtual": true, - "Override": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "SendUsersAsync", - "Parameters": [ - { - "Name": "userIds", - "Type": "System.Collections.Generic.IReadOnlyList" - }, - { - "Name": "methodName", - "Type": "System.String" - }, - { - "Name": "args", - "Type": "System.Object[]" - }, - { - "Name": "cancellationToken", - "Type": "System.Threading.CancellationToken", - "DefaultValue": "default(System.Threading.CancellationToken)" - } - ], - "ReturnType": "System.Threading.Tasks.Task", - "Virtual": true, - "Override": true, - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "Dispose", - "Parameters": [], - "ReturnType": "System.Void", - "Sealed": true, - "Virtual": true, - "ImplementedInterface": "System.IDisposable", - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Constructor", - "Name": ".ctor", - "Parameters": [ - { - "Name": "logger", - "Type": "Microsoft.Extensions.Logging.ILogger>" - }, - { - "Name": "options", - "Type": "Microsoft.Extensions.Options.IOptions" - }, - { - "Name": "hubProtocolResolver", - "Type": "Microsoft.AspNetCore.SignalR.IHubProtocolResolver" - } - ], - "Visibility": "Public", - "GenericParameter": [] - } - ], - "GenericParameters": [ - { - "ParameterName": "THub", - "ParameterPosition": 0, - "BaseTypeOrInterfaces": [ - "Microsoft.AspNetCore.SignalR.Hub" - ] - } - ] - }, - { - "Name": "Microsoft.AspNetCore.SignalR.Redis.RedisOptions", - "Visibility": "Public", - "Kind": "Class", - "ImplementedInterfaces": [], - "Members": [ - { - "Kind": "Method", - "Name": "get_Configuration", - "Parameters": [], - "ReturnType": "StackExchange.Redis.ConfigurationOptions", - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "set_Configuration", - "Parameters": [ - { - "Name": "value", - "Type": "StackExchange.Redis.ConfigurationOptions" - } - ], - "ReturnType": "System.Void", - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "get_ConnectionFactory", - "Parameters": [], - "ReturnType": "System.Func>", - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Method", - "Name": "set_ConnectionFactory", - "Parameters": [ - { - "Name": "value", - "Type": "System.Func>" - } - ], - "ReturnType": "System.Void", - "Visibility": "Public", - "GenericParameter": [] - }, - { - "Kind": "Constructor", - "Name": ".ctor", - "Parameters": [], - "Visibility": "Public", - "GenericParameter": [] - } - ], - "GenericParameters": [] - } - ] -} \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Docker.cs b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Docker.cs deleted file mode 100644 index 10f087ac6a..0000000000 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Docker.cs +++ /dev/null @@ -1,192 +0,0 @@ -// 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; -using System.Collections.Concurrent; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; - -namespace Microsoft.AspNetCore.SignalR.Redis.Tests -{ - public class Docker - { - private static readonly string _exeSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty; - - private static readonly string _dockerContainerName = "redisTestContainer-1x"; - private static readonly string _dockerMonitorContainerName = _dockerContainerName + "Monitor-1x"; - private static readonly Lazy _instance = new Lazy(Create); - - public static Docker Default => _instance.Value; - - private readonly string _path; - - public Docker(string path) - { - _path = path; - } - - private static Docker Create() - { - var location = GetDockerLocation(); - if (location == null) - { - return null; - } - - var docker = new Docker(location); - - docker.RunCommand("info --format '{{.OSType}}'", "docker info", out var output); - - if (!string.Equals(output.Trim('\'', '"', '\r', '\n', ' '), "linux")) - { - Console.WriteLine($"'docker info' output: {output}"); - return null; - } - - return docker; - } - - private static string GetDockerLocation() - { - // OSX + Docker + Redis don't play well together for some reason. We already have these tests covered on Linux and Windows - // So we are happy ignoring them on OSX - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - return null; - } - - foreach (var dir in Environment.GetEnvironmentVariable("PATH").Split(Path.PathSeparator)) - { - var candidate = Path.Combine(dir, "docker" + _exeSuffix); - if (File.Exists(candidate)) - { - return candidate; - } - } - - return null; - } - - public void Start(ILogger logger) - { - logger.LogInformation("Starting docker container"); - - // stop container if there is one, could be from a previous test run, ignore failures - RunProcessAndWait(_path, $"stop {_dockerMonitorContainerName}", "docker stop", logger, TimeSpan.FromSeconds(15), out var _); - RunProcessAndWait(_path, $"stop {_dockerContainerName}", "docker stop", logger, TimeSpan.FromSeconds(15), out var output); - - // create and run docker container, remove automatically when stopped, map 6379 from the container to 6379 localhost - // use static name 'redisTestContainer' so if the container doesn't get removed we don't keep adding more - // use redis base docker image - // 20 second timeout to allow redis image to be downloaded, should be a rare occurrence, only happening when a new version is released - RunProcessAndThrowIfFailed(_path, $"run --rm -p 6380:6379 --name {_dockerContainerName} -d redis", "redis", logger, TimeSpan.FromSeconds(20)); - - // inspect the redis docker image and extract the IPAddress. Necessary when running tests from inside a docker container, spinning up a new docker container for redis - // outside the current container requires linking the networks (difficult to automate) or using the IP:Port combo - RunProcessAndWait(_path, "inspect --format=\"{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}\" " + _dockerContainerName, "docker ipaddress", logger, TimeSpan.FromSeconds(5), out output); - output = output.Trim().Replace(Environment.NewLine, ""); - - // variable used by Startup.cs - Environment.SetEnvironmentVariable("REDIS_CONNECTION-PREV", $"{output}:6379"); - - var (monitorProcess, monitorOutput) = RunProcess(_path, $"run -i --name {_dockerMonitorContainerName} --link {_dockerContainerName}:redis --rm redis redis-cli -h redis -p 6379", "redis monitor", logger); - monitorProcess.StandardInput.WriteLine("MONITOR"); - monitorProcess.StandardInput.Flush(); - } - - public void Stop(ILogger logger) - { - // Get logs from Redis container before stopping the container - RunProcessAndThrowIfFailed(_path, $"logs {_dockerContainerName}", "docker logs", logger, TimeSpan.FromSeconds(5)); - - logger.LogInformation("Stopping docker container"); - RunProcessAndWait(_path, $"stop {_dockerMonitorContainerName}", "docker stop", logger, TimeSpan.FromSeconds(15), out var _); - RunProcessAndWait(_path, $"stop {_dockerContainerName}", "docker stop", logger, TimeSpan.FromSeconds(15), out var _); - } - - public int RunCommand(string commandAndArguments, string prefix, out string output) => - RunCommand(commandAndArguments, prefix, NullLogger.Instance, out output); - - public int RunCommand(string commandAndArguments, string prefix, ILogger logger, out string output) - { - return RunProcessAndWait(_path, commandAndArguments, prefix, logger, TimeSpan.FromSeconds(5), out output); - } - - private static void RunProcessAndThrowIfFailed(string fileName, string arguments, string prefix, ILogger logger, TimeSpan timeout) - { - var exitCode = RunProcessAndWait(fileName, arguments, prefix, logger, timeout, out var output); - - if (exitCode != 0) - { - throw new Exception($"Command '{fileName} {arguments}' failed with exit code '{exitCode}'. Output:{Environment.NewLine}{output}"); - } - } - - private static int RunProcessAndWait(string fileName, string arguments, string prefix, ILogger logger, TimeSpan timeout, out string output) - { - var (process, lines) = RunProcess(fileName, arguments, prefix, logger); - - if (!process.WaitForExit((int)timeout.TotalMilliseconds)) - { - process.Close(); - logger.LogError("Closing process '{processName}' because it is running longer than the configured timeout.", fileName); - } - - // Need to WaitForExit without a timeout to guarantee the output stream has written everything - process.WaitForExit(); - - output = string.Join(Environment.NewLine, lines); - - return process.ExitCode; - } - - private static (Process, ConcurrentQueue) RunProcess(string fileName, string arguments, string prefix, ILogger logger) - { - var process = new Process - { - StartInfo = new ProcessStartInfo - { - FileName = fileName, - Arguments = arguments, - UseShellExecute = false, - RedirectStandardError = true, - RedirectStandardOutput = true, - RedirectStandardInput = true - }, - EnableRaisingEvents = true - }; - - var exitCode = 0; - var lines = new ConcurrentQueue(); - process.Exited += (_, __) => exitCode = process.ExitCode; - process.OutputDataReceived += (_, a) => - { - LogIfNotNull(logger.LogInformation, $"'{prefix}' stdout: {{0}}", a.Data); - lines.Enqueue(a.Data); - }; - process.ErrorDataReceived += (_, a) => - { - LogIfNotNull(logger.LogError, $"'{prefix}' stderr: {{0}}", a.Data); - lines.Enqueue(a.Data); - }; - - process.Start(); - - process.BeginErrorReadLine(); - process.BeginOutputReadLine(); - - return (process, lines); - } - - private static void LogIfNotNull(Action logger, string message, string data) - { - if (!string.IsNullOrEmpty(data)) - { - logger(message, new[] { data }); - } - } - } -} diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/EchoHub.cs b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/EchoHub.cs deleted file mode 100644 index e7747b50d3..0000000000 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/EchoHub.cs +++ /dev/null @@ -1,31 +0,0 @@ -// 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; -using System.Threading.Tasks; - -namespace Microsoft.AspNetCore.SignalR.Redis.Tests -{ - public class EchoHub : Hub - { - public string Echo(string message) - { - return message; - } - - public Task EchoGroup(string groupName, string message) - { - return Clients.Group(groupName).SendAsync("Echo", message); - } - - public Task EchoUser(string userName, string message) - { - return Clients.User(userName).SendAsync("Echo", message); - } - - public Task AddSelfToGroup(string groupName) - { - return Groups.AddToGroupAsync(Context.ConnectionId, groupName); - } - } -} diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Microsoft.AspNetCore.SignalR.Redis.Tests.csproj b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Microsoft.AspNetCore.SignalR.Redis.Tests.csproj deleted file mode 100644 index 24d6cebb93..0000000000 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Microsoft.AspNetCore.SignalR.Redis.Tests.csproj +++ /dev/null @@ -1,27 +0,0 @@ - - - - $(StandardTestTfms) - - - - - PreserveNewest - - - - - - - - - - - - - - - - - - diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisDependencyInjectionExtensionsTests.cs b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisDependencyInjectionExtensionsTests.cs deleted file mode 100644 index 385bf345d9..0000000000 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisDependencyInjectionExtensionsTests.cs +++ /dev/null @@ -1,41 +0,0 @@ -// 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; -using System.Collections.Generic; -using System.Net; -using System.Text; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Xunit; - -namespace Microsoft.AspNetCore.SignalR.Redis.Tests -{ - public class RedisDependencyInjectionExtensionsTests - { - // No need to go too deep with these tests, or we're just testing StackExchange.Redis again :). It's the one doing the parsing. - [Theory] - [InlineData("testredis.example.com", "testredis.example.com", 0, null, false)] - [InlineData("testredis.example.com:6380,ssl=True", "testredis.example.com", 6380, null, true)] - [InlineData("testredis.example.com:6380,password=hunter2,ssl=True", "testredis.example.com", 6380, "hunter2", true)] - public void AddRedisWithConnectionStringProperlyParsesOptions(string connectionString, string host, int port, string password, bool useSsl) - { - var services = new ServiceCollection(); - services.AddSignalR().AddRedis(connectionString); - var provider = services.BuildServiceProvider(); - - var options = provider.GetService>(); - Assert.NotNull(options.Value); - Assert.NotNull(options.Value.Configuration); - Assert.Equal(password, options.Value.Configuration.Password); - Assert.Collection(options.Value.Configuration.EndPoints, - endpoint => - { - var dnsEndpoint = Assert.IsType(endpoint); - Assert.Equal(host, dnsEndpoint.Host); - Assert.Equal(port, dnsEndpoint.Port); - }); - Assert.Equal(useSsl, options.Value.Configuration.Ssl); - } - } -} diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisEndToEnd.cs b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisEndToEnd.cs deleted file mode 100644 index 2c239b3e67..0000000000 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisEndToEnd.cs +++ /dev/null @@ -1,198 +0,0 @@ -// 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; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http.Connections; -using Microsoft.AspNetCore.SignalR.Client; -using Microsoft.AspNetCore.SignalR.Protocol; -using Microsoft.AspNetCore.SignalR.Tests; -using Microsoft.AspNetCore.Testing.xunit; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Xunit; -using Xunit.Abstractions; - -namespace Microsoft.AspNetCore.SignalR.Redis.Tests -{ - // Disable running server tests in parallel so server logs can accurately be captured per test - [CollectionDefinition(Name, DisableParallelization = true)] - public class RedisEndToEndTestsCollection : ICollectionFixture> - { - public const string Name = nameof(RedisEndToEndTestsCollection); - } - - [Collection(RedisEndToEndTestsCollection.Name)] - public class RedisEndToEndTests : VerifiableLoggedTest - { - private readonly RedisServerFixture _serverFixture; - - public RedisEndToEndTests(RedisServerFixture serverFixture, ITestOutputHelper output) : base(output) - { - if (serverFixture == null) - { - throw new ArgumentNullException(nameof(serverFixture)); - } - - _serverFixture = serverFixture; - } - - [ConditionalTheory] - [SkipIfDockerNotPresent] - [MemberData(nameof(TransportTypesAndProtocolTypes))] - public async Task HubConnectionCanSendAndReceiveMessages(HttpTransportType transportType, string protocolName) - { - using (StartVerifiableLog(out var loggerFactory, testName: - $"{nameof(HubConnectionCanSendAndReceiveMessages)}_{transportType.ToString()}_{protocolName}")) - { - var protocol = HubProtocolHelpers.GetHubProtocol(protocolName); - - var connection = CreateConnection(_serverFixture.FirstServer.Url + "/echo", transportType, protocol, loggerFactory); - - await connection.StartAsync().OrTimeout(); - var str = await connection.InvokeAsync("Echo", "Hello, World!").OrTimeout(); - - Assert.Equal("Hello, World!", str); - - await connection.DisposeAsync().OrTimeout(); - } - } - - [ConditionalTheory] - [SkipIfDockerNotPresent] - [MemberData(nameof(TransportTypesAndProtocolTypes))] - public async Task HubConnectionCanSendAndReceiveGroupMessages(HttpTransportType transportType, string protocolName) - { - using (StartVerifiableLog(out var loggerFactory, testName: - $"{nameof(HubConnectionCanSendAndReceiveGroupMessages)}_{transportType.ToString()}_{protocolName}")) - { - var protocol = HubProtocolHelpers.GetHubProtocol(protocolName); - - var connection = CreateConnection(_serverFixture.FirstServer.Url + "/echo", transportType, protocol, loggerFactory); - var secondConnection = CreateConnection(_serverFixture.SecondServer.Url + "/echo", transportType, protocol, loggerFactory); - - var tcs = new TaskCompletionSource(); - connection.On("Echo", message => tcs.TrySetResult(message)); - var tcs2 = new TaskCompletionSource(); - secondConnection.On("Echo", message => tcs2.TrySetResult(message)); - - var groupName = $"TestGroup_{transportType}_{protocolName}_{Guid.NewGuid()}"; - - await secondConnection.StartAsync().OrTimeout(); - await connection.StartAsync().OrTimeout(); - await connection.InvokeAsync("AddSelfToGroup", groupName).OrTimeout(); - await secondConnection.InvokeAsync("AddSelfToGroup", groupName).OrTimeout(); - await connection.InvokeAsync("EchoGroup", groupName, "Hello, World!").OrTimeout(); - - Assert.Equal("Hello, World!", await tcs.Task.OrTimeout()); - Assert.Equal("Hello, World!", await tcs2.Task.OrTimeout()); - - await connection.DisposeAsync().OrTimeout(); - } - } - - [ConditionalTheory] - [SkipIfDockerNotPresent] - [MemberData(nameof(TransportTypesAndProtocolTypes))] - public async Task CanSendAndReceiveUserMessagesFromMultipleConnectionsWithSameUser(HttpTransportType transportType, string protocolName) - { - using (StartVerifiableLog(out var loggerFactory, testName: - $"{nameof(CanSendAndReceiveUserMessagesFromMultipleConnectionsWithSameUser)}_{transportType.ToString()}_{protocolName}")) - { - var protocol = HubProtocolHelpers.GetHubProtocol(protocolName); - - var connection = CreateConnection(_serverFixture.FirstServer.Url + "/echo", transportType, protocol, loggerFactory, userName: "userA"); - var secondConnection = CreateConnection(_serverFixture.SecondServer.Url + "/echo", transportType, protocol, loggerFactory, userName: "userA"); - - var tcs = new TaskCompletionSource(); - connection.On("Echo", message => tcs.TrySetResult(message)); - var tcs2 = new TaskCompletionSource(); - secondConnection.On("Echo", message => tcs2.TrySetResult(message)); - - await secondConnection.StartAsync().OrTimeout(); - await connection.StartAsync().OrTimeout(); - await connection.InvokeAsync("EchoUser", "userA", "Hello, World!").OrTimeout(); - - Assert.Equal("Hello, World!", await tcs.Task.OrTimeout()); - Assert.Equal("Hello, World!", await tcs2.Task.OrTimeout()); - - await connection.DisposeAsync().OrTimeout(); - await secondConnection.DisposeAsync().OrTimeout(); - } - } - - [ConditionalTheory] - [SkipIfDockerNotPresent] - [MemberData(nameof(TransportTypesAndProtocolTypes))] - public async Task CanSendAndReceiveUserMessagesWhenOneConnectionWithUserDisconnects(HttpTransportType transportType, string protocolName) - { - // Regression test: - // When multiple connections from the same user were connected and one left, it used to unsubscribe from the user channel - // Now we keep track of users connections and only unsubscribe when no users are listening - using (StartVerifiableLog(out var loggerFactory, testName: - $"{nameof(CanSendAndReceiveUserMessagesWhenOneConnectionWithUserDisconnects)}_{transportType.ToString()}_{protocolName}")) - { - var protocol = HubProtocolHelpers.GetHubProtocol(protocolName); - - var firstConnection = CreateConnection(_serverFixture.FirstServer.Url + "/echo", transportType, protocol, loggerFactory, userName: "userA"); - var secondConnection = CreateConnection(_serverFixture.SecondServer.Url + "/echo", transportType, protocol, loggerFactory, userName: "userA"); - - var tcs = new TaskCompletionSource(); - firstConnection.On("Echo", message => tcs.TrySetResult(message)); - - await secondConnection.StartAsync().OrTimeout(); - await firstConnection.StartAsync().OrTimeout(); - await secondConnection.DisposeAsync().OrTimeout(); - await firstConnection.InvokeAsync("EchoUser", "userA", "Hello, World!").OrTimeout(); - - Assert.Equal("Hello, World!", await tcs.Task.OrTimeout()); - - await firstConnection.DisposeAsync().OrTimeout(); - } - } - - private static HubConnection CreateConnection(string url, HttpTransportType transportType, IHubProtocol protocol, ILoggerFactory loggerFactory, string userName = null) - { - var hubConnectionBuilder = new HubConnectionBuilder() - .WithLoggerFactory(loggerFactory) - .WithUrl(url, transportType, httpConnectionOptions => - { - if (!string.IsNullOrEmpty(userName)) - { - httpConnectionOptions.Headers["UserName"] = userName; - } - }); - - hubConnectionBuilder.Services.AddSingleton(protocol); - - return hubConnectionBuilder.Build(); - } - - private static IEnumerable TransportTypes() - { - if (TestHelpers.IsWebSocketsSupported()) - { - yield return HttpTransportType.WebSockets; - } - yield return HttpTransportType.ServerSentEvents; - yield return HttpTransportType.LongPolling; - } - - public static IEnumerable TransportTypesAndProtocolTypes - { - get - { - foreach (var transport in TransportTypes()) - { - yield return new object[] { transport, "json" }; - - if (transport != HttpTransportType.ServerSentEvents) - { - yield return new object[] { transport, "messagepack" }; - } - } - } - } - } -} diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisHubLifetimeManagerTests.cs b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisHubLifetimeManagerTests.cs deleted file mode 100644 index 39dc6acb66..0000000000 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisHubLifetimeManagerTests.cs +++ /dev/null @@ -1,102 +0,0 @@ -// 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.Threading.Tasks; -using Microsoft.AspNetCore.SignalR.Internal; -using Microsoft.AspNetCore.SignalR.Protocol; -using Microsoft.AspNetCore.SignalR.Tests; -using Microsoft.Extensions.Logging.Abstractions; -using Microsoft.Extensions.Options; -using Microsoft.AspNetCore.SignalR.Specification.Tests; -using Newtonsoft.Json.Linq; -using Newtonsoft.Json.Serialization; -using Xunit; - -namespace Microsoft.AspNetCore.SignalR.Redis.Tests -{ - public class RedisHubLifetimeManagerTests : ScaleoutHubLifetimeManagerTests - { - private TestRedisServer _server; - - public override HubLifetimeManager CreateNewHubLifetimeManager(TestRedisServer backplane) - { - return CreateLifetimeManager(backplane); - } - - public override TestRedisServer CreateBackplane() - { - return new TestRedisServer(); - } - - public override HubLifetimeManager CreateNewHubLifetimeManager() - { - _server = new TestRedisServer(); - - return CreateLifetimeManager(_server); - } - - public class TestObject - { - public string TestProperty { get; set; } - } - - private RedisHubLifetimeManager CreateLifetimeManager(TestRedisServer server, MessagePackHubProtocolOptions messagePackOptions = null, JsonHubProtocolOptions jsonOptions = null) - { - var options = new RedisOptions() { ConnectionFactory = async (t) => await Task.FromResult(new TestConnectionMultiplexer(server)) }; - messagePackOptions = messagePackOptions ?? new MessagePackHubProtocolOptions(); - jsonOptions = jsonOptions ?? new JsonHubProtocolOptions(); - return new RedisHubLifetimeManager( - NullLogger>.Instance, - Options.Create(options), - new DefaultHubProtocolResolver(new IHubProtocol[] - { - new JsonHubProtocol(Options.Create(jsonOptions)), - new MessagePackHubProtocol(Options.Create(messagePackOptions)), - }, NullLogger.Instance)); - } - - [Fact] - public async Task CamelCasedJsonIsPreservedAcrossRedisBoundary() - { - var server = new TestRedisServer(); - - var messagePackOptions = new MessagePackHubProtocolOptions(); - - var jsonOptions = new JsonHubProtocolOptions(); - jsonOptions.PayloadSerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); - - using (var client1 = new TestClient()) - using (var client2 = new TestClient()) - { - // The sending manager has serializer settings - var manager1 = CreateLifetimeManager(server, messagePackOptions, jsonOptions); - - // The receiving one doesn't matter because of how we serialize! - var manager2 = CreateLifetimeManager(server); - - var connection1 = HubConnectionContextUtils.Create(client1.Connection); - var connection2 = HubConnectionContextUtils.Create(client2.Connection); - - await manager1.OnConnectedAsync(connection1).OrTimeout(); - await manager2.OnConnectedAsync(connection2).OrTimeout(); - - await manager1.SendAllAsync("Hello", new object[] { new TestObject { TestProperty = "Foo" } }); - - var message = Assert.IsType(await client2.ReadAsync().OrTimeout()); - Assert.Equal("Hello", message.Target); - Assert.Collection( - message.Arguments, - arg0 => - { - var dict = Assert.IsType(arg0); - Assert.Collection(dict.Properties(), - prop => - { - Assert.Equal("testProperty", prop.Name); - Assert.Equal("Foo", prop.Value.Value()); - }); - }); - } - } - } -} diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisProtocolTests.cs b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisProtocolTests.cs deleted file mode 100644 index 89b960df71..0000000000 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisProtocolTests.cs +++ /dev/null @@ -1,202 +0,0 @@ -// 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; -using System.Buffers; -using System.Collections.Generic; -using System.Linq; -using Microsoft.AspNetCore.Connections; -using Microsoft.AspNetCore.SignalR.Internal; -using Microsoft.AspNetCore.SignalR.Protocol; -using Microsoft.AspNetCore.SignalR.Redis.Internal; -using Microsoft.AspNetCore.SignalR.Tests; -using Xunit; - -namespace Microsoft.AspNetCore.SignalR.Redis.Tests -{ - public class RedisProtocolTests - { - private static Dictionary> _ackTestData = new[] - { - CreateTestData("Zero", 0, 0x91, 0x00), - CreateTestData("Fixnum", 42, 0x91, 0x2A), - CreateTestData("Uint8", 180, 0x91, 0xCC, 0xB4), - CreateTestData("Uint16", 384, 0x91, 0xCD, 0x01, 0x80), - CreateTestData("Uint32", 70_000, 0x91, 0xCE, 0x00, 0x01, 0x11, 0x70), - }.ToDictionary(t => t.Name); - - public static IEnumerable AckTestData = _ackTestData.Keys.Select(k => new object[] { k }); - - [Theory] - [MemberData(nameof(AckTestData))] - public void ParseAck(string testName) - { - var testData = _ackTestData[testName]; - var protocol = new RedisProtocol(Array.Empty()); - - var decoded = protocol.ReadAck(testData.Encoded); - - Assert.Equal(testData.Decoded, decoded); - } - - [Theory] - [MemberData(nameof(AckTestData))] - public void WriteAck(string testName) - { - var testData = _ackTestData[testName]; - var protocol = new RedisProtocol(Array.Empty()); - - var encoded = protocol.WriteAck(testData.Decoded); - - Assert.Equal(testData.Encoded, encoded); - } - - private static Dictionary> _groupCommandTestData = new[] - { - CreateTestData("GroupAdd", new RedisGroupCommand(42, "S", GroupAction.Add, "G", "C" ), 0x95, 0x2A, 0xA1, (byte)'S', 0x01, 0xA1, (byte)'G', 0xA1, (byte)'C'), - CreateTestData("GroupRemove", new RedisGroupCommand(42, "S", GroupAction.Remove, "G", "C" ), 0x95, 0x2A, 0xA1, (byte)'S', 0x02, 0xA1, (byte)'G', 0xA1, (byte)'C'), - }.ToDictionary(t => t.Name); - - public static IEnumerable GroupCommandTestData = _groupCommandTestData.Keys.Select(k => new object[] { k }); - - [Theory] - [MemberData(nameof(GroupCommandTestData))] - public void ParseGroupCommand(string testName) - { - var testData = _groupCommandTestData[testName]; - var protocol = new RedisProtocol(Array.Empty()); - - var decoded = protocol.ReadGroupCommand(testData.Encoded); - - Assert.Equal(testData.Decoded.Id, decoded.Id); - Assert.Equal(testData.Decoded.ServerName, decoded.ServerName); - Assert.Equal(testData.Decoded.Action, decoded.Action); - Assert.Equal(testData.Decoded.GroupName, decoded.GroupName); - Assert.Equal(testData.Decoded.ConnectionId, decoded.ConnectionId); - } - - [Theory] - [MemberData(nameof(GroupCommandTestData))] - public void WriteGroupCommand(string testName) - { - var testData = _groupCommandTestData[testName]; - var protocol = new RedisProtocol(Array.Empty()); - - var encoded = protocol.WriteGroupCommand(testData.Decoded); - - Assert.Equal(testData.Encoded, encoded); - } - - // The actual invocation message doesn't matter - private static InvocationMessage _testMessage = new InvocationMessage("target", Array.Empty()); - - // We use a func so we are guaranteed to get a new SerializedHubMessage for each test - private static Dictionary>> _invocationTestData = new[] - { - CreateTestData>( - "NoExcludedIds", - () => new RedisInvocation(new SerializedHubMessage(_testMessage), null), - 0x92, - 0x90, - 0x82, - 0xA2, (byte)'p', (byte)'1', - 0xC4, 0x01, 0x2A, - 0xA2, (byte)'p', (byte)'2', - 0xC4, 0x01, 0x2A), - CreateTestData>( - "OneExcludedId", - () => new RedisInvocation(new SerializedHubMessage(_testMessage), new [] { "a" }), - 0x92, - 0x91, - 0xA1, (byte)'a', - 0x82, - 0xA2, (byte)'p', (byte)'1', - 0xC4, 0x01, 0x2A, - 0xA2, (byte)'p', (byte)'2', - 0xC4, 0x01, 0x2A), - CreateTestData>( - "ManyExcludedIds", - () => new RedisInvocation(new SerializedHubMessage(_testMessage), new [] { "a", "b", "c", "d", "e", "f" }), - 0x92, - 0x96, - 0xA1, (byte)'a', - 0xA1, (byte)'b', - 0xA1, (byte)'c', - 0xA1, (byte)'d', - 0xA1, (byte)'e', - 0xA1, (byte)'f', - 0x82, - 0xA2, (byte)'p', (byte)'1', - 0xC4, 0x01, 0x2A, - 0xA2, (byte)'p', (byte)'2', - 0xC4, 0x01, 0x2A), - }.ToDictionary(t => t.Name); - - public static IEnumerable InvocationTestData = _invocationTestData.Keys.Select(k => new object[] { k }); - - [Theory] - [MemberData(nameof(InvocationTestData))] - public void ParseInvocation(string testName) - { - var testData = _invocationTestData[testName]; - var hubProtocols = new[] { new DummyHubProtocol("p1"), new DummyHubProtocol("p2") }; - var protocol = new RedisProtocol(hubProtocols); - - var expected = testData.Decoded(); - - var decoded = protocol.ReadInvocation(testData.Encoded); - - Assert.Equal(expected.ExcludedConnectionIds, decoded.ExcludedConnectionIds); - - // Verify the deserialized object has the necessary serialized forms - foreach (var hubProtocol in hubProtocols) - { - Assert.Equal( - expected.Message.GetSerializedMessage(hubProtocol).ToArray(), - decoded.Message.GetSerializedMessage(hubProtocol).ToArray()); - - var writtenMessages = hubProtocol.GetWrittenMessages(); - Assert.Collection(writtenMessages, - actualMessage => - { - var invocation = Assert.IsType(actualMessage); - Assert.Same(_testMessage.Target, invocation.Target); - Assert.Same(_testMessage.Arguments, invocation.Arguments); - }); - } - } - - [Theory] - [MemberData(nameof(InvocationTestData))] - public void WriteInvocation(string testName) - { - var testData = _invocationTestData[testName]; - var protocol = new RedisProtocol(new[] { new DummyHubProtocol("p1"), new DummyHubProtocol("p2") }); - - // Actual invocation doesn't matter because we're using a dummy hub protocol. - // But the dummy protocol will check that we gave it the test message to make sure everything flows through properly. - var expected = testData.Decoded(); - var encoded = protocol.WriteInvocation(_testMessage.Target, _testMessage.Arguments, expected.ExcludedConnectionIds); - - Assert.Equal(testData.Encoded, encoded); - } - - // Create ProtocolTestData using the Power of Type Inference(TM). - private static ProtocolTestData CreateTestData(string name, T decoded, params byte[] encoded) - => new ProtocolTestData(name, decoded, encoded); - - public class ProtocolTestData - { - public string Name { get; } - public T Decoded { get; } - public byte[] Encoded { get; } - - public ProtocolTestData(string name, T decoded, byte[] encoded) - { - Name = name; - Decoded = decoded; - Encoded = encoded; - } - } - } -} diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisServerFixture.cs b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisServerFixture.cs deleted file mode 100644 index e2fab22665..0000000000 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/RedisServerFixture.cs +++ /dev/null @@ -1,64 +0,0 @@ -// 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; -using Microsoft.AspNetCore.SignalR.Tests; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Testing; - -namespace Microsoft.AspNetCore.SignalR.Redis.Tests -{ - public class RedisServerFixture : IDisposable - where TStartup : class - { - public ServerFixture FirstServer { get; private set; } - public ServerFixture SecondServer { get; private set; } - - private readonly ILogger _logger; - private readonly ILoggerFactory _loggerFactory; - private readonly IDisposable _logToken; - - public RedisServerFixture() - { - // Docker is not available on the machine, tests using this fixture - // should be using SkipIfDockerNotPresentAttribute and will be skipped. - if (Docker.Default == null) - { - return; - } - - var testLog = AssemblyTestLog.ForAssembly(typeof(RedisServerFixture).Assembly); - _logToken = testLog.StartTestLog(null, $"{nameof(RedisServerFixture)}_{typeof(TStartup).Name}", out _loggerFactory, LogLevel.Trace, "RedisServerFixture"); - _logger = _loggerFactory.CreateLogger>(); - - Docker.Default.Start(_logger); - - FirstServer = StartServer(); - SecondServer = StartServer(); - } - - private ServerFixture StartServer() - { - try - { - return new ServerFixture(_loggerFactory); - } - catch (Exception ex) - { - _logger.LogError(ex, "Server failed to start."); - throw; - } - } - - public void Dispose() - { - if (Docker.Default != null) - { - FirstServer.Dispose(); - SecondServer.Dispose(); - Docker.Default.Stop(_logger); - _logToken.Dispose(); - } - } - } -} diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/SkipIfDockerNotPresentAttribute.cs b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/SkipIfDockerNotPresentAttribute.cs deleted file mode 100644 index 6bdba837bd..0000000000 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/SkipIfDockerNotPresentAttribute.cs +++ /dev/null @@ -1,39 +0,0 @@ -// 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; -using Microsoft.AspNetCore.Testing.xunit; - -namespace Microsoft.AspNetCore.SignalR.Redis.Tests -{ - [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] - public class SkipIfDockerNotPresentAttribute : Attribute, ITestCondition - { - public bool IsMet => CheckDocker(); - public string SkipReason { get; private set; } = "Docker is not available"; - - private bool CheckDocker() - { - if(Docker.Default != null) - { - // Docker is present, but is it working? - if (Docker.Default.RunCommand("ps", "docker ps", out var output) != 0) - { - SkipReason = $"Failed to invoke test command 'docker ps'. Output: {output}"; - } - else - { - // We have a docker - return true; - } - } - else - { - SkipReason = "Docker is not installed on the host machine."; - } - - // If we get here, we don't have a docker - return false; - } - } -} diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Startup.cs b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Startup.cs deleted file mode 100644 index 3259ab7f40..0000000000 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/Startup.cs +++ /dev/null @@ -1,49 +0,0 @@ -// 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; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Primitives; - -namespace Microsoft.AspNetCore.SignalR.Redis.Tests -{ - public class Startup - { - public void ConfigureServices(IServiceCollection services) - { - services.AddSignalR(options => - { - options.EnableDetailedErrors = true; - }) - .AddMessagePackProtocol() - .AddRedis(options => - { - options.Configuration.EndPoints.Add(Environment.GetEnvironmentVariable("REDIS_CONNECTION-PREV")); - }); - - services.AddSingleton(); - } - - public void Configure(IApplicationBuilder app, IHostingEnvironment env) - { - app.UseSignalR(options => options.MapHub("/echo")); - } - - private class UserNameIdProvider : IUserIdProvider - { - public string GetUserId(HubConnectionContext connection) - { - // This is an AWFUL way to authenticate users! We're just using it for test purposes. - var userNameHeader = connection.GetHttpContext().Request.Headers["UserName"]; - if (!StringValues.IsNullOrEmpty(userNameHeader)) - { - return userNameHeader; - } - - return null; - } - } - } -} diff --git a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/TestConnectionMultiplexer.cs b/test/Microsoft.AspNetCore.SignalR.Redis.Tests/TestConnectionMultiplexer.cs deleted file mode 100644 index 2852f9c64c..0000000000 --- a/test/Microsoft.AspNetCore.SignalR.Redis.Tests/TestConnectionMultiplexer.cs +++ /dev/null @@ -1,350 +0,0 @@ -// 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; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Threading.Tasks; -using StackExchange.Redis; - -namespace Microsoft.AspNetCore.SignalR.Tests -{ - public class TestConnectionMultiplexer : IConnectionMultiplexer - { - public string ClientName => throw new NotImplementedException(); - - public string Configuration => throw new NotImplementedException(); - - public int TimeoutMilliseconds => throw new NotImplementedException(); - - public long OperationCount => throw new NotImplementedException(); - - public bool PreserveAsyncOrder { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public bool IsConnected => true; - - public bool IncludeDetailInExceptions { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - public int StormLogThreshold { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } - - public event EventHandler ErrorMessage - { - add { } - remove { } - } - - public event EventHandler ConnectionFailed - { - add { } - remove { } - } - - public event EventHandler InternalError - { - add { } - remove { } - } - - public event EventHandler ConnectionRestored - { - add { } - remove { } - } - - public event EventHandler ConfigurationChanged - { - add { } - remove { } - } - - public event EventHandler ConfigurationChangedBroadcast - { - add { } - remove { } - } - - public event EventHandler HashSlotMoved - { - add { } - remove { } - } - - private readonly ISubscriber _subscriber; - - public TestConnectionMultiplexer(TestRedisServer server) - { - _subscriber = new TestSubscriber(server); - } - - public void BeginProfiling(object forContext) - { - throw new NotImplementedException(); - } - - public void Close(bool allowCommandsToComplete = true) - { - throw new NotImplementedException(); - } - - public Task CloseAsync(bool allowCommandsToComplete = true) - { - throw new NotImplementedException(); - } - - public bool Configure(TextWriter log = null) - { - throw new NotImplementedException(); - } - - public Task ConfigureAsync(TextWriter log = null) - { - throw new NotImplementedException(); - } - - public void Dispose() - { - throw new NotImplementedException(); - } - - public ProfiledCommandEnumerable FinishProfiling(object forContext, bool allowCleanupSweep = true) - { - throw new NotImplementedException(); - } - - public ServerCounters GetCounters() - { - throw new NotImplementedException(); - } - - public IDatabase GetDatabase(int db = -1, object asyncState = null) - { - throw new NotImplementedException(); - } - - public EndPoint[] GetEndPoints(bool configuredOnly = false) - { - throw new NotImplementedException(); - } - - public IServer GetServer(string host, int port, object asyncState = null) - { - throw new NotImplementedException(); - } - - public IServer GetServer(string hostAndPort, object asyncState = null) - { - throw new NotImplementedException(); - } - - public IServer GetServer(IPAddress host, int port) - { - throw new NotImplementedException(); - } - - public IServer GetServer(EndPoint endpoint, object asyncState = null) - { - throw new NotImplementedException(); - } - - public string GetStatus() - { - throw new NotImplementedException(); - } - - public void GetStatus(TextWriter log) - { - throw new NotImplementedException(); - } - - public string GetStormLog() - { - throw new NotImplementedException(); - } - - public ISubscriber GetSubscriber(object asyncState = null) - { - return _subscriber; - } - - public int HashSlot(RedisKey key) - { - throw new NotImplementedException(); - } - - public long PublishReconfigure(CommandFlags flags = CommandFlags.None) - { - throw new NotImplementedException(); - } - - public Task PublishReconfigureAsync(CommandFlags flags = CommandFlags.None) - { - throw new NotImplementedException(); - } - - public void RegisterProfiler(IProfiler profiler) - { - throw new NotImplementedException(); - } - - public void ResetStormLog() - { - throw new NotImplementedException(); - } - - public void Wait(Task task) - { - throw new NotImplementedException(); - } - - public T Wait(Task task) - { - throw new NotImplementedException(); - } - - public void WaitAll(params Task[] tasks) - { - throw new NotImplementedException(); - } - } - - public class TestRedisServer - { - private readonly ConcurrentDictionary>> _subscriptions = - new ConcurrentDictionary>>(); - - public long Publish(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None) - { - if (_subscriptions.TryGetValue(channel, out var handlers)) - { - foreach (var handler in handlers) - { - handler(channel, message); - } - } - - return handlers != null ? handlers.Count : 0; - } - - public void Subscribe(RedisChannel channel, Action handler, CommandFlags flags = CommandFlags.None) - { - _subscriptions.AddOrUpdate(channel, _ => new List> { handler }, (_, list) => - { - list.Add(handler); - return list; - }); - } - - public void Unsubscribe(RedisChannel channel, Action handler = null, CommandFlags flags = CommandFlags.None) - { - if (_subscriptions.TryGetValue(channel, out var list)) - { - list.Remove(handler); - } - } - } - - public class TestSubscriber : ISubscriber - { - private readonly TestRedisServer _server; - public ConnectionMultiplexer Multiplexer => throw new NotImplementedException(); - - public TestSubscriber(TestRedisServer server) - { - _server = server; - } - - public EndPoint IdentifyEndpoint(RedisChannel channel, CommandFlags flags = CommandFlags.None) - { - throw new NotImplementedException(); - } - - public Task IdentifyEndpointAsync(RedisChannel channel, CommandFlags flags = CommandFlags.None) - { - throw new NotImplementedException(); - } - - public bool IsConnected(RedisChannel channel = default) - { - throw new NotImplementedException(); - } - - public TimeSpan Ping(CommandFlags flags = CommandFlags.None) - { - throw new NotImplementedException(); - } - - public Task PingAsync(CommandFlags flags = CommandFlags.None) - { - throw new NotImplementedException(); - } - - public long Publish(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None) - { - return _server.Publish(channel, message, flags); - } - - public async Task PublishAsync(RedisChannel channel, RedisValue message, CommandFlags flags = CommandFlags.None) - { - await Task.Yield(); - return Publish(channel, message, flags); - } - - public void Subscribe(RedisChannel channel, Action handler, CommandFlags flags = CommandFlags.None) - { - _server.Subscribe(channel, handler, flags); - } - - public Task SubscribeAsync(RedisChannel channel, Action handler, CommandFlags flags = CommandFlags.None) - { - Subscribe(channel, handler, flags); - return Task.CompletedTask; - } - - public EndPoint SubscribedEndpoint(RedisChannel channel) - { - throw new NotImplementedException(); - } - - public bool TryWait(Task task) - { - throw new NotImplementedException(); - } - - public void Unsubscribe(RedisChannel channel, Action handler = null, CommandFlags flags = CommandFlags.None) - { - _server.Unsubscribe(channel, handler, flags); - } - - public void UnsubscribeAll(CommandFlags flags = CommandFlags.None) - { - throw new NotImplementedException(); - } - - public Task UnsubscribeAllAsync(CommandFlags flags = CommandFlags.None) - { - throw new NotImplementedException(); - } - - public Task UnsubscribeAsync(RedisChannel channel, Action handler = null, CommandFlags flags = CommandFlags.None) - { - Unsubscribe(channel, handler, flags); - return Task.CompletedTask; - } - - public void Wait(Task task) - { - throw new NotImplementedException(); - } - - public T Wait(Task task) - { - throw new NotImplementedException(); - } - - public void WaitAll(params Task[] tasks) - { - throw new NotImplementedException(); - } - } -} From 71e2f4545075aba39b24726f7defa0bb64b647e1 Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Tue, 6 Nov 2018 09:24:34 -0800 Subject: [PATCH 19/30] Wrap log in enabled check --- .../Internal/DefaultHubDispatcher.Log.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.Log.cs b/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.Log.cs index 096b4ec229..10fb4da955 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.Log.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.Log.cs @@ -102,8 +102,11 @@ namespace Microsoft.AspNetCore.SignalR.Internal public static void SendingResult(ILogger logger, string invocationId, ObjectMethodExecutor objectMethodExecutor) { - var resultType = objectMethodExecutor.AsyncResultType == null ? objectMethodExecutor.MethodReturnType : objectMethodExecutor.AsyncResultType; - _sendingResult(logger, invocationId, resultType.FullName, null); + if (logger.IsEnabled(LogLevel.Trace)) + { + var resultType = objectMethodExecutor.AsyncResultType == null ? objectMethodExecutor.MethodReturnType : objectMethodExecutor.AsyncResultType; + _sendingResult(logger, invocationId, resultType.FullName, null); + } } public static void FailedInvokingHubMethod(ILogger logger, string hubMethod, Exception exception) From c206ea612a4704f920f62d53fa253f615e4998f4 Mon Sep 17 00:00:00 2001 From: dotnet-maestro-bot Date: Wed, 7 Nov 2018 15:27:19 -0800 Subject: [PATCH 20/30] [automated] Merge branch 'release/2.2' => 'master' (#3278) I detected changes in the release/2.2 branch which have not been merged yet to master. I'm a robot and am configured to help you automatically keep master up to date, so I've opened this PR. This PR merges commits made on release/2.2 by the following committers: * @anurse ## Instructions for merging This PR will not be auto-merged. When pull request checks pass, please complete this PR by creating a merge commit, *not* a squash or rebase commit. merge button instructions You can also do this on command line: ``` git checkout -b merge/release/2.2-to-master master git pull https://github.com/dotnet-maestro-bot/SignalR merge/release/2.2-to-master git checkout master git merge --no-ff merge/release/2.2-to-master git push origin master ``` ## Instructions for resolving conflicts :warning: If there are merge conflicts, you will need to resolve them manually before merging. You can do this [using GitHub][resolve-github] or using the [command line][resolve-cli]. [resolve-github]: https://help.github.com/articles/resolving-a-merge-conflict-on-github/ [resolve-cli]: https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/ ## Instructions for updating this pull request Contributors to this repo have permission update this pull request by pushing to the branch 'merge/release/2.2-to-master'. This can be done to resolve conflicts or make other changes to this pull request before it is merged. ``` git checkout -b merge/release/2.2-to-master master git pull https://github.com/dotnet-maestro-bot/SignalR merge/release/2.2-to-master (make changes) git commit -m "Updated PR with my changes" git push https://github.com/dotnet-maestro-bot/SignalR merge/release/2.2-to-master ``` Please contact .NET Core Engineering if you have questions or issues. Also, if this PR was generated incorrectly, help us fix it. See https://github.com/dotnet/arcade/blob/master/scripts/GitHubMergeBranches.ps1. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 896a93ff72..4223ebe9c3 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,10 @@ You can watch an introductory presentation here - [ASP.NET Core SignalR: Build 2 This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the [Home](https://github.com/aspnet/home) repo. +## Documentation + +Documentation for ASP.NET Core SignalR can be found in the [Real-time Apps](https://docs.microsoft.com/en-us/aspnet/core/signalr/introduction?view=aspnetcore-2.1) section of the ASP.NET Core Documentation site. + ## TypeScript Version If you are encountering TypeScript definition issues with SignalR, please ensure you are using the latest version of TypeScript to compile your application. If the issue occurs in the latest TypeScript, please let us know. From dea121061bc9923c4b02ba6698a0f6025be08c99 Mon Sep 17 00:00:00 2001 From: Mikael Mengistu Date: Thu, 8 Nov 2018 12:30:10 -0800 Subject: [PATCH 21/30] Update RxJava dependency. (#3272) --- clients/java/signalr/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/java/signalr/build.gradle b/clients/java/signalr/build.gradle index 70eaa9fc45..20c3661bda 100644 --- a/clients/java/signalr/build.gradle +++ b/clients/java/signalr/build.gradle @@ -35,7 +35,7 @@ dependencies { testCompile 'org.slf4j:slf4j-jdk14:1.7.25' implementation 'com.google.code.gson:gson:2.8.5' implementation 'com.squareup.okhttp3:okhttp:3.11.0' - api 'io.reactivex.rxjava2:rxjava:2.2.2' + api 'io.reactivex.rxjava2:rxjava:2.2.3' implementation 'org.slf4j:slf4j-api:1.7.25' } From cdd7387159190d4e3c1755ffc0830d5b5073bb28 Mon Sep 17 00:00:00 2001 From: Mikael Mengistu Date: Fri, 16 Nov 2018 16:29:32 -0800 Subject: [PATCH 22/30] Java Client Steaming (#3301) --- .../signalr/CancelInvocationMessage.java | 18 ++ .../com/microsoft/signalr/HubConnection.java | 64 ++++- .../microsoft/signalr/InvocationRequest.java | 21 +- .../microsoft/signalr/JsonHubProtocol.java | 13 +- .../signalr/StreamInvocationMessage.java | 23 +- .../com/microsoft/signalr/StreamItem.java | 28 +++ .../microsoft/signalr/HubConnectionTest.java | 219 ++++++++++++++++++ .../signalr/JsonHubProtocolTest.java | 9 - 8 files changed, 368 insertions(+), 27 deletions(-) create mode 100644 clients/java/signalr/src/main/java/com/microsoft/signalr/CancelInvocationMessage.java create mode 100644 clients/java/signalr/src/main/java/com/microsoft/signalr/StreamItem.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/CancelInvocationMessage.java b/clients/java/signalr/src/main/java/com/microsoft/signalr/CancelInvocationMessage.java new file mode 100644 index 0000000000..096c49faf0 --- /dev/null +++ b/clients/java/signalr/src/main/java/com/microsoft/signalr/CancelInvocationMessage.java @@ -0,0 +1,18 @@ +// 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. + +package com.microsoft.signalr; + +final class CancelInvocationMessage extends HubMessage { + private final int type = HubMessageType.CANCEL_INVOCATION.value; + private final String invocationId; + + public CancelInvocationMessage(String invocationId) { + this.invocationId = invocationId; + } + + @Override + public HubMessageType getMessageType() { + return HubMessageType.CANCEL_INVOCATION; + } +} diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java b/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java index 485137d0a6..5b255ec9bd 100644 --- a/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java +++ b/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java @@ -21,9 +21,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import io.reactivex.Completable; +import io.reactivex.Observable; import io.reactivex.Single; -import io.reactivex.subjects.CompletableSubject; -import io.reactivex.subjects.SingleSubject; +import io.reactivex.subjects.*; /** * A connection used to invoke hub methods on a SignalR Server. @@ -58,7 +58,6 @@ public class HubConnection { private long handshakeResponseTimeout = 15*1000; private final Logger logger = LoggerFactory.getLogger(HubConnection.class); - /** * Sets the server timeout interval for the connection. * @@ -202,8 +201,17 @@ public class HubConnection { } irq.complete(completionMessage); break; - case STREAM_INVOCATION: case STREAM_ITEM: + StreamItem streamItem = (StreamItem)message; + InvocationRequest streamInvocationRequest = connectionState.getInvocation(streamItem.getInvocationId()); + if (streamInvocationRequest == null) { + logger.warn("Dropped unsolicited Completion message for invocation '{}'.", streamItem.getInvocationId()); + continue; + } + + streamInvocationRequest.addItem(streamItem); + break; + case STREAM_INVOCATION: case CANCEL_INVOCATION: logger.error("This client does not support {} messages.", message.getMessageType()); @@ -481,7 +489,7 @@ public class HubConnection { // forward the invocation result or error to the user // run continuations on a separate thread - Single pendingCall = irq.getPendingCall(); + Subject pendingCall = irq.getPendingCall(); pendingCall.subscribe(result -> { // Primitive types can't be cast with the Class cast function if (returnType.isPrimitive()) { @@ -498,10 +506,54 @@ public class HubConnection { return subject; } + /** + * Invokes a streaming hub method on the server using the specified name and arguments. + * + * @param returnType The expected return type of the stream items. + * @param method The name of the server method to invoke. + * @param args The arguments used to invoke the server method. + * @param The expected return type. + * @return An observable that yields the streaming results from the server. + */ + @SuppressWarnings("unchecked") + public Observable stream(Class returnType, String method, Object ... args) { + String invocationId = connectionState.getNextInvocationId(); + AtomicInteger subscriptionCount = new AtomicInteger(); + StreamInvocationMessage streamInvocationMessage = new StreamInvocationMessage(invocationId, method, args); + InvocationRequest irq = new InvocationRequest(returnType, invocationId); + connectionState.addInvocation(irq); + ReplaySubject subject = ReplaySubject.create(); + + Subject pendingCall = irq.getPendingCall(); + pendingCall.subscribe(result -> { + // Primitive types can't be cast with the Class cast function + if (returnType.isPrimitive()) { + subject.onNext((T)result); + } else { + subject.onNext(returnType.cast(result)); + } + }, error -> subject.onError(error), + () -> subject.onComplete()); + + sendHubMessage(streamInvocationMessage); + Observable observable = subject.doOnSubscribe((subscriber) -> subscriptionCount.incrementAndGet()); + + return observable.doOnDispose(() -> { + if (subscriptionCount.decrementAndGet() == 0) { + CancelInvocationMessage cancelInvocationMessage = new CancelInvocationMessage(invocationId); + sendHubMessage(cancelInvocationMessage); + connectionState.tryRemoveInvocation(invocationId); + subject.onComplete(); + } + }); + } + private void sendHubMessage(HubMessage message) { String serializedMessage = protocol.writeMessage(message); - if (message.getMessageType() == HubMessageType.INVOCATION) { + if (message.getMessageType() == HubMessageType.INVOCATION ) { logger.debug("Sending {} message '{}'.", message.getMessageType().name(), ((InvocationMessage)message).getInvocationId()); + } else if (message.getMessageType() == HubMessageType.STREAM_INVOCATION) { + logger.debug("Sending {} message '{}'.", message.getMessageType().name(), ((StreamInvocationMessage)message).getInvocationId()); } else { logger.debug("Sending {} message.", message.getMessageType().name()); } diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationRequest.java b/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationRequest.java index 3d12d39d04..1c936da663 100644 --- a/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationRequest.java +++ b/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationRequest.java @@ -5,12 +5,12 @@ package com.microsoft.signalr; import java.util.concurrent.CancellationException; -import io.reactivex.Single; -import io.reactivex.subjects.SingleSubject; +import io.reactivex.subjects.ReplaySubject; +import io.reactivex.subjects.Subject; class InvocationRequest { private final Class returnType; - private final SingleSubject pendingCall = SingleSubject.create(); + private final Subject pendingCall = ReplaySubject.create(); private final String invocationId; InvocationRequest(Class returnType, String invocationId) { @@ -19,13 +19,22 @@ class InvocationRequest { } public void complete(CompletionMessage completion) { - if (completion.getResult() != null) { - pendingCall.onSuccess(completion.getResult()); + if (completion.getError() == null) { + if (completion.getResult() != null) { + pendingCall.onNext(completion.getResult()); + } + pendingCall.onComplete(); } else { pendingCall.onError(new HubException(completion.getError())); } } + public void addItem(StreamItem streamItem) { + if (streamItem.getResult() != null) { + pendingCall.onNext(streamItem.getResult()); + } + } + public void fail(Exception ex) { pendingCall.onError(ex); } @@ -34,7 +43,7 @@ class InvocationRequest { pendingCall.onError(new CancellationException("Invocation was canceled.")); } - public Single getPendingCall() { + public Subject getPendingCall() { return pendingCall; } diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/JsonHubProtocol.java b/clients/java/signalr/src/main/java/com/microsoft/signalr/JsonHubProtocol.java index 8ff1024b4b..b0005f8cd7 100644 --- a/clients/java/signalr/src/main/java/com/microsoft/signalr/JsonHubProtocol.java +++ b/clients/java/signalr/src/main/java/com/microsoft/signalr/JsonHubProtocol.java @@ -73,7 +73,7 @@ class JsonHubProtocol implements HubProtocol { error = reader.nextString(); break; case "result": - if (invocationId == null) { + if (invocationId == null || binder.getReturnType(invocationId) == null) { resultToken = jsonParser.parse(reader); } else { result = gson.fromJson(reader, binder.getReturnType(invocationId)); @@ -142,12 +142,19 @@ class JsonHubProtocol implements HubProtocol { break; case COMPLETION: if (resultToken != null) { - result = gson.fromJson(resultToken, binder.getReturnType(invocationId)); + Class returnType = binder.getReturnType(invocationId); + result = gson.fromJson(resultToken, returnType != null ? returnType : Object.class); } hubMessages.add(new CompletionMessage(invocationId, result, error)); break; - case STREAM_INVOCATION: case STREAM_ITEM: + if (resultToken != null) { + Class returnType = binder.getReturnType(invocationId); + result = gson.fromJson(resultToken, returnType != null ? returnType : Object.class); + } + hubMessages.add(new StreamItem(invocationId, result)); + break; + case STREAM_INVOCATION: case CANCEL_INVOCATION: throw new UnsupportedOperationException(String.format("The message type %s is not supported yet.", messageType)); case PING: diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamInvocationMessage.java b/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamInvocationMessage.java index eb4ae0e479..f897195667 100644 --- a/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamInvocationMessage.java +++ b/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamInvocationMessage.java @@ -3,11 +3,28 @@ package com.microsoft.signalr; -class StreamInvocationMessage extends InvocationMessage { +final class StreamInvocationMessage extends HubMessage { private final int type = HubMessageType.STREAM_INVOCATION.value; + private final String invocationId; + private final String target; + private final Object[] arguments; - public StreamInvocationMessage(String invocationId, String target, Object[] arguments) { - super(invocationId, target, arguments); + public StreamInvocationMessage(String invocationId, String target, Object[] args) { + this.invocationId = invocationId; + this.target = target; + this.arguments = args; + } + + public String getInvocationId() { + return invocationId; + } + + public String getTarget() { + return target; + } + + public Object[] getArguments() { + return arguments; } @Override diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamItem.java b/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamItem.java new file mode 100644 index 0000000000..e39941d04c --- /dev/null +++ b/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamItem.java @@ -0,0 +1,28 @@ +// 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. + +package com.microsoft.signalr; + +final class StreamItem extends HubMessage { + private final int type = HubMessageType.STREAM_ITEM.value; + private final String invocationId; + private final Object result; + + public StreamItem(String invocationId, Object result) { + this.invocationId = invocationId; + this.result = result; + } + + public String getInvocationId() { + return invocationId; + } + + public Object getResult() { + return result; + } + + @Override + public HubMessageType getMessageType() { + return HubMessageType.STREAM_ITEM; + } +} diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java b/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java index 6c29be1c82..cab2ae0ecb 100644 --- a/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java +++ b/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java @@ -5,6 +5,7 @@ package com.microsoft.signalr; import static org.junit.jupiter.api.Assertions.*; +import java.util.Iterator; import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; @@ -15,7 +16,9 @@ import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.Test; +import io.reactivex.Observable; import io.reactivex.Single; +import io.reactivex.disposables.Disposable; import io.reactivex.subjects.SingleSubject; class HubConnectionTest { @@ -367,6 +370,222 @@ class HubConnectionTest { assertEquals(Double.valueOf(24), value.get()); } + @Test + public void checkStreamSingleItem() { + MockTransport mockTransport = new MockTransport(); + HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport); + + hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait(); + + AtomicBoolean completed = new AtomicBoolean(); + AtomicBoolean onNextCalled = new AtomicBoolean(); + Observable result = hubConnection.stream(String.class, "echo", "message"); + result.subscribe((item) -> onNextCalled.set(true), + (error) -> {}, + () -> completed.set(true)); + + assertEquals("{\"type\":4,\"invocationId\":\"1\",\"target\":\"echo\",\"arguments\":[\"message\"]}" + RECORD_SEPARATOR, mockTransport.getSentMessages()[1]); + assertFalse(completed.get()); + assertFalse(onNextCalled.get()); + + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"First\"}" + RECORD_SEPARATOR); + + assertTrue(onNextCalled.get()); + + mockTransport.receiveMessage("{\"type\":3,\"invocationId\":\"1\",\"result\":\"hello\"}" + RECORD_SEPARATOR); + assertTrue(completed.get()); + + assertEquals("First", result.timeout(1000, TimeUnit.MILLISECONDS).blockingFirst()); + } + + @Test + public void checkStreamCompletionResult() { + MockTransport mockTransport = new MockTransport(); + HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport); + + hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait(); + + AtomicBoolean completed = new AtomicBoolean(); + AtomicBoolean onNextCalled = new AtomicBoolean(); + Observable result = hubConnection.stream(String.class, "echo", "message"); + result.subscribe((item) -> onNextCalled.set(true), + (error) -> {}, + () -> completed.set(true)); + + assertEquals("{\"type\":4,\"invocationId\":\"1\",\"target\":\"echo\",\"arguments\":[\"message\"]}" + RECORD_SEPARATOR, mockTransport.getSentMessages()[1]); + assertFalse(completed.get()); + assertFalse(onNextCalled.get()); + + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"First\"}" + RECORD_SEPARATOR); + + assertTrue(onNextCalled.get()); + + mockTransport.receiveMessage("{\"type\":3,\"invocationId\":\"1\",\"result\":\"COMPLETED\"}" + RECORD_SEPARATOR); + assertTrue(completed.get()); + + assertEquals("First", result.timeout(1000, TimeUnit.MILLISECONDS).blockingFirst()); + assertEquals("COMPLETED", result.timeout(1000, TimeUnit.MILLISECONDS).blockingLast()); + + } + + @Test + public void checkStreamCompletionError() { + MockTransport mockTransport = new MockTransport(); + HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport); + + hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait(); + + AtomicBoolean onErrorCalled = new AtomicBoolean(); + AtomicBoolean onNextCalled = new AtomicBoolean(); + Observable result = hubConnection.stream(String.class, "echo", "message"); + result.subscribe((item) -> onNextCalled.set(true), + (error) -> onErrorCalled.set(true), + () -> {}); + + assertEquals("{\"type\":4,\"invocationId\":\"1\",\"target\":\"echo\",\"arguments\":[\"message\"]}" + RECORD_SEPARATOR, mockTransport.getSentMessages()[1]); + assertFalse(onErrorCalled.get()); + assertFalse(onNextCalled.get()); + + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"First\"}" + RECORD_SEPARATOR); + + assertTrue(onNextCalled.get()); + + mockTransport.receiveMessage("{\"type\":3,\"invocationId\":\"1\",\"error\":\"There was an error\"}" + RECORD_SEPARATOR); + assertTrue(onErrorCalled.get()); + + assertEquals("First", result.timeout(1000, TimeUnit.MILLISECONDS).blockingFirst()); + Throwable exception = assertThrows(HubException.class, () -> result.timeout(1000, TimeUnit.MILLISECONDS).blockingLast()); + assertEquals("There was an error", exception.getMessage()); + } + + @Test + public void checkStreamMultipleItems() { + MockTransport mockTransport = new MockTransport(); + HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport); + + hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait(); + + AtomicBoolean completed = new AtomicBoolean(); + Observable result = hubConnection.stream(String.class, "echo", "message"); + result.subscribe((item) -> {/*OnNext*/ }, + (error) -> {/*OnError*/}, + () -> {/*OnCompleted*/completed.set(true);}); + + assertEquals("{\"type\":4,\"invocationId\":\"1\",\"target\":\"echo\",\"arguments\":[\"message\"]}" + RECORD_SEPARATOR, mockTransport.getSentMessages()[1]); + assertFalse(completed.get()); + + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"First\"}" + RECORD_SEPARATOR); + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"Second\"}" + RECORD_SEPARATOR); + mockTransport.receiveMessage("{\"type\":3,\"invocationId\":\"1\",\"result\":\"null\"}" + RECORD_SEPARATOR); + + Iterator resultIterator = result.timeout(1000, TimeUnit.MILLISECONDS).blockingIterable().iterator(); + assertEquals("First", resultIterator.next()); + assertEquals("Second", resultIterator.next()); + assertTrue(completed.get()); + } + + @Test + public void checkCancelIsSentAfterDispose() { + MockTransport mockTransport = new MockTransport(); + HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport); + + hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait(); + + AtomicBoolean completed = new AtomicBoolean(); + Observable result = hubConnection.stream(String.class, "echo", "message"); + Disposable subscription = result.subscribe((item) -> {/*OnNext*/ }, + (error) -> {/*OnError*/}, + () -> {/*OnCompleted*/completed.set(true);}); + + assertEquals("{\"type\":4,\"invocationId\":\"1\",\"target\":\"echo\",\"arguments\":[\"message\"]}" + RECORD_SEPARATOR, mockTransport.getSentMessages()[1]); + assertFalse(completed.get()); + + subscription.dispose(); + assertEquals("{\"type\":5,\"invocationId\":\"1\"}" + RECORD_SEPARATOR, mockTransport.getSentMessages()[2]); + } + + @Test + public void checkCancelIsSentAfterAllSubscriptionsAreDisposed() { + MockTransport mockTransport = new MockTransport(); + HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport); + + hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait(); + + Observable result = hubConnection.stream(String.class, "echo", "message"); + Disposable subscription = result.subscribe((item) -> {/*OnNext*/ }, + (error) -> {/*OnError*/}, + () -> {/*OnCompleted*/}); + + Disposable secondSubscription = result.subscribe((item) -> {/*OnNext*/ }, + (error) -> {/*OnError*/}, + () -> {/*OnCompleted*/}); + + subscription.dispose(); + assertEquals(2, mockTransport.getSentMessages().length); + assertEquals("{\"type\":4,\"invocationId\":\"1\",\"target\":\"echo\",\"arguments\":[\"message\"]}" + RECORD_SEPARATOR, + mockTransport.getSentMessages()[mockTransport.getSentMessages().length - 1]); + + secondSubscription.dispose(); + assertEquals(3, mockTransport.getSentMessages().length); + assertEquals("{\"type\":5,\"invocationId\":\"1\"}" + RECORD_SEPARATOR, + mockTransport.getSentMessages()[mockTransport.getSentMessages().length - 1]); + } + + @Test + public void checkStreamWithDispose() { + MockTransport mockTransport = new MockTransport(); + HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport); + + hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait(); + + Observable result = hubConnection.stream(String.class, "echo", "message"); + Disposable subscription = result.subscribe((item) -> {/*OnNext*/}, + (error) -> {/*OnError*/}, + () -> {/*OnCompleted*/}); + + assertEquals("{\"type\":4,\"invocationId\":\"1\",\"target\":\"echo\",\"arguments\":[\"message\"]}" + RECORD_SEPARATOR, mockTransport.getSentMessages()[1]); + + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"First\"}" + RECORD_SEPARATOR); + + subscription.dispose(); + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"Second\"}" + RECORD_SEPARATOR); + + assertEquals("First", result.timeout(1000, TimeUnit.MILLISECONDS).blockingLast()); + } + + @Test + public void checkStreamWithDisposeWithMultipleSubscriptions() { + MockTransport mockTransport = new MockTransport(); + HubConnection hubConnection = TestUtils.createHubConnection("http://example.com", mockTransport); + + hubConnection.start().timeout(1, TimeUnit.SECONDS).blockingAwait(); + + AtomicBoolean completed = new AtomicBoolean(); + Observable result = hubConnection.stream(String.class, "echo", "message"); + Disposable subscription = result.subscribe((item) -> {/*OnNext*/}, + (error) -> {/*OnError*/}, + () -> {/*OnCompleted*/}); + + Disposable subscription2 = result.subscribe((item) -> {/*OnNext*/}, + (error) -> {/*OnError*/}, + () -> {/*OnCompleted*/completed.set(true);}); + + assertEquals("{\"type\":4,\"invocationId\":\"1\",\"target\":\"echo\",\"arguments\":[\"message\"]}" + RECORD_SEPARATOR, mockTransport.getSentMessages()[1]); + assertFalse(completed.get()); + + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"First\"}" + RECORD_SEPARATOR); + + subscription.dispose(); + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"Second\"}" + RECORD_SEPARATOR); + + mockTransport.receiveMessage("{\"type\":3,\"invocationId\":\"1\"}" + RECORD_SEPARATOR); + assertTrue(completed.get()); + assertEquals("First", result.timeout(1000, TimeUnit.MILLISECONDS).blockingFirst()); + + subscription2.dispose(); + assertEquals("Second", result.timeout(1000, TimeUnit.MILLISECONDS).blockingLast()); + } + @Test public void invokeWaitsForCompletionMessage() { MockTransport mockTransport = new MockTransport(); diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/JsonHubProtocolTest.java b/clients/java/signalr/src/test/java/com/microsoft/signalr/JsonHubProtocolTest.java index 8a8ad9f3cd..f4df7a24b6 100644 --- a/clients/java/signalr/src/test/java/com/microsoft/signalr/JsonHubProtocolTest.java +++ b/clients/java/signalr/src/test/java/com/microsoft/signalr/JsonHubProtocolTest.java @@ -108,15 +108,6 @@ class JsonHubProtocolTest { assertEquals(42, messageResult); } - @Test - public void parseSingleUnsupportedStreamItemMessage() { - String stringifiedMessage = "{\"type\":2,\"Id\":1,\"Item\":42}\u001E"; - TestBinder binder = new TestBinder(null); - - Throwable exception = assertThrows(UnsupportedOperationException.class, () -> jsonHubProtocol.parseMessages(stringifiedMessage, binder)); - assertEquals("The message type STREAM_ITEM is not supported yet.", exception.getMessage()); - } - @Test public void parseSingleUnsupportedStreamInvocationMessage() { String stringifiedMessage = "{\"type\":4,\"Id\":1,\"target\":\"test\",\"arguments\":[42]}\u001E"; From 3db604d9d25429b1a622bd018f6d59549a7a9f22 Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Fri, 16 Nov 2018 16:44:36 -0800 Subject: [PATCH 23/30] Upgrade packages and projects to target netcoreapp3.0 (except the .NET signalr client) (aspnet/SignalR#3315) --- Directory.Build.targets | 4 +- .../BenchmarkServer/BenchmarkServer.csproj | 8 +- benchmarkapps/Crankier/Crankier.csproj | 2 +- ....AspNetCore.SignalR.Microbenchmarks.csproj | 2 +- build/dependencies.props | 92 +++++++++---------- build/publish-apps.ps1 | 4 +- build/repo.props | 2 +- .../ts/FunctionalTests/FunctionalTests.csproj | 2 +- clients/ts/FunctionalTests/package-lock.json | 28 ++++-- .../ts/FunctionalTests/scripts/run-tests.ts | 2 +- clients/ts/common/package-lock.json | 13 ++- .../package-lock.json | 36 ++++---- clients/ts/signalr/package-lock.json | 10 +- korebuild-lock.txt | 4 +- samples/ClientSample/ClientSample.csproj | 2 +- samples/ClientSample/Tcp/SocketReceiver.cs | 2 +- samples/ClientSample/Tcp/SocketSender.cs | 4 +- .../JwtClientSample/JwtClientSample.csproj | 2 +- samples/JwtSample/JwtSample.csproj | 2 +- samples/SignalRSamples/SignalRSamples.csproj | 2 +- samples/SocialWeather/SocialWeather.csproj | 2 +- .../WebSocketSample/WebSocketSample.csproj | 2 +- src/Common/MemoryBufferWriter.cs | 2 +- src/Common/PipeWriterStream.cs | 2 +- src/Common/StreamExtensions.cs | 4 +- src/Common/Utf8BufferTextReader.cs | 2 +- src/Common/Utf8BufferTextWriter.cs | 4 +- src/Common/WebSocketExtensions.cs | 6 +- .../HttpConnection.cs | 4 +- .../Internal/WebSocketsTransport.cs | 6 +- ....AspNetCore.Http.Connections.Client.csproj | 2 +- .../Transports/WebSocketsTransport.cs | 6 +- ...crosoft.AspNetCore.Http.Connections.csproj | 2 +- ...Microsoft.AspNetCore.SignalR.Common.csproj | 4 +- .../Microsoft.AspNetCore.SignalR.Core.csproj | 2 +- ...NetCore.SignalR.Specification.Tests.csproj | 6 +- ...pNetCore.SignalR.StackExchangeRedis.csproj | 2 +- .../Microsoft.AspNetCore.SignalR.csproj | 2 +- test/Directory.Build.props | 3 - ...t.AspNetCore.Http.Connections.Tests.csproj | 3 +- ...Core.SignalR.Client.FunctionalTests.csproj | 2 +- ...oft.AspNetCore.SignalR.Client.Tests.csproj | 2 +- .../Protocol/MemoryBufferWriterTests.cs | 2 +- ...oft.AspNetCore.SignalR.Common.Tests.csproj | 4 +- ...re.SignalR.StackExchangeRedis.Tests.csproj | 2 +- ...soft.AspNetCore.SignalR.Tests.Utils.csproj | 2 +- .../TestHelpers.cs | 2 +- .../Microsoft.AspNetCore.SignalR.Tests.csproj | 13 +-- 48 files changed, 159 insertions(+), 159 deletions(-) diff --git a/Directory.Build.targets b/Directory.Build.targets index a5761bff02..923e244638 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -1,7 +1,5 @@  - $(MicrosoftNETCoreApp22PackageVersion) - - 99.9 + $(MicrosoftNETCoreAppPackageVersion) diff --git a/benchmarkapps/BenchmarkServer/BenchmarkServer.csproj b/benchmarkapps/BenchmarkServer/BenchmarkServer.csproj index f9dedb7341..cc5036ad1a 100644 --- a/benchmarkapps/BenchmarkServer/BenchmarkServer.csproj +++ b/benchmarkapps/BenchmarkServer/BenchmarkServer.csproj @@ -1,9 +1,7 @@  - netcoreapp2.2 - - $([System.String]::Copy($(MicrosoftAspNetCoreAllPackageVersion)).Replace('2.2', '1.1')) + netcoreapp3.0 @@ -23,8 +21,8 @@ - - + + diff --git a/benchmarkapps/Crankier/Crankier.csproj b/benchmarkapps/Crankier/Crankier.csproj index d73db04ff4..d8dbc064ff 100644 --- a/benchmarkapps/Crankier/Crankier.csproj +++ b/benchmarkapps/Crankier/Crankier.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.2 + netcoreapp3.0 Microsoft.AspNetCore.SignalR.CranksRevenge diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj index 0143f5ffae..4f0e19b517 100644 --- a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj +++ b/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp2.2 + netcoreapp3.0 diff --git a/build/dependencies.props b/build/dependencies.props index 9ab630773a..719ea4d5a2 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -5,58 +5,58 @@ 0.10.13 3.1.0 - 3.0.0-preview-181108-06 - 3.0.0-alpha1-20181011.3 + 3.0.0-preview-181113-11 + 3.0.0-build-20181114.5 1.7.3.4 - 3.0.0-alpha1-10660 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-preview-181108-06 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-alpha1-10727 - 3.0.0-preview-181108-06 - 3.0.0-alpha1-10727 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-preview-181113-11 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-alpha1-10742 + 3.0.0-preview-181113-11 + 3.0.0-alpha1-10742 4.6.0-preview1-26907-04 3.0.0-preview-181109-02 3.0.0-preview-181109-02 3.0.0-preview-181109-02 3.0.0-alpha1-10727 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 3.0.0-preview-181108-06 - 2.2.0-rtm-27105-02 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview-181113-11 + 3.0.0-preview1-26907-05 15.6.1 4.10.0 2.0.3 diff --git a/build/publish-apps.ps1 b/build/publish-apps.ps1 index a2d0062e79..6a45f50a0f 100644 --- a/build/publish-apps.ps1 +++ b/build/publish-apps.ps1 @@ -1,4 +1,4 @@ -param($RootDirectory = (Get-Location), $Framework = "netcoreapp2.2", $Runtime = "win7-x64", $CommitHash, $BranchName, $BuildNumber) +param($RootDirectory = (Get-Location), $Framework = "netcoreapp3.0", $Runtime = "win7-x64", $CommitHash, $BranchName, $BuildNumber) # De-Powershell the path $RootDirectory = (Convert-Path $RootDirectory) @@ -45,4 +45,4 @@ $Apps.Keys | ForEach-Object { } finally { Remove-Item $MetadataPath } -} \ No newline at end of file +} diff --git a/build/repo.props b/build/repo.props index 472d056854..16207d928b 100644 --- a/build/repo.props +++ b/build/repo.props @@ -19,6 +19,6 @@ - + diff --git a/clients/ts/FunctionalTests/FunctionalTests.csproj b/clients/ts/FunctionalTests/FunctionalTests.csproj index 06948653fc..1f2d67dfcd 100644 --- a/clients/ts/FunctionalTests/FunctionalTests.csproj +++ b/clients/ts/FunctionalTests/FunctionalTests.csproj @@ -1,7 +1,7 @@ - netcoreapp2.2 + netcoreapp3.0 True 2.8 diff --git a/clients/ts/FunctionalTests/package-lock.json b/clients/ts/FunctionalTests/package-lock.json index 98ea76c951..e2b24fb2bb 100644 --- a/clients/ts/FunctionalTests/package-lock.json +++ b/clients/ts/FunctionalTests/package-lock.json @@ -1827,12 +1827,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1847,17 +1849,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -1974,7 +1979,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -1986,6 +1992,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2000,6 +2007,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2007,12 +2015,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -2031,6 +2041,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -2111,7 +2122,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -2123,6 +2135,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -2244,6 +2257,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", diff --git a/clients/ts/FunctionalTests/scripts/run-tests.ts b/clients/ts/FunctionalTests/scripts/run-tests.ts index 7dd600eded..5ae55bad6c 100644 --- a/clients/ts/FunctionalTests/scripts/run-tests.ts +++ b/clients/ts/FunctionalTests/scripts/run-tests.ts @@ -191,7 +191,7 @@ function runJest(httpsUrl: string, httpUrl: string) { (async () => { try { - const serverPath = path.resolve(__dirname, "..", "bin", configuration, "netcoreapp2.2", "FunctionalTests.dll"); + const serverPath = path.resolve(__dirname, "..", "bin", configuration, "netcoreapp3.0", "FunctionalTests.dll"); debug(`Launching Functional Test Server: ${serverPath}`); let desiredServerUrl = "https://127.0.0.1:0;http://127.0.0.1:0"; diff --git a/clients/ts/common/package-lock.json b/clients/ts/common/package-lock.json index 8b3564efc7..7ad4e6a391 100644 --- a/clients/ts/common/package-lock.json +++ b/clients/ts/common/package-lock.json @@ -2601,7 +2601,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -3016,7 +3017,8 @@ "safe-buffer": { "version": "5.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3072,6 +3074,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3115,12 +3118,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, diff --git a/clients/ts/signalr-protocol-msgpack/package-lock.json b/clients/ts/signalr-protocol-msgpack/package-lock.json index 38c6007853..68493e002a 100644 --- a/clients/ts/signalr-protocol-msgpack/package-lock.json +++ b/clients/ts/signalr-protocol-msgpack/package-lock.json @@ -10,7 +10,7 @@ "integrity": "sha512-EiFdEaD7EQNFl4PDBvlbPlX4hV8rJhEKfFj58jkjqvj1gN6E1lShu24cXeWH/RQ5nf+/ei4WGp70xp2ubBaE5Q==", "dev": true, "requires": { - "@types/node": "8.5.5" + "@types/node": "*" } }, "@types/msgpack5": { @@ -19,7 +19,7 @@ "integrity": "sha512-E3wILUjTXONukpiI6tmqpLwf7eV3MVTdxpjz56FqNn7koMF/6sSPUh5TxMlwgoOhyeejxwVoNZUiDcdqChKkAw==", "dev": true, "requires": { - "@types/bl": "0.8.31" + "@types/bl": "*" } }, "@types/node": { @@ -39,8 +39,8 @@ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "requires": { - "readable-stream": "2.3.6", - "safe-buffer": "5.1.1" + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" } }, "buffer": { @@ -49,8 +49,8 @@ "integrity": "sha512-xXvjQhVNz50v2nPeoOsNqWCLGfiv4ji/gXZM28jnVwdLJxH4mFyqgqCKfaK9zf1KUbG6zTkjLOy7ou+jSMarGA==", "dev": true, "requires": { - "base64-js": "1.2.1", - "ieee754": "1.1.8" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" } }, "core-util-is": { @@ -79,10 +79,10 @@ "resolved": "https://registry.npmjs.org/msgpack5/-/msgpack5-4.0.2.tgz", "integrity": "sha512-rEIx0/KFtWGtqlF5D/NIMzOHDhm7AhIFzHR3/PLqMrXXbMKoSitDE/IDuTactlTjxEc0ScmHx/5qoH015uL7xA==", "requires": { - "bl": "1.2.2", - "inherits": "2.0.3", - "readable-stream": "2.3.6", - "safe-buffer": "5.1.1" + "bl": "^1.2.1", + "inherits": "^2.0.3", + "readable-stream": "^2.3.3", + "safe-buffer": "^5.1.1" } }, "process-nextick-args": { @@ -95,13 +95,13 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "safe-buffer": { @@ -114,7 +114,7 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "util-deprecate": { diff --git a/clients/ts/signalr/package-lock.json b/clients/ts/signalr/package-lock.json index 8d1c148cee..9bedb9db53 100644 --- a/clients/ts/signalr/package-lock.json +++ b/clients/ts/signalr/package-lock.json @@ -157,7 +157,7 @@ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", "requires": { - "original": "1.0.2" + "original": "^1.0.0" } }, "extend": { @@ -291,7 +291,7 @@ "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", "requires": { - "url-parse": "1.4.3" + "url-parse": "^1.4.3" } }, "performance-now": { @@ -404,8 +404,8 @@ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.3.tgz", "integrity": "sha512-rh+KuAW36YKo0vClhQzLLveoj8FwPJNu65xLb7Mrt+eZht0IPT0IXgSv8gcMegZ6NvjJUALf6Mf25POlMwD1Fw==", "requires": { - "querystringify": "2.0.0", - "requires-port": "1.0.0" + "querystringify": "^2.0.0", + "requires-port": "^1.0.0" } }, "uuid": { @@ -428,7 +428,7 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-6.0.0.tgz", "integrity": "sha512-c2UlYcAZp1VS8AORtpq6y4RJIkJ9dQz18W32SpR/qXGfLDZ2jU4y4wKvvZwqbi7U6gxFQTeE+urMbXU/tsDy4w==", "requires": { - "async-limiter": "1.0.0" + "async-limiter": "~1.0.0" } } } diff --git a/korebuild-lock.txt b/korebuild-lock.txt index b886680b23..3400cb92d8 100644 --- a/korebuild-lock.txt +++ b/korebuild-lock.txt @@ -1,2 +1,2 @@ -version:3.0.0-alpha1-20181011.3 -commithash:e7569d931e994629267ab2646e9926140962b4ac +version:3.0.0-build-20181114.5 +commithash:880e9a204d4ee4a18dfd83c9fb05a192a28bca60 diff --git a/samples/ClientSample/ClientSample.csproj b/samples/ClientSample/ClientSample.csproj index b38755fe73..7449e1e91a 100644 --- a/samples/ClientSample/ClientSample.csproj +++ b/samples/ClientSample/ClientSample.csproj @@ -1,7 +1,7 @@  - netcoreapp2.2;net461 + netcoreapp3.0;net461 false Exe diff --git a/samples/ClientSample/Tcp/SocketReceiver.cs b/samples/ClientSample/Tcp/SocketReceiver.cs index f8e5d87b61..b5d664dbc9 100644 --- a/samples/ClientSample/Tcp/SocketReceiver.cs +++ b/samples/ClientSample/Tcp/SocketReceiver.cs @@ -22,7 +22,7 @@ namespace ClientSample public SocketAwaitable ReceiveAsync(Memory buffer) { -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 _eventArgs.SetBuffer(buffer); #else var segment = buffer.GetArray(); diff --git a/samples/ClientSample/Tcp/SocketSender.cs b/samples/ClientSample/Tcp/SocketSender.cs index 49a44fbb27..13bdbd1e5a 100644 --- a/samples/ClientSample/Tcp/SocketSender.cs +++ b/samples/ClientSample/Tcp/SocketSender.cs @@ -32,7 +32,7 @@ namespace ClientSample return SendAsync(buffers.First); } -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 if (!_eventArgs.MemoryBuffer.Equals(Memory.Empty)) #else if (_eventArgs.Buffer != null) @@ -59,7 +59,7 @@ namespace ClientSample _eventArgs.BufferList = null; } -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 _eventArgs.SetBuffer(MemoryMarshal.AsMemory(memory)); #else var segment = memory.GetArray(); diff --git a/samples/JwtClientSample/JwtClientSample.csproj b/samples/JwtClientSample/JwtClientSample.csproj index 7746780816..5cc83d46b2 100644 --- a/samples/JwtClientSample/JwtClientSample.csproj +++ b/samples/JwtClientSample/JwtClientSample.csproj @@ -1,7 +1,7 @@  - netcoreapp2.2 + netcoreapp3.0 false Exe diff --git a/samples/JwtSample/JwtSample.csproj b/samples/JwtSample/JwtSample.csproj index dfadf14bef..8e7b28a97b 100644 --- a/samples/JwtSample/JwtSample.csproj +++ b/samples/JwtSample/JwtSample.csproj @@ -1,7 +1,7 @@  - netcoreapp2.2 + netcoreapp3.0 diff --git a/samples/SignalRSamples/SignalRSamples.csproj b/samples/SignalRSamples/SignalRSamples.csproj index 5a93bdd381..15d52e1209 100644 --- a/samples/SignalRSamples/SignalRSamples.csproj +++ b/samples/SignalRSamples/SignalRSamples.csproj @@ -1,7 +1,7 @@  - netcoreapp2.2;net461 + netcoreapp3.0 false diff --git a/samples/SocialWeather/SocialWeather.csproj b/samples/SocialWeather/SocialWeather.csproj index e96e794705..b1113d58bb 100644 --- a/samples/SocialWeather/SocialWeather.csproj +++ b/samples/SocialWeather/SocialWeather.csproj @@ -1,7 +1,7 @@  - netcoreapp2.2;net461 + netcoreapp3.0 false diff --git a/samples/WebSocketSample/WebSocketSample.csproj b/samples/WebSocketSample/WebSocketSample.csproj index 8227ddf127..d63209836c 100644 --- a/samples/WebSocketSample/WebSocketSample.csproj +++ b/samples/WebSocketSample/WebSocketSample.csproj @@ -1,7 +1,7 @@  - netcoreapp2.2;net461 + netcoreapp3.0 Exe false diff --git a/src/Common/MemoryBufferWriter.cs b/src/Common/MemoryBufferWriter.cs index e13f2be3f7..95d3e2f375 100644 --- a/src/Common/MemoryBufferWriter.cs +++ b/src/Common/MemoryBufferWriter.cs @@ -293,7 +293,7 @@ namespace Microsoft.AspNetCore.Internal } } -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 public override void Write(ReadOnlySpan span) { if (_currentSegment != null && span.TryCopyTo(_currentSegment.AsSpan(_position))) diff --git a/src/Common/PipeWriterStream.cs b/src/Common/PipeWriterStream.cs index 8c39ca46fb..10bfa18b96 100644 --- a/src/Common/PipeWriterStream.cs +++ b/src/Common/PipeWriterStream.cs @@ -60,7 +60,7 @@ namespace System.IO.Pipelines return WriteCoreAsync(buffer.AsMemory(offset, count), cancellationToken).AsTask(); } -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 public override ValueTask WriteAsync(ReadOnlyMemory source, CancellationToken cancellationToken = default) { return WriteCoreAsync(source, cancellationToken); diff --git a/src/Common/StreamExtensions.cs b/src/Common/StreamExtensions.cs index 8c971ede0d..9601fc2add 100644 --- a/src/Common/StreamExtensions.cs +++ b/src/Common/StreamExtensions.cs @@ -15,7 +15,7 @@ namespace System.IO { if (buffer.IsSingleSegment) { -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 return stream.WriteAsync(buffer.First, cancellationToken); #else var isArray = MemoryMarshal.TryGetArray(buffer.First, out var arraySegment); @@ -33,7 +33,7 @@ namespace System.IO var position = buffer.Start; while (buffer.TryGet(ref position, out var segment)) { -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 await stream.WriteAsync(segment, cancellationToken); #else var isArray = MemoryMarshal.TryGetArray(segment, out var arraySegment); diff --git a/src/Common/Utf8BufferTextReader.cs b/src/Common/Utf8BufferTextReader.cs index f78c878b1d..66af65c237 100644 --- a/src/Common/Utf8BufferTextReader.cs +++ b/src/Common/Utf8BufferTextReader.cs @@ -72,7 +72,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal var source = _utf8Buffer.First.Span; var bytesUsed = 0; var charsUsed = 0; -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 var destination = new Span(buffer, index, count); _decoder.Convert(source, destination, false, out bytesUsed, out charsUsed, out var completed); #else diff --git a/src/Common/Utf8BufferTextWriter.cs b/src/Common/Utf8BufferTextWriter.cs index eb57dc2e36..d60caf3bda 100644 --- a/src/Common/Utf8BufferTextWriter.cs +++ b/src/Common/Utf8BufferTextWriter.cs @@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Internal // this should be an exceptional case var bytesUsed = 0; var charsUsed = 0; -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 _encoder.Convert(new Span(&value, 1), destination, false, out charsUsed, out bytesUsed, out _); #else fixed (byte* destinationBytes = &MemoryMarshal.GetReference(destination)) @@ -167,7 +167,7 @@ namespace Microsoft.AspNetCore.Internal var bytesUsed = 0; var charsUsed = 0; -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 _encoder.Convert(buffer, destination, false, out charsUsed, out bytesUsed, out _); #else unsafe diff --git a/src/Common/WebSocketExtensions.cs b/src/Common/WebSocketExtensions.cs index 63eb7e62b3..a15ad78891 100644 --- a/src/Common/WebSocketExtensions.cs +++ b/src/Common/WebSocketExtensions.cs @@ -13,7 +13,7 @@ namespace System.Net.WebSockets { public static ValueTask SendAsync(this WebSocket webSocket, ReadOnlySequence buffer, WebSocketMessageType webSocketMessageType, CancellationToken cancellationToken = default) { -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 if (buffer.IsSingleSegment) { return webSocket.SendAsync(buffer.First, webSocketMessageType, endOfMessage: true, cancellationToken); @@ -41,7 +41,7 @@ namespace System.Net.WebSockets var position = buffer.Start; while (buffer.TryGet(ref position, out var segment)) { -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 await webSocket.SendAsync(segment, webSocketMessageType, endOfMessage: false, cancellationToken); #else var isArray = MemoryMarshal.TryGetArray(segment, out var arraySegment); @@ -51,7 +51,7 @@ namespace System.Net.WebSockets } // Empty end of message frame -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 await webSocket.SendAsync(Memory.Empty, webSocketMessageType, endOfMessage: true, cancellationToken); #else await webSocket.SendAsync(new ArraySegment(Array.Empty()), webSocketMessageType, endOfMessage: true, cancellationToken); diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.cs b/src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.cs index 80f9c88d54..bd9010f9b7 100644 --- a/src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.cs +++ b/src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.cs @@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client private static readonly Task _noAccessToken = Task.FromResult(null); private static readonly TimeSpan HttpClientTimeout = TimeSpan.FromSeconds(120); -#if !NETCOREAPP2_2 +#if !NETCOREAPP3_0 private static readonly Version Windows8Version = new Version(6, 2); #endif @@ -573,7 +573,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client private static bool IsWebSocketsSupported() { -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 // .NET Core 2.1 and above has a managed implementation return true; #else diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.cs b/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.cs index 054e32c5bc..cb7ed9f06c 100644 --- a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.cs +++ b/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.cs @@ -196,7 +196,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal { while (true) { -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 var result = await socket.ReceiveAsync(Memory.Empty, CancellationToken.None); if (result.MessageType == WebSocketMessageType.Close) @@ -212,7 +212,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal } #endif var memory = _application.Output.GetMemory(); -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 // Because we checked the CloseStatus from the 0 byte read above, we don't need to check again after reading var receiveResult = await socket.ReceiveAsync(memory, CancellationToken.None); #else @@ -222,7 +222,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal // Exceptions are handled above where the send and receive tasks are being run. var receiveResult = await socket.ReceiveAsync(arraySegment, CancellationToken.None); #endif - // Need to check again for NetCoreApp2.2 because a close can happen between a 0-byte read and the actual read + // Need to check again for netcoreapp3.0 because a close can happen between a 0-byte read and the actual read if (receiveResult.MessageType == WebSocketMessageType.Close) { Log.WebSocketClosed(_logger, _webSocket.CloseStatus); diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Microsoft.AspNetCore.Http.Connections.Client.csproj b/src/Microsoft.AspNetCore.Http.Connections.Client/Microsoft.AspNetCore.Http.Connections.Client.csproj index 2c330f24b5..8a018490d4 100644 --- a/src/Microsoft.AspNetCore.Http.Connections.Client/Microsoft.AspNetCore.Http.Connections.Client.csproj +++ b/src/Microsoft.AspNetCore.Http.Connections.Client/Microsoft.AspNetCore.Http.Connections.Client.csproj @@ -2,7 +2,7 @@ Client for ASP.NET Core Connection Handlers - netstandard2.0;netcoreapp2.2 + netstandard2.0;netcoreapp3.0 diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.cs b/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.cs index f7700701e9..8a14478831 100644 --- a/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.cs +++ b/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.cs @@ -144,7 +144,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal.Transports { while (!token.IsCancellationRequested) { -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 // Do a 0 byte read so that idle connections don't allocate a buffer when waiting for a read var result = await socket.ReceiveAsync(Memory.Empty, token); @@ -155,7 +155,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal.Transports #endif var memory = _application.Output.GetMemory(); -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 var receiveResult = await socket.ReceiveAsync(memory, token); #else var isArray = MemoryMarshal.TryGetArray(memory, out var arraySegment); @@ -164,7 +164,7 @@ namespace Microsoft.AspNetCore.Http.Connections.Internal.Transports // Exceptions are handled above where the send and receive tasks are being run. var receiveResult = await socket.ReceiveAsync(arraySegment, token); #endif - // Need to check again for NetCoreApp2.2 because a close can happen between a 0-byte read and the actual read + // Need to check again for netcoreapp3.0 because a close can happen between a 0-byte read and the actual read if (receiveResult.MessageType == WebSocketMessageType.Close) { return; diff --git a/src/Microsoft.AspNetCore.Http.Connections/Microsoft.AspNetCore.Http.Connections.csproj b/src/Microsoft.AspNetCore.Http.Connections/Microsoft.AspNetCore.Http.Connections.csproj index 1cc7e47c44..38f677b784 100644 --- a/src/Microsoft.AspNetCore.Http.Connections/Microsoft.AspNetCore.Http.Connections.csproj +++ b/src/Microsoft.AspNetCore.Http.Connections/Microsoft.AspNetCore.Http.Connections.csproj @@ -2,7 +2,7 @@ Components for providing real-time bi-directional communication across the Web. - netstandard2.0;netcoreapp2.2 + netstandard2.0;netcoreapp3.0 diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj b/src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj index 8130586cf1..6e1fb9d892 100644 --- a/src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj +++ b/src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj @@ -2,7 +2,7 @@ Common serialiation primitives for SignalR Clients Servers - netstandard2.0;netcoreapp2.2 + netstandard2.0;netcoreapp3.0 Microsoft.AspNetCore.SignalR true @@ -23,4 +23,4 @@ - \ No newline at end of file + diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Microsoft.AspNetCore.SignalR.Core.csproj b/src/Microsoft.AspNetCore.SignalR.Core/Microsoft.AspNetCore.SignalR.Core.csproj index 012aca906c..98856f40d9 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/Microsoft.AspNetCore.SignalR.Core.csproj +++ b/src/Microsoft.AspNetCore.SignalR.Core/Microsoft.AspNetCore.SignalR.Core.csproj @@ -2,7 +2,7 @@ Real-time communication framework for ASP.NET Core. - netstandard2.0 + netcoreapp3.0 Microsoft.AspNetCore.SignalR diff --git a/src/Microsoft.AspNetCore.SignalR.Specification.Tests/Microsoft.AspNetCore.SignalR.Specification.Tests.csproj b/src/Microsoft.AspNetCore.SignalR.Specification.Tests/Microsoft.AspNetCore.SignalR.Specification.Tests.csproj index c5745d4d84..7cb0c7c64c 100644 --- a/src/Microsoft.AspNetCore.SignalR.Specification.Tests/Microsoft.AspNetCore.SignalR.Specification.Tests.csproj +++ b/src/Microsoft.AspNetCore.SignalR.Specification.Tests/Microsoft.AspNetCore.SignalR.Specification.Tests.csproj @@ -2,9 +2,9 @@ Tests for users to verify their own implementations of SignalR types - netcoreapp2.2;net461 + netcoreapp3.0 - + @@ -15,7 +15,7 @@ - + diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj b/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj index f1fabc764b..45ff7d501b 100644 --- a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj +++ b/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj @@ -2,7 +2,7 @@ Provides scale-out support for ASP.NET Core SignalR using a Redis server and the StackExchange.Redis client. - netstandard2.0 + netcoreapp3.0 diff --git a/src/Microsoft.AspNetCore.SignalR/Microsoft.AspNetCore.SignalR.csproj b/src/Microsoft.AspNetCore.SignalR/Microsoft.AspNetCore.SignalR.csproj index 885b476430..3ca8671d7c 100644 --- a/src/Microsoft.AspNetCore.SignalR/Microsoft.AspNetCore.SignalR.csproj +++ b/src/Microsoft.AspNetCore.SignalR/Microsoft.AspNetCore.SignalR.csproj @@ -1,7 +1,7 @@  Components for providing real-time bi-directional communication across the Web. - netstandard2.0 + netcoreapp3.0 diff --git a/test/Directory.Build.props b/test/Directory.Build.props index dfd1b2c370..ae9c6b5322 100644 --- a/test/Directory.Build.props +++ b/test/Directory.Build.props @@ -2,9 +2,6 @@ - netcoreapp2.2 - $(DeveloperBuildTestTfms) - $(StandardTestTfms);net461 win7-x86 diff --git a/test/Microsoft.AspNetCore.Http.Connections.Tests/Microsoft.AspNetCore.Http.Connections.Tests.csproj b/test/Microsoft.AspNetCore.Http.Connections.Tests/Microsoft.AspNetCore.Http.Connections.Tests.csproj index b161cd535b..2b4c82d26b 100644 --- a/test/Microsoft.AspNetCore.Http.Connections.Tests/Microsoft.AspNetCore.Http.Connections.Tests.csproj +++ b/test/Microsoft.AspNetCore.Http.Connections.Tests/Microsoft.AspNetCore.Http.Connections.Tests.csproj @@ -1,8 +1,7 @@  - $(StandardTestTfms) - win7-x86 + netcoreapp3.0 diff --git a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj b/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj index bc1254feac..50cbc55270 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj +++ b/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj @@ -1,7 +1,7 @@  - $(StandardTestTfms) + netcoreapp3.0 diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/Microsoft.AspNetCore.SignalR.Client.Tests.csproj b/test/Microsoft.AspNetCore.SignalR.Client.Tests/Microsoft.AspNetCore.SignalR.Client.Tests.csproj index 43229b1bea..b9e8663cf9 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/Microsoft.AspNetCore.SignalR.Client.Tests.csproj +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/Microsoft.AspNetCore.SignalR.Client.Tests.csproj @@ -1,7 +1,7 @@  - $(StandardTestTfms) + netcoreapp3.0 diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MemoryBufferWriterTests.cs b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MemoryBufferWriterTests.cs index d8f51a80e3..7cd455a009 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MemoryBufferWriterTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MemoryBufferWriterTests.cs @@ -358,7 +358,7 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol } } -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 [Fact] public void WriteSpanWorksAtNonZeroOffset() { diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Microsoft.AspNetCore.SignalR.Common.Tests.csproj b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Microsoft.AspNetCore.SignalR.Common.Tests.csproj index 39827c10d7..0a279ffb0d 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Microsoft.AspNetCore.SignalR.Common.Tests.csproj +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Microsoft.AspNetCore.SignalR.Common.Tests.csproj @@ -1,7 +1,7 @@  - $(StandardTestTfms) + netcoreapp3.0 @@ -20,4 +20,4 @@ - \ No newline at end of file + diff --git a/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests.csproj b/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests.csproj index ef017f8ba8..ddb63a904f 100644 --- a/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests.csproj +++ b/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests.csproj @@ -1,7 +1,7 @@  - $(StandardTestTfms) + netcoreapp3.0 diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/Microsoft.AspNetCore.SignalR.Tests.Utils.csproj b/test/Microsoft.AspNetCore.SignalR.Tests.Utils/Microsoft.AspNetCore.SignalR.Tests.Utils.csproj index 976041ab7c..211e6824e7 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/Microsoft.AspNetCore.SignalR.Tests.Utils.csproj +++ b/test/Microsoft.AspNetCore.SignalR.Tests.Utils/Microsoft.AspNetCore.SignalR.Tests.Utils.csproj @@ -1,7 +1,7 @@  - $(StandardTestTfms) + netcoreapp3.0 Microsoft.AspNetCore.SignalR.Tests $(DefineConstants);TESTUTILS diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestHelpers.cs b/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestHelpers.cs index be8f1e90c5..10473ad9ab 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestHelpers.cs +++ b/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestHelpers.cs @@ -10,7 +10,7 @@ namespace Microsoft.AspNetCore.SignalR.Tests { public static bool IsWebSocketsSupported() { -#if NETCOREAPP2_2 +#if NETCOREAPP3_0 // .NET Core 2.1 and greater has sockets return true; #else diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj b/test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj index 0796e5430a..fcb8415080 100644 --- a/test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj +++ b/test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj @@ -1,20 +1,9 @@  - $(StandardTestTfms) - - - true - win7-x86 + netcoreapp3.0 - - - - PreserveNewest From 4cbabea501187d2f7f8b42dd4804421d1ab34a27 Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Fri, 16 Nov 2018 19:54:24 -0800 Subject: [PATCH 24/30] Dispose WebSocket if StartAsync fails (#3311) --- .../Internal/WebSocketsTransport.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.cs b/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.cs index cb7ed9f06c..4fe1e61b73 100644 --- a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.cs +++ b/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.cs @@ -119,7 +119,15 @@ namespace Microsoft.AspNetCore.Http.Connections.Client.Internal Log.StartTransport(_logger, transferFormat, resolvedUrl); - await _webSocket.ConnectAsync(resolvedUrl, CancellationToken.None); + try + { + await _webSocket.ConnectAsync(resolvedUrl, CancellationToken.None); + } + catch + { + _webSocket.Dispose(); + throw; + } Log.StartedTransport(_logger); From a5884d3ad72bc87c0150377240c2a9fbd1abcd66 Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Mon, 19 Nov 2018 09:44:47 -0800 Subject: [PATCH 25/30] Reenable logging for SSE tests (#3320) --- ...HttpConnectionTests.ConnectionLifecycle.cs | 32 ++++++++++++------- .../ServerSentEventsTransportTests.cs | 11 +++++-- version.props | 2 +- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.ConnectionLifecycle.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.ConnectionLifecycle.cs index 73278bfd3d..ae73e83aec 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.ConnectionLifecycle.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.ConnectionLifecycle.cs @@ -322,23 +322,31 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests [Fact] public async Task SSEWontStartIfSuccessfulConnectionIsNotEstablished() { - // TODO: Add logging https://github.com/aspnet/SignalR/issues/2879 - var httpHandler = new TestHttpMessageHandler(); - - httpHandler.OnGet("/?id=00000000-0000-0000-0000-000000000000", (_, __) => + bool ExpectedErrors(WriteContext writeContext) { - return Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.InternalServerError)); - }); + return writeContext.LoggerName == typeof(HttpConnection).FullName && + writeContext.EventId.Name == "ErrorStartingTransport"; + } - var sse = new ServerSentEventsTransport(new HttpClient(httpHandler)); + using (StartVerifiableLog(expectedErrorsFilter: ExpectedErrors)) + { + var httpHandler = new TestHttpMessageHandler(); - await WithConnectionAsync( - CreateConnection(httpHandler, transport: sse), - async (connection) => + httpHandler.OnGet("/?id=00000000-0000-0000-0000-000000000000", (_, __) => { - await Assert.ThrowsAsync( - () => connection.StartAsync(TransferFormat.Text).OrTimeout()); + return Task.FromResult(ResponseUtils.CreateResponse(HttpStatusCode.InternalServerError)); }); + + var sse = new ServerSentEventsTransport(new HttpClient(httpHandler), LoggerFactory); + + await WithConnectionAsync( + CreateConnection(httpHandler, loggerFactory: LoggerFactory, transport: sse), + async (connection) => + { + await Assert.ThrowsAsync( + () => connection.StartAsync(TransferFormat.Text).OrTimeout()); + }); + } } [Fact] diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsTransportTests.cs b/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsTransportTests.cs index ab497f6ab3..421e1cef61 100644 --- a/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsTransportTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsTransportTests.cs @@ -12,6 +12,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Http.Connections.Client.Internal; using Microsoft.AspNetCore.SignalR.Tests; +using Microsoft.Extensions.Logging.Testing; using Moq; using Moq.Protected; using Xunit; @@ -156,7 +157,12 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests [Fact] public async Task SSETransportStopsWithErrorIfSendingMessageFails() { - // TODO: Add logging https://github.com/aspnet/SignalR/issues/2879 + bool ExpectedErrors(WriteContext writeContext) + { + return writeContext.LoggerName == typeof(ServerSentEventsTransport).FullName && + writeContext.EventId.Name == "ErrorSending"; + } + var eventStreamTcs = new TaskCompletionSource(); var copyToAsyncTcs = new TaskCompletionSource(); @@ -185,8 +191,9 @@ namespace Microsoft.AspNetCore.SignalR.Client.Tests }); using (var httpClient = new HttpClient(mockHttpHandler.Object)) + using (StartVerifiableLog(expectedErrorsFilter: ExpectedErrors)) { - var sseTransport = new ServerSentEventsTransport(httpClient); + var sseTransport = new ServerSentEventsTransport(httpClient, LoggerFactory); await sseTransport.StartAsync( new Uri("http://fakeuri.org"), TransferFormat.Text).OrTimeout(); diff --git a/version.props b/version.props index c7f960fb01..062be0cd41 100644 --- a/version.props +++ b/version.props @@ -2,7 +2,7 @@ 3.0.0 alpha1 - 1.0.0 + 3.0.0 $(VersionPrefix) $(VersionPrefix)-$(VersionSuffix)-final t000 From 86787f1c2895dfcff62a569d00f26e5443576e7c Mon Sep 17 00:00:00 2001 From: Mikael Mengistu Date: Mon, 19 Nov 2018 10:32:43 -0800 Subject: [PATCH 26/30] [Java] Change StreamItem to have items instead of results (#3317) --- .../microsoft/signalr/InvocationRequest.java | 4 ++-- .../com/microsoft/signalr/JsonHubProtocol.java | 4 +--- .../java/com/microsoft/signalr/StreamItem.java | 10 +++++----- .../microsoft/signalr/HubConnectionTest.java | 18 +++++++++--------- .../com/microsoft/signalr/sample/Chat.java | 1 + 5 files changed, 18 insertions(+), 19 deletions(-) diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationRequest.java b/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationRequest.java index 1c936da663..7de8890db7 100644 --- a/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationRequest.java +++ b/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationRequest.java @@ -30,8 +30,8 @@ class InvocationRequest { } public void addItem(StreamItem streamItem) { - if (streamItem.getResult() != null) { - pendingCall.onNext(streamItem.getResult()); + if (streamItem.getItem() != null) { + pendingCall.onNext(streamItem.getItem()); } } diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/JsonHubProtocol.java b/clients/java/signalr/src/main/java/com/microsoft/signalr/JsonHubProtocol.java index b0005f8cd7..57bb5d1a7b 100644 --- a/clients/java/signalr/src/main/java/com/microsoft/signalr/JsonHubProtocol.java +++ b/clients/java/signalr/src/main/java/com/microsoft/signalr/JsonHubProtocol.java @@ -73,15 +73,13 @@ class JsonHubProtocol implements HubProtocol { error = reader.nextString(); break; case "result": + case "item": if (invocationId == null || binder.getReturnType(invocationId) == null) { resultToken = jsonParser.parse(reader); } else { result = gson.fromJson(reader, binder.getReturnType(invocationId)); } break; - case "item": - reader.skipValue(); - break; case "arguments": if (target != null) { boolean startedArray = false; diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamItem.java b/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamItem.java index e39941d04c..3b422daf46 100644 --- a/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamItem.java +++ b/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamItem.java @@ -6,19 +6,19 @@ package com.microsoft.signalr; final class StreamItem extends HubMessage { private final int type = HubMessageType.STREAM_ITEM.value; private final String invocationId; - private final Object result; + private final Object item; - public StreamItem(String invocationId, Object result) { + public StreamItem(String invocationId, Object item) { this.invocationId = invocationId; - this.result = result; + this.item = item; } public String getInvocationId() { return invocationId; } - public Object getResult() { - return result; + public Object getItem() { + return item; } @Override diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java b/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java index cab2ae0ecb..95f4e2c191 100644 --- a/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java +++ b/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java @@ -388,7 +388,7 @@ class HubConnectionTest { assertFalse(completed.get()); assertFalse(onNextCalled.get()); - mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"First\"}" + RECORD_SEPARATOR); + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"item\":\"First\"}" + RECORD_SEPARATOR); assertTrue(onNextCalled.get()); @@ -416,7 +416,7 @@ class HubConnectionTest { assertFalse(completed.get()); assertFalse(onNextCalled.get()); - mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"First\"}" + RECORD_SEPARATOR); + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"item\":\"First\"}" + RECORD_SEPARATOR); assertTrue(onNextCalled.get()); @@ -446,7 +446,7 @@ class HubConnectionTest { assertFalse(onErrorCalled.get()); assertFalse(onNextCalled.get()); - mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"First\"}" + RECORD_SEPARATOR); + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"item\":\"First\"}" + RECORD_SEPARATOR); assertTrue(onNextCalled.get()); @@ -474,8 +474,8 @@ class HubConnectionTest { assertEquals("{\"type\":4,\"invocationId\":\"1\",\"target\":\"echo\",\"arguments\":[\"message\"]}" + RECORD_SEPARATOR, mockTransport.getSentMessages()[1]); assertFalse(completed.get()); - mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"First\"}" + RECORD_SEPARATOR); - mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"Second\"}" + RECORD_SEPARATOR); + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"item\":\"First\"}" + RECORD_SEPARATOR); + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"item\":\"Second\"}" + RECORD_SEPARATOR); mockTransport.receiveMessage("{\"type\":3,\"invocationId\":\"1\",\"result\":\"null\"}" + RECORD_SEPARATOR); Iterator resultIterator = result.timeout(1000, TimeUnit.MILLISECONDS).blockingIterable().iterator(); @@ -545,10 +545,10 @@ class HubConnectionTest { assertEquals("{\"type\":4,\"invocationId\":\"1\",\"target\":\"echo\",\"arguments\":[\"message\"]}" + RECORD_SEPARATOR, mockTransport.getSentMessages()[1]); - mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"First\"}" + RECORD_SEPARATOR); + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"item\":\"First\"}" + RECORD_SEPARATOR); subscription.dispose(); - mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"Second\"}" + RECORD_SEPARATOR); + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"item\":\"Second\"}" + RECORD_SEPARATOR); assertEquals("First", result.timeout(1000, TimeUnit.MILLISECONDS).blockingLast()); } @@ -573,10 +573,10 @@ class HubConnectionTest { assertEquals("{\"type\":4,\"invocationId\":\"1\",\"target\":\"echo\",\"arguments\":[\"message\"]}" + RECORD_SEPARATOR, mockTransport.getSentMessages()[1]); assertFalse(completed.get()); - mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"First\"}" + RECORD_SEPARATOR); + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"item\":\"First\"}" + RECORD_SEPARATOR); subscription.dispose(); - mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"result\":\"Second\"}" + RECORD_SEPARATOR); + mockTransport.receiveMessage("{\"type\":2,\"invocationId\":\"1\",\"item\":\"Second\"}" + RECORD_SEPARATOR); mockTransport.receiveMessage("{\"type\":3,\"invocationId\":\"1\"}" + RECORD_SEPARATOR); assertTrue(completed.get()); diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/sample/Chat.java b/clients/java/signalr/src/test/java/com/microsoft/signalr/sample/Chat.java index 2e0990d70a..0acb379433 100644 --- a/clients/java/signalr/src/test/java/com/microsoft/signalr/sample/Chat.java +++ b/clients/java/signalr/src/test/java/com/microsoft/signalr/sample/Chat.java @@ -8,6 +8,7 @@ import java.util.Scanner; import com.microsoft.signalr.HubConnection; import com.microsoft.signalr.HubConnectionBuilder; + public class Chat { public static void main(String[] args) { System.out.println("Enter the URL of the SignalR Chat you want to join"); From 2c3ebd1648a480ca180c77f123a10f4dcc591c3b Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Mon, 19 Nov 2018 11:47:42 -0800 Subject: [PATCH 27/30] Update TFM for Http.Connections (#3323) --- .../Microsoft.AspNetCore.Http.Connections.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNetCore.Http.Connections/Microsoft.AspNetCore.Http.Connections.csproj b/src/Microsoft.AspNetCore.Http.Connections/Microsoft.AspNetCore.Http.Connections.csproj index 38f677b784..e72fe999b4 100644 --- a/src/Microsoft.AspNetCore.Http.Connections/Microsoft.AspNetCore.Http.Connections.csproj +++ b/src/Microsoft.AspNetCore.Http.Connections/Microsoft.AspNetCore.Http.Connections.csproj @@ -2,7 +2,7 @@ Components for providing real-time bi-directional communication across the Web. - netstandard2.0;netcoreapp3.0 + netcoreapp3.0 From dde73d0b8ac4284ea8ca926a7441a0734302899d Mon Sep 17 00:00:00 2001 From: Nate McMaster Date: Tue, 20 Nov 2018 15:17:28 -0800 Subject: [PATCH 28/30] Set local builds to build as 3.0.0-dev (#3327) --- version.props | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/version.props b/version.props index 062be0cd41..32c7a64b55 100644 --- a/version.props +++ b/version.props @@ -1,16 +1,7 @@  3.0.0 - alpha1 - 3.0.0 - $(VersionPrefix) - $(VersionPrefix)-$(VersionSuffix)-final - t000 - $(JavaVersionPrefix)-$(VersionSuffix)-$(BuildNumber) - $(JavaVersionPrefix)-$(VersionSuffix) - $(JavaVersionPrefix)-$(VersionSuffix)-final - a- - $(FeatureBranchVersionPrefix)$(VersionSuffix)-$([System.Text.RegularExpressions.Regex]::Replace('$(FeatureBranchVersionSuffix)', '[^\w-]', '-')) - $(VersionSuffix)-$(BuildNumber) + dev + $(VersionPrefix)-$(VersionSuffix) From c852bdcc332ffb998ec6a5b226e35d5e74d24009 Mon Sep 17 00:00:00 2001 From: BrennanConroy Date: Wed, 21 Nov 2018 11:47:39 -0800 Subject: [PATCH 29/30] Avoid zero-byte send in WebSockets (#3326) --- src/Common/WebSocketExtensions.cs | 16 +++++++--- .../WebSocketsTests.cs | 31 +++++++++++++++++++ 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/Common/WebSocketExtensions.cs b/src/Common/WebSocketExtensions.cs index a15ad78891..fedb954296 100644 --- a/src/Common/WebSocketExtensions.cs +++ b/src/Common/WebSocketExtensions.cs @@ -39,22 +39,28 @@ namespace System.Net.WebSockets private static async ValueTask SendMultiSegmentAsync(WebSocket webSocket, ReadOnlySequence buffer, WebSocketMessageType webSocketMessageType, CancellationToken cancellationToken = default) { var position = buffer.Start; + // Get a segment before the loop so we can be one segment behind while writing + // This allows us to do a non-zero byte write for the endOfMessage = true send + buffer.TryGet(ref position, out var prevSegment); while (buffer.TryGet(ref position, out var segment)) { #if NETCOREAPP3_0 - await webSocket.SendAsync(segment, webSocketMessageType, endOfMessage: false, cancellationToken); + await webSocket.SendAsync(prevSegment, webSocketMessageType, endOfMessage: false, cancellationToken); #else - var isArray = MemoryMarshal.TryGetArray(segment, out var arraySegment); + var isArray = MemoryMarshal.TryGetArray(prevSegment, out var arraySegment); Debug.Assert(isArray); await webSocket.SendAsync(arraySegment, webSocketMessageType, endOfMessage: false, cancellationToken); #endif + prevSegment = segment; } - // Empty end of message frame + // End of message frame #if NETCOREAPP3_0 - await webSocket.SendAsync(Memory.Empty, webSocketMessageType, endOfMessage: true, cancellationToken); + await webSocket.SendAsync(prevSegment, webSocketMessageType, endOfMessage: true, cancellationToken); #else - await webSocket.SendAsync(new ArraySegment(Array.Empty()), webSocketMessageType, endOfMessage: true, cancellationToken); + var isArrayEnd = MemoryMarshal.TryGetArray(prevSegment, out var arraySegmentEnd); + Debug.Assert(isArrayEnd); + await webSocket.SendAsync(arraySegmentEnd, webSocketMessageType, endOfMessage: true, cancellationToken); #endif } } diff --git a/test/Microsoft.AspNetCore.Http.Connections.Tests/WebSocketsTests.cs b/test/Microsoft.AspNetCore.Http.Connections.Tests/WebSocketsTests.cs index 0af2f65812..8068853f17 100644 --- a/test/Microsoft.AspNetCore.Http.Connections.Tests/WebSocketsTests.cs +++ b/test/Microsoft.AspNetCore.Http.Connections.Tests/WebSocketsTests.cs @@ -396,5 +396,36 @@ namespace Microsoft.AspNetCore.Http.Connections.Tests } } } + + [Fact] + public async Task MultiSegmentSendWillNotSendEmptyEndOfMessageFrame() + { + using (var feature = new TestWebSocketConnectionFeature()) + { + var serverSocket = await feature.AcceptAsync(); + var sequence = ReadOnlySequenceFactory.CreateSegments(new byte[] { 1 }, new byte[] { 15 }); + Assert.False(sequence.IsSingleSegment); + + await serverSocket.SendAsync(sequence, WebSocketMessageType.Text); + + // Run the client socket + var client = feature.Client.ExecuteAndCaptureFramesAsync(); + + await serverSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", default); + + var messages = await client.OrTimeout(); + Assert.Equal(2, messages.Received.Count); + + // First message: 1 byte, endOfMessage false + Assert.Single(messages.Received[0].Buffer); + Assert.Equal(1, messages.Received[0].Buffer[0]); + Assert.False(messages.Received[0].EndOfMessage); + + // Second message: 1 byte, endOfMessage true + Assert.Single(messages.Received[1].Buffer); + Assert.Equal(15, messages.Received[1].Buffer[0]); + Assert.True(messages.Received[1].EndOfMessage); + } + } } } From c88b650c5a98970d2541c3be0c8751767538cddb Mon Sep 17 00:00:00 2001 From: Ryan Brandenburg Date: Tue, 27 Nov 2018 15:29:29 -0800 Subject: [PATCH 30/30] Reorganize source code in preparation to move into aspnet/AspNetCore Prior to reorganization, this source code was found in https://github.com/aspnet/SignalR/tree/c852bdcc332ffb998ec6a5b226e35d5e74d24009 --- .gitattributes | 58 ---- .github/ISSUE_TEMPLATE.md | 19 -- .travis.yml | 29 -- .vscode/launch.json | 41 --- .vsts-pipelines/builds/ci-internal.yml | 19 -- .vsts-pipelines/builds/ci-public.yml | 21 -- .../builds/slow-tests-internal.yml | 46 ---- CONTRIBUTING.md | 4 - LICENSE.txt | 201 -------------- NuGet.config | 7 - build.cmd | 2 - build.sh | 8 - clients/cpp/test/gtest/googletest | 1 - korebuild-lock.txt | 2 - korebuild.json | 10 - run.cmd | 2 - run.ps1 | 209 -------------- run.sh | 256 ------------------ .gitignore => src/SignalR/.gitignore | 0 .gitmodules => src/SignalR/.gitmodules | 0 .../SignalR/Directory.Build.props | 0 .../SignalR/Directory.Build.targets | 0 .../SignalR/NuGetPackageVerifier.json | 0 README.md => src/SignalR/README.md | 0 SignalR.sln => src/SignalR/SignalR.sln | 0 .../SignalR/THIRD-PARTY-NOTICES | 0 .../BenchmarkServer/BenchmarkServer.csproj | 0 .../BenchmarkServer/Hubs/EchoHub.cs | 0 .../benchmarkapps}/BenchmarkServer/Program.cs | 0 .../benchmarkapps}/BenchmarkServer/README.md | 0 .../benchmarkapps}/BenchmarkServer/Startup.cs | 0 .../BenchmarkServer/signalr.json | 0 .../SignalR/benchmarkapps}/Crankier/Agent.cs | 0 .../Crankier/AgentHeartbeatInformation.cs | 0 .../benchmarkapps}/Crankier/AgentReceiver.cs | 0 .../benchmarkapps}/Crankier/AgentSender.cs | 0 .../benchmarkapps}/Crankier/AgentWorker.cs | 0 .../SignalR/benchmarkapps}/Crankier/Client.cs | 0 .../Crankier/Commands/AgentCommand.cs | 0 .../Crankier/Commands/CommandLineUtilities.cs | 0 .../Crankier/Commands/Defaults.cs | 0 .../Crankier/Commands/LocalCommand.cs | 0 .../Crankier/Commands/WorkerCommand.cs | 0 .../Crankier/ConnectionState.cs | 0 .../benchmarkapps}/Crankier/Crankier.csproj | 0 .../SignalR/benchmarkapps}/Crankier/IAgent.cs | 0 .../benchmarkapps}/Crankier/IRunner.cs | 0 .../benchmarkapps}/Crankier/IWorker.cs | 0 .../benchmarkapps}/Crankier/Message.cs | 0 .../benchmarkapps}/Crankier/Program.cs | 0 .../SignalR/benchmarkapps}/Crankier/Runner.cs | 0 .../Crankier/StatusInformation.cs | 0 .../SignalR/benchmarkapps}/Crankier/Worker.cs | 0 .../Crankier/WorkerHeartbeatInformation.cs | 0 .../benchmarkapps}/Crankier/WorkerReceiver.cs | 0 .../benchmarkapps}/Crankier/WorkerSender.cs | 0 .../AssemblyInfo.cs | 0 .../BroadcastBenchmark.cs | 0 .../DefaultHubActivatorBenchmark.cs | 0 .../DefaultHubDispatcherBenchmark.cs | 0 .../DefaultHubLifetimeManagerBenchmark.cs | 0 .../HandshakeProtocolBenchmark.cs | 0 .../HubConnectionContextBenchmark.cs | 0 .../HubConnectionReceiveBenchmark.cs | 0 .../HubConnectionSendBenchmark.cs | 0 .../HubConnectionStartBenchmark.cs | 0 .../HubProtocolBenchmark.cs | 0 .../MessageParserBenchmark.cs | 0 ....AspNetCore.SignalR.Microbenchmarks.csproj | 0 .../NegotiateProtocolBenchmark.cs | 0 .../RedisHubLifetimeManagerBenchmark.cs | 0 .../RedisProtocolBenchmark.cs | 0 .../ServerSentEventsBenchmark.cs | 0 .../Shared/TestConnectionContext.cs | 0 .../Shared/TestDuplexPipe.cs | 0 .../Shared/TestPipeReader.cs | 0 .../Shared/TestPipeWriter.cs | 0 .../TestBinder.cs | 0 {build => src/SignalR/build}/Key.snk | Bin .../SignalR/build}/dependencies.props | 0 {build => src/SignalR/build}/publish-apps.ps1 | 0 {build => src/SignalR/build}/repo.props | 0 {build => src/SignalR/build}/repo.targets | 0 {build => src/SignalR/build}/sources.props | 0 .../SignalR/clients}/cpp/.nuget/NuGet.Config | 0 .../SignalR/clients}/cpp/.nuget/NuGet.exe | Bin .../SignalR/clients}/cpp/.nuget/NuGet.targets | 0 .../clients}/cpp/Build/Common.Build.Settings | 0 .../SignalR/clients}/cpp/Build/Common.tasks | 0 .../cpp/Build/Config.Definitions.Props | 0 .../cpp/Build/SignalRClient.Build.Settings | 0 .../SignalR/clients}/cpp/Build/Version.props | 0 .../SignalR/clients}/cpp/Build/build.msbuild | 0 .../SignalR/clients}/cpp/CMakeLists.txt | 0 .../SignalR/clients}/cpp/CONTRIBUTING.md | 0 .../SignalR/clients}/cpp/NuGet.config | 0 ...et.SignalR.Client.Cpp.UWP.targets.template | 0 ...alR.Client.Cpp.WinDesktop.targets.template | 0 .../NuGet/signalrclientcpp.nuspec.template | 0 .../SignalR/clients}/cpp/README.md | 0 .../SignalR/clients}/cpp/build.cmd | 0 .../cpp/include/signalrclient/_exports.h | 0 .../cpp/include/signalrclient/connection.h | 0 .../include/signalrclient/connection_state.h | 0 .../include/signalrclient/hub_connection.h | 0 .../cpp/include/signalrclient/hub_exception.h | 0 .../cpp/include/signalrclient/log_writer.h | 0 .../signalrclient/signalr_client_config.h | 0 .../include/signalrclient/signalr_exception.h | 0 .../cpp/include/signalrclient/trace_level.h | 0 .../include/signalrclient/transport_type.h | 0 .../cpp/include/signalrclient/web_exception.h | 0 .../SignalR/clients}/cpp/samples.sln | 0 .../HubConnectionSample.cpp | 0 .../HubConnectionSample.vcxproj | 0 .../HubConnectionSample.vcxproj.filters | 0 .../HubConnectionSample/packages.config | 0 .../samples/HubConnectionSample/stdafx.cpp | 0 .../cpp/samples/HubConnectionSample/stdafx.h | 0 .../PersistentConnectionSample.cpp | 0 .../PersistentConnectionSample.vcxproj | 0 ...PersistentConnectionSample.vcxproj.filters | 0 .../packages.config | 0 .../PersistentConnectionSample/stdafx.cpp | 0 .../PersistentConnectionSample/stdafx.h | 0 .../cpp/samples/SignalRServer/ChatHub.cs | 0 .../samples/SignalRServer/EchoConnection.cs | 0 .../SignalRServer/Properties/AssemblyInfo.cs | 0 .../Scripts/jquery-1.10.2.intellisense.js | 0 .../SignalRServer/Scripts/jquery-1.10.2.js | 0 .../Scripts/jquery-1.10.2.min.js | 0 .../Scripts/jquery-1.10.2.min.map | 0 .../Scripts/jquery.signalR-2.2.0.js | 0 .../Scripts/jquery.signalR-2.2.0.min.js | 0 .../SignalRServer/SignalRServer.csproj | 0 .../cpp/samples/SignalRServer/Startup.cs | 0 .../samples/SignalRServer/Web.Debug.config | 0 .../samples/SignalRServer/Web.Release.config | 0 .../cpp/samples/SignalRServer/Web.config | 0 .../cpp/samples/SignalRServer/index.html | 0 .../cpp/samples/SignalRServer/packages.config | 0 .../SignalR/clients}/cpp/signalrclient.sln | 0 .../signalrclient/Build/VS/packages.config | 0 .../Build/VS/signalrclient.vcxproj | 0 .../Build/VS/signalrclient.vcxproj.filters | 0 .../cpp/src/signalrclient/CMakeLists.txt | 0 .../src/signalrclient/callback_manager.cpp | 0 .../cpp/src/signalrclient/callback_manager.h | 0 .../case_insensitive_comparison_utils.h | 0 .../cpp/src/signalrclient/connection.cpp | 0 .../cpp/src/signalrclient/connection_impl.cpp | 0 .../cpp/src/signalrclient/connection_impl.h | 0 .../cpp/src/signalrclient/constants.h | 0 .../default_websocket_client.cpp | 0 .../signalrclient/default_websocket_client.h | 0 .../clients}/cpp/src/signalrclient/event.h | 0 .../cpp/src/signalrclient/http_sender.cpp | 0 .../cpp/src/signalrclient/http_sender.h | 0 .../cpp/src/signalrclient/hub_connection.cpp | 0 .../src/signalrclient/hub_connection_impl.cpp | 0 .../src/signalrclient/hub_connection_impl.h | 0 .../clients}/cpp/src/signalrclient/logger.cpp | 0 .../clients}/cpp/src/signalrclient/logger.h | 0 .../cpp/src/signalrclient/make_unique.h | 0 .../signalrclient/negotiation_response.cpp | 0 .../src/signalrclient/negotiation_response.h | 0 .../cpp/src/signalrclient/request_sender.cpp | 0 .../cpp/src/signalrclient/request_sender.h | 0 .../signalrclient/signalr_client_config.cpp | 0 .../clients}/cpp/src/signalrclient/stdafx.cpp | 0 .../clients}/cpp/src/signalrclient/stdafx.h | 0 .../src/signalrclient/trace_log_writer.cpp | 0 .../cpp/src/signalrclient/trace_log_writer.h | 0 .../cpp/src/signalrclient/transport.cpp | 0 .../cpp/src/signalrclient/transport.h | 0 .../src/signalrclient/transport_factory.cpp | 0 .../cpp/src/signalrclient/transport_factory.h | 0 .../cpp/src/signalrclient/url_builder.cpp | 0 .../cpp/src/signalrclient/url_builder.h | 0 .../cpp/src/signalrclient/web_request.cpp | 0 .../cpp/src/signalrclient/web_request.h | 0 .../src/signalrclient/web_request_factory.cpp | 0 .../src/signalrclient/web_request_factory.h | 0 .../cpp/src/signalrclient/web_response.h | 0 .../cpp/src/signalrclient/websocket_client.h | 0 .../src/signalrclient/websocket_transport.cpp | 0 .../src/signalrclient/websocket_transport.h | 0 .../signalrclientdll/Build/VS/packages.config | 0 .../Build/VS/signalrclientdll.vcxproj | 0 .../Build/VS/signalrclientdll.vcxproj.filters | 0 .../cpp/src/signalrclientdll/Resource.rc | Bin .../cpp/src/signalrclientdll/dllmain.cpp | 0 .../cpp/src/signalrclientdll/resource.h | 0 .../cpp/src/signalrclientdll/version.h | 0 .../SignalR/clients}/cpp/test/CMakeLists.txt | 0 .../clients}/cpp/test/gtest/gtest.vcxproj | 0 .../cpp/test/gtest/gtest.vcxproj.filters | 0 .../Build/VS/packages.config | 0 .../Build/VS/signalrclient-e2e-tests.vcxproj | 0 .../signalrclient-e2e-tests.vcxproj.filters | 0 .../connection_tests.cpp | 0 .../hub_connection_tests.cpp | 0 .../signalrclient-e2e-tests.cpp | 0 .../test/signalrclient-e2e-tests/stdafx.cpp | 0 .../cpp/test/signalrclient-e2e-tests/stdafx.h | 0 .../signalrclient-e2e-tests/test_utils.cpp | 0 .../test/signalrclient-e2e-tests/test_utils.h | 0 .../test/signalrclient-testhost/App.config | 0 .../Connections/HubConnection.cs | 0 .../Connections/RawConnection.cs | 0 .../test/signalrclient-testhost/Program.cs | 0 .../Properties/AssemblyInfo.cs | 0 .../test/signalrclient-testhost/Startup.cs | 0 .../signalrclient-testhost/packages.config | 0 .../signalrclient-testhost.csproj | 0 .../Build/VS/packages.config | 0 .../Build/VS/signalrclienttests.vcxproj | 0 .../VS/signalrclienttests.vcxproj.filters | 0 .../test/signalrclienttests/CMakeLists.txt | 0 .../callback_manager_tests.cpp | 0 ...ase_insensitive_comparison_utils_tests.cpp | 0 .../connection_impl_tests.cpp | 0 .../signalrclienttests/http_sender_tests.cpp | 0 .../hub_connection_impl_tests.cpp | 0 .../hub_exception_tests.cpp | 0 .../internal_hub_proxy_tests.cpp | 0 .../test/signalrclienttests/logger_tests.cpp | 0 .../signalrclienttests/memory_log_writer.cpp | 0 .../signalrclienttests/memory_log_writer.h | 0 .../request_sender_tests.cpp | 0 .../signalrclienttests/signalrclienttests.cpp | 0 .../cpp/test/signalrclienttests/stdafx.cpp | 0 .../cpp/test/signalrclienttests/stdafx.h | 0 .../cpp/test/signalrclienttests/targetver.h | 0 .../test_transport_factory.cpp | 0 .../test_transport_factory.h | 0 .../test/signalrclienttests/test_utils.cpp | 0 .../cpp/test/signalrclienttests/test_utils.h | 0 .../test_web_request_factory.cpp | 0 .../test_web_request_factory.h | 0 .../test_websocket_client.cpp | 0 .../test_websocket_client.h | 0 .../signalrclienttests/url_builder_tests.cpp | 0 .../signalrclienttests/web_request_stub.cpp | 0 .../signalrclienttests/web_request_stub.h | 0 .../signalrclienttests/web_request_tests.cpp | 0 .../websocket_transport_tests.cpp | 0 .../SignalR/clients}/java/signalr/.gitignore | 0 .../clients}/java/signalr/build.gradle | 0 .../signalr/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../SignalR/clients}/java/signalr/gradlew | 0 .../SignalR/clients}/java/signalr/gradlew.bat | 0 .../clients}/java/signalr/settings.gradle | 0 .../java/com/microsoft/signalr/Action.java | 0 .../java/com/microsoft/signalr/Action1.java | 0 .../java/com/microsoft/signalr/Action2.java | 0 .../java/com/microsoft/signalr/Action3.java | 0 .../java/com/microsoft/signalr/Action4.java | 0 .../java/com/microsoft/signalr/Action5.java | 0 .../java/com/microsoft/signalr/Action6.java | 0 .../java/com/microsoft/signalr/Action7.java | 0 .../java/com/microsoft/signalr/Action8.java | 0 .../com/microsoft/signalr/ActionBase.java | 0 .../com/microsoft/signalr/CallbackMap.java | 0 .../signalr/CancelInvocationMessage.java | 0 .../com/microsoft/signalr/CloseMessage.java | 0 .../microsoft/signalr/CompletionMessage.java | 0 .../microsoft/signalr/DefaultHttpClient.java | 0 .../microsoft/signalr/HandshakeProtocol.java | 0 .../signalr/HandshakeRequestMessage.java | 0 .../signalr/HandshakeResponseMessage.java | 0 .../com/microsoft/signalr/HttpClient.java | 0 .../signalr/HttpHubConnectionBuilder.java | 0 .../com/microsoft/signalr/HubConnection.java | 0 .../signalr/HubConnectionBuilder.java | 0 .../microsoft/signalr/HubConnectionState.java | 0 .../com/microsoft/signalr/HubException.java | 0 .../com/microsoft/signalr/HubMessage.java | 0 .../com/microsoft/signalr/HubMessageType.java | 0 .../com/microsoft/signalr/HubProtocol.java | 0 .../microsoft/signalr/InvocationBinder.java | 0 .../InvocationBindingFailureMessage.java | 0 .../microsoft/signalr/InvocationHandler.java | 0 .../microsoft/signalr/InvocationMessage.java | 0 .../microsoft/signalr/InvocationRequest.java | 0 .../microsoft/signalr/JsonHubProtocol.java | 0 .../java/com/microsoft/signalr/Negotiate.java | 0 .../microsoft/signalr/NegotiateResponse.java | 0 .../signalr/OkHttpWebSocketWrapper.java | 0 .../microsoft/signalr/OnClosedCallback.java | 0 .../microsoft/signalr/OnReceiveCallBack.java | 0 .../com/microsoft/signalr/PingMessage.java | 0 .../signalr/StreamInvocationMessage.java | 0 .../com/microsoft/signalr/StreamItem.java | 0 .../com/microsoft/signalr/Subscription.java | 0 .../com/microsoft/signalr/TransferFormat.java | 0 .../java/com/microsoft/signalr/Transport.java | 0 .../signalr/TransportOnClosedCallback.java | 0 .../microsoft/signalr/WebSocketTransport.java | 0 .../microsoft/signalr/WebSocketWrapper.java | 0 .../signalr/WebsocketWrapperOnClosed.java | 0 .../com/microsoft/signalr/package-info.java | 0 .../signalr/HandshakeProtocolTest.java | 0 .../signalr/HubConnectionBuilderTest.java | 0 .../microsoft/signalr/HubConnectionTest.java | 0 .../microsoft/signalr/HubExceptionTest.java | 0 .../signalr/JsonHubProtocolTest.java | 0 .../com/microsoft/signalr/MockTransport.java | 0 .../signalr/NegotiateResponseTest.java | 0 .../signalr/ResolveNegotiateUrlTest.java | 0 .../com/microsoft/signalr/TestHttpClient.java | 0 .../java/com/microsoft/signalr/TestUtils.java | 0 .../signalr/WebSocketTransportTest.java | 0 .../WebSocketTransportUrlFormatTest.java | 0 .../com/microsoft/signalr/sample/Chat.java | 0 .../clients}/ts/FunctionalTests/.gitignore | 0 .../ts/FunctionalTests/AuthorizedHub.cs | 0 .../ts/FunctionalTests/ComplexObject.cs | 0 .../FunctionalTests/EchoConnectionHandler.cs | 0 .../ts/FunctionalTests/FunctionalTests.csproj | 0 .../clients}/ts/FunctionalTests/Program.cs | 0 .../clients}/ts/FunctionalTests/Startup.cs | 0 .../clients}/ts/FunctionalTests/TestHub.cs | 0 .../ts/FunctionalTests/UncreatableHub.cs | 0 .../ts/FunctionalTests/func.jest.config.js | 0 .../ts/FunctionalTests/package-lock.json | 0 .../clients}/ts/FunctionalTests/package.json | 0 .../scripts/karma.base.conf.js | 0 .../scripts/karma.local.conf.js | 0 .../scripts/karma.sauce.conf.js | 0 .../ts/FunctionalTests/scripts/run-tests.ts | 0 .../ts/FunctionalTests/scripts/tsconfig.json | 0 .../clients}/ts/FunctionalTests/testCert.pfx | Bin .../ts/FunctionalTests/testCertECC.pfx | Bin .../clients}/ts/FunctionalTests/ts/Common.ts | 0 .../ts/FunctionalTests/ts/ConnectionTests.ts | 0 .../FunctionalTests/ts/HubConnectionTests.ts | 0 .../FunctionalTests/ts/LogBannerReporter.ts | 0 .../ts/FunctionalTests/ts/TestLogger.ts | 0 .../clients}/ts/FunctionalTests/ts/Utils.ts | 0 .../ts/FunctionalTests/ts/WebSocketTests.ts | 0 .../clients}/ts/FunctionalTests/ts/index.ts | 0 .../clients}/ts/FunctionalTests/tsconfig.json | 0 .../clients}/ts/FunctionalTests/web.config | 0 .../ts/FunctionalTests/webpack.config.js | 0 .../ts/FunctionalTests/wwwroot/default.html | 0 .../clients}/ts/build/embed-version.js | 0 .../clients}/ts/common/package-lock.json | 0 .../SignalR/clients}/ts/common/package.json | 0 .../SignalR/clients}/ts/jest.config.js | 0 .../SignalR/clients}/ts/package-lock.json | 0 .../SignalR/clients}/ts/package.json | 0 .../ts/signalr-protocol-msgpack/README.md | 0 .../package-lock.json | 0 .../ts/signalr-protocol-msgpack/package.json | 0 .../signalr-protocol-msgpack/rollup.config.js | 0 .../src/BinaryMessageFormat.ts | 0 .../src/MessagePackHubProtocol.ts | 0 .../ts/signalr-protocol-msgpack/src/Utils.ts | 0 .../src/browser-index.ts | 0 .../ts/signalr-protocol-msgpack/src/index.ts | 0 .../src/third-party-notices.txt | 0 .../tests/BinaryMessageFormatter.test.ts | 0 .../tests/MessagePackHubProtocol.test.ts | 0 .../tests/tsconfig.json | 0 .../ts/signalr-protocol-msgpack/tsconfig.json | 0 .../webpack.config.js | 0 .../SignalR/clients}/ts/signalr/README.md | 0 .../clients}/ts/signalr/build/process-dts.js | 0 .../clients}/ts/signalr/package-lock.json | 0 .../SignalR/clients}/ts/signalr/package.json | 0 .../clients}/ts/signalr/rollup.config.js | 0 .../ts/signalr/src/AbortController.ts | 0 .../ts/signalr/src/DefaultHttpClient.ts | 0 .../SignalR/clients}/ts/signalr/src/Errors.ts | 0 .../ts/signalr/src/HandshakeProtocol.ts | 0 .../clients}/ts/signalr/src/HttpClient.ts | 0 .../clients}/ts/signalr/src/HttpConnection.ts | 0 .../clients}/ts/signalr/src/HubConnection.ts | 0 .../ts/signalr/src/HubConnectionBuilder.ts | 0 .../clients}/ts/signalr/src/IConnection.ts | 0 .../ts/signalr/src/IHttpConnectionOptions.ts | 0 .../clients}/ts/signalr/src/IHubProtocol.ts | 0 .../clients}/ts/signalr/src/ILogger.ts | 0 .../clients}/ts/signalr/src/ITransport.ts | 0 .../ts/signalr/src/JsonHubProtocol.ts | 0 .../clients}/ts/signalr/src/Loggers.ts | 0 .../ts/signalr/src/LongPollingTransport.ts | 0 .../clients}/ts/signalr/src/NodeHttpClient.ts | 0 .../clients}/ts/signalr/src/Polyfills.ts | 0 .../signalr/src/ServerSentEventsTransport.ts | 0 .../SignalR/clients}/ts/signalr/src/Stream.ts | 0 .../ts/signalr/src/TextMessageFormat.ts | 0 .../SignalR/clients}/ts/signalr/src/Utils.ts | 0 .../ts/signalr/src/WebSocketTransport.ts | 0 .../clients}/ts/signalr/src/XhrHttpClient.ts | 0 .../clients}/ts/signalr/src/browser-index.ts | 0 .../SignalR/clients}/ts/signalr/src/index.ts | 0 .../ts/signalr/src/third-party-notices.txt | 0 .../ts/signalr/tests/AbortSignal.test.ts | 0 .../clients}/ts/signalr/tests/Common.ts | 0 .../ts/signalr/tests/HttpClient.test.ts | 0 .../ts/signalr/tests/HttpConnection.test.ts | 0 .../ts/signalr/tests/HubConnection.test.ts | 0 .../tests/HubConnectionBuilder.test.ts | 0 .../ts/signalr/tests/JsonHubProtocol.test.ts | 0 .../tests/LongPollingTransport.test.ts | 0 .../tests/ServerSentEventsTransport.test.ts | 0 .../ts/signalr/tests/TestEventSource.ts | 0 .../ts/signalr/tests/TestHttpClient.ts | 0 .../ts/signalr/tests/TestWebSocket.ts | 0 .../signalr/tests/TextMessageFormat.test.ts | 0 .../clients}/ts/signalr/tests/Utils.ts | 0 .../signalr/tests/WebSocketTransport.test.ts | 0 .../clients}/ts/signalr/tests/tsconfig.json | 0 .../SignalR/clients}/ts/signalr/tsconfig.json | 0 .../clients}/ts/signalr/webpack.config.js | 0 .../SignalR/clients}/ts/tsconfig.base.json | 0 .../SignalR/clients}/ts/tsconfig.jest.json | 0 .../SignalR/clients}/ts/tslint.json | 0 .../clients}/ts/webpack.config.base.js | 0 {docs => src/SignalR/docs}/GettingStarted.md | 0 .../SignalR/docs}/JSFunctionalTests.md | 0 {docs => src/SignalR/docs}/JSUnitTests.md | 0 .../samples}/ClientSample/ClientSample.csproj | 0 .../samples}/ClientSample/HubSample.cs | 0 .../ClientSample/LoggingMessageHandler.cs | 0 .../SignalR/samples}/ClientSample/Program.cs | 0 .../samples}/ClientSample/RawSample.cs | 0 .../samples}/ClientSample/StreamingSample.cs | 0 .../ClientSample/Tcp/BufferExtensions.cs | 0 .../ClientSample/Tcp/SocketAwaitable.cs | 0 .../ClientSample/Tcp/SocketReceiver.cs | 0 .../samples}/ClientSample/Tcp/SocketSender.cs | 0 .../ClientSample/Tcp/TcpConnection.cs | 0 .../Tcp/TcpHubConnectionBuilderExtensions.cs | 0 .../samples}/ClientSample/UploadSample.cs | 0 .../JwtClientSample/JwtClientSample.csproj | 0 .../samples}/JwtClientSample/Program.cs | 0 .../SignalR/samples}/JwtSample/.gitignore | 0 .../SignalR/samples}/JwtSample/Broadcaster.cs | 0 .../samples}/JwtSample/JwtSample.csproj | 0 .../SignalR/samples}/JwtSample/Program.cs | 0 .../JwtSample/Properties/launchSettings.json | 0 .../SignalR/samples}/JwtSample/Startup.cs | 0 .../samples}/JwtSample/wwwroot/index.html | 0 .../samples}/SignalRSamples/.gitignore | 0 .../MessagesConnectionHandler.cs | 0 .../samples}/SignalRSamples/ConnectionList.cs | 0 .../samples}/SignalRSamples/Hubs/Chat.cs | 0 .../SignalRSamples/Hubs/DynamicChat.cs | 0 .../samples}/SignalRSamples/Hubs/HubTChat.cs | 0 .../samples}/SignalRSamples/Hubs/Streaming.cs | 0 .../samples}/SignalRSamples/Hubs/UploadHub.cs | 0 .../SignalRSamples/ObservableExtensions.cs | 0 .../samples}/SignalRSamples/Program.cs | 0 .../SignalRSamples/SignalRSamples.csproj | 0 .../samples}/SignalRSamples/Startup.cs | 0 .../samples}/SignalRSamples/web.config | 0 .../samples}/SignalRSamples/wwwroot/hubs.html | 0 .../SignalRSamples/wwwroot/index.html | 0 .../SignalRSamples/wwwroot/sockets.html | 0 .../SignalRSamples/wwwroot/streaming.html | 0 .../samples}/SignalRSamples/wwwroot/utils.js | 0 .../samples}/SignalRSamples/wwwroot/ws.html | 0 .../samples}/SocialWeather/ConnectionList.cs | 0 .../SocialWeather/FormatterResolver.cs | 0 .../SocialWeather/IStreamFormatter.cs | 0 .../SocialWeather/Json/JSonStreamFormatter.cs | 0 .../PersistentConnectionLifeTimeManager.cs | 0 .../Pipe/PipeWeatherStreamFormatter.cs | 0 .../SignalR/samples}/SocialWeather/Program.cs | 0 .../ProtobufWeatherStreamFormatter.cs | 0 .../SocialWeather/Protobuf/WeatherReport.cs | 0 .../Protobuf/WeatherReport.proto | 0 .../SocialWeather/SocialWeather.csproj | 0 .../SocialWeatherConnectionHandler.cs | 0 .../SignalR/samples}/SocialWeather/Startup.cs | 0 .../samples}/SocialWeather/WeatherReport.cs | 0 .../SignalR/samples}/SocialWeather/web.config | 0 .../samples}/SocialWeather/wwwroot/index.html | 0 .../samples}/WebSocketSample/Program.cs | 0 .../WebSocketSample/WebSocketSample.csproj | 0 {specs => src/SignalR/specs}/HubProtocol.md | 0 .../SignalR/specs}/TransportProtocols.md | 0 .../src}/Common/AwaitableThreadPool.cs | 0 .../src}/Common/BinaryMessageFormatter.cs | 0 .../src}/Common/BinaryMessageParser.cs | 0 src/{ => SignalR/src}/Common/DuplexPipe.cs | 0 .../src}/Common/ForceAsyncAwaiter.cs | 0 src/{ => SignalR/src}/Common/JsonUtils.cs | 0 .../src}/Common/MemoryBufferWriter.cs | 0 .../src}/Common/PipeWriterStream.cs | 0 .../src}/Common/ReflectionHelper.cs | 0 .../src}/Common/StreamExtensions.cs | 0 .../src}/Common/TextMessageFormatter.cs | 0 .../src}/Common/TextMessageParser.cs | 0 .../src}/Common/TimerAwaitable.cs | 0 .../src}/Common/Utf8BufferTextReader.cs | 0 .../src}/Common/Utf8BufferTextWriter.cs | 0 .../src}/Common/WebSocketExtensions.cs | 0 src/{ => SignalR/src}/Directory.Build.props | 0 .../HttpConnection.Log.cs | 0 .../HttpConnection.cs | 0 .../HttpConnectionOptions.cs | 0 .../Internal/AccessTokenHttpMessageHandler.cs | 0 .../Internal/ClientPipeOptions.cs | 0 .../Internal/ConnectionLogScope.cs | 0 .../Internal/Constants.cs | 0 .../Internal/DefaultTransportFactory.cs | 0 .../Internal/ITransport.cs | 0 .../Internal/ITransportFactory.cs | 0 .../Internal/LoggingHttpMessageHandler.cs | 0 .../Internal/LongPollingTransport.Log.cs | 0 .../Internal/LongPollingTransport.cs | 0 .../Internal/PipeReaderFactory.cs | 0 .../Internal/SendUtils.cs | 0 .../Internal/ServerSentEventsMessageParser.cs | 0 .../Internal/ServerSentEventsTransport.Log.cs | 0 .../Internal/ServerSentEventsTransport.cs | 0 .../Internal/TaskExtensions.cs | 0 .../Internal/Utils.cs | 0 .../Internal/WebSocketsTransport.Log.cs | 0 .../Internal/WebSocketsTransport.cs | 0 ....AspNetCore.Http.Connections.Client.csproj | 0 .../Properties/AssemblyInfo.cs | 0 .../baseline.netcore.json | 0 .../AvailableTransport.cs | 0 .../HttpTransportType.cs | 0 .../HttpTransports.cs | 0 ....AspNetCore.Http.Connections.Common.csproj | 0 .../NegotiateProtocol.cs | 0 .../NegotiationResponse.cs | 0 .../baseline.netcore.json | 0 .../ConnectionsAppBuilderExtensions.cs | 0 ...onnectionsDependencyInjectionExtensions.cs | 0 .../ConnectionsRouteBuilder.cs | 0 .../Features/IHttpContextFeature.cs | 0 .../Features/IHttpTransportFeature.cs | 0 .../HttpConnectionContextExtensions.cs | 0 .../HttpConnectionDispatcherOptions.cs | 0 .../Internal/AuthorizeHelper.cs | 0 .../Internal/ConnectionLogScope.cs | 0 .../Internal/HttpConnectionContext.cs | 0 .../Internal/HttpConnectionDispatcher.Log.cs | 0 .../Internal/HttpConnectionDispatcher.cs | 0 .../Internal/HttpConnectionManager.Log.cs | 0 .../Internal/HttpConnectionManager.cs | 0 .../Internal/HttpConnectionStatus.cs | 0 .../Internal/HttpConnectionsEventSource.cs | 0 .../Internal/Transports/IHttpTransport.cs | 0 .../Transports/LongPollingTransport.cs | 0 .../ServerSentEventsMessageFormatter.cs | 0 .../Transports/ServerSentEventsTransport.cs | 0 .../Transports/WebSocketsTransport.Log.cs | 0 .../Transports/WebSocketsTransport.cs | 0 .../LongPollingOptions.cs | 0 ...crosoft.AspNetCore.Http.Connections.csproj | 0 .../Properties/AssemblyInfo.cs | 0 .../WebSocketOptions.cs | 0 .../baseline.netcore.json | 0 .../HubConnection.Log.cs | 0 .../HubConnection.cs | 0 .../HubConnectionBuilder.cs | 0 .../HubConnectionBuilderExtensions.cs | 0 .../HubConnectionExtensions.InvokeAsync.cs | 0 ...ConnectionExtensions.InvokeAsyncGeneric.cs | 0 .../HubConnectionExtensions.SendAsync.cs | 0 ...nnectionExtensions.StreamAsChannelAsync.cs | 0 .../HubConnectionExtensions.cs | 0 .../HubConnectionState.cs | 0 .../IConnectionFactory.cs | 0 .../IHubConnectionBuilder.cs | 0 .../Internal/ConnectionLogScope.cs | 0 .../Internal/InvocationRequest.cs | 0 ...soft.AspNetCore.SignalR.Client.Core.csproj | 0 .../Properties/AssemblyInfo.cs | 0 .../baseline.netcore.json | 0 .../HttpConnectionFactory.cs | 0 .../HubConnectionBuilderHttpExtensions.cs | 0 ...Microsoft.AspNetCore.SignalR.Client.csproj | 0 .../baseline.netcore.json | 0 .../HubException.cs | 0 .../IInvocationBinder.cs | 0 .../ISignalRBuilder.cs | 0 ...Microsoft.AspNetCore.SignalR.Common.csproj | 0 .../Properties/AssemblyInfo.cs | 0 .../Protocol/CancelInvocationMessage.cs | 0 .../Protocol/CloseMessage.cs | 0 .../Protocol/CompletionMessage.cs | 0 .../Protocol/HandshakeProtocol.cs | 0 .../Protocol/HandshakeRequestMessage.cs | 0 .../Protocol/HandshakeResponseMessage.cs | 0 .../Protocol/HubInvocationMessage.cs | 0 .../Protocol/HubMessage.cs | 0 .../Protocol/HubMethodInvocationMessage.cs | 0 .../Protocol/HubProtocolConstants.cs | 0 .../Protocol/HubProtocolExtensions.cs | 0 .../Protocol/IHubProtocol.cs | 0 .../InvocationBindingFailureMessage.cs | 0 .../Protocol/PingMessage.cs | 0 .../Protocol/StreamBindingFailureMessage.cs | 0 .../Protocol/StreamCompleteMessage.cs | 0 .../Protocol/StreamDataMessage.cs | 0 .../Protocol/StreamItemMessage.cs | 0 .../Protocol/StreamPlaceholder.cs | 0 .../baseline.netcore.json | 0 .../breakingchanges.netcore.json | 0 .../ClientProxyExtensions.cs | 0 .../DefaultHubLifetimeManager.cs | 0 .../DefaultUserIdProvider.cs | 0 .../DynamicHub.cs | 0 .../DynamicHubClients.cs | 0 .../Microsoft.AspNetCore.SignalR.Core/Hub.cs | 0 .../HubCallerContext.cs | 0 .../HubClientsExtensions.cs | 0 .../HubConnectionContext.cs | 0 .../HubConnectionHandler.cs | 0 .../HubConnectionStore.cs | 0 .../HubLifetimeManager.cs | 0 .../HubMethodNameAttribute.cs | 0 .../HubOptions.cs | 0 .../HubOptions`T.cs | 0 .../Hub`T.cs | 0 .../IClientProxy.cs | 0 .../IGroupManager.cs | 0 .../IHubActivator.cs | 0 .../IHubCallerClients.cs | 0 .../IHubCallerClients`T.cs | 0 .../IHubClients.cs | 0 .../IHubClients`T.cs | 0 .../IHubContext.cs | 0 .../IHubContext`T.cs | 0 .../IHubProtocolResolver.cs | 0 .../ISignalRServerBuilder.cs | 0 .../IUserIdProvider.cs | 0 .../Internal/AsyncEnumeratorAdapters.cs | 0 .../Internal/DefaultHubActivator.cs | 0 .../Internal/DefaultHubCallerContext.cs | 0 .../Internal/DefaultHubDispatcher.Log.cs | 0 .../Internal/DefaultHubDispatcher.cs | 0 .../Internal/DefaultHubProtocolResolver.cs | 0 .../Internal/DynamicClientProxy.cs | 0 .../Internal/ErrorMessageHelper.cs | 0 .../Internal/GroupManager.cs | 0 .../Internal/HubCallerClients.cs | 0 .../Internal/HubClients.cs | 0 .../Internal/HubClients`T.cs | 0 .../Internal/HubConnectionBinder.cs | 0 .../Internal/HubContext.cs | 0 .../Internal/HubContext`T.cs | 0 .../Internal/HubDispatcher.cs | 0 .../Internal/HubGroupList.cs | 0 .../Internal/HubMethodDescriptor.cs | 0 .../Internal/HubOptionsSetup.cs | 0 .../Internal/HubOptionsSetup`T.cs | 0 .../Internal/HubReflectionHelper.cs | 0 .../Internal/Proxies.cs | 0 .../Internal/SignalRBuilder.cs | 0 .../Internal/SignalRCoreMarkerService.cs | 0 .../Internal/TaskCache.cs | 0 .../Internal/TypeBaseEnumerationExtensions.cs | 0 .../Internal/TypedClientBuilder.cs | 0 .../Internal/TypedHubClients.cs | 0 .../Microsoft.AspNetCore.SignalR.Core.csproj | 0 .../Properties/AssemblyInfo.cs | 0 .../SerializedHubMessage.cs | 0 .../SerializedMessage.cs | 0 .../SignalRConnectionBuilderExtensions.cs | 0 .../SignalRDependencyInjectionExtensions.cs | 0 .../StreamTracker.cs | 0 .../baseline.netcore.json | 0 .../JsonHubProtocolOptions.cs | 0 ...onProtocolDependencyInjectionExtensions.cs | 0 ...t.AspNetCore.SignalR.Protocols.Json.csproj | 0 .../Protocol/JsonHubProtocol.cs | 0 .../baseline.netcore.json | 0 .../MessagePackHubProtocolOptions.cs | 0 ...ckProtocolDependencyInjectionExtensions.cs | 0 ...tCore.SignalR.Protocols.MessagePack.csproj | 0 .../Protocol/MessagePackHubProtocol.cs | 0 .../baseline.netcore.json | 0 .../HubLifetimeManagerTestBase.cs | 0 ...NetCore.SignalR.Specification.Tests.csproj | 0 .../ScaleoutHubLifetimeManagerTests.cs | 0 .../Internal/AckHandler.cs | 0 .../Internal/GroupAction.cs | 0 .../Internal/MessagePackUtil.cs | 0 .../Internal/RedisChannels.cs | 0 .../Internal/RedisGroupCommand.cs | 0 .../Internal/RedisInvocation.cs | 0 .../Internal/RedisLog.cs | 0 .../Internal/RedisProtocol.cs | 0 .../Internal/RedisSubscriptionManager.cs | 0 ...pNetCore.SignalR.StackExchangeRedis.csproj | 0 .../RedisDependencyInjectionExtensions.cs | 0 .../RedisHubLifetimeManager.cs | 0 .../RedisOptions.cs | 0 .../GetHttpContextExtensions.cs | 0 .../HubRouteBuilder.cs | 0 .../Microsoft.AspNetCore.SignalR.csproj | 0 .../SignalRAppBuilderExtensions.cs | 0 .../SignalRDependencyInjectionExtensions.cs | 0 .../SignalRMarkerService.cs | 0 .../baseline.netcore.json | 0 .../SignalR/test}/Directory.Build.props | 0 .../ApplicationLifetime.cs | 0 .../HttpConnectionDispatcherTests.cs | 0 .../HttpConnectionManagerTests.cs | 0 .../LongPollingTests.cs | 0 .../MapConnectionHandlerTests.cs | 0 ...t.AspNetCore.Http.Connections.Tests.csproj | 0 .../NegotiateProtocolTests.cs | 0 .../ServerSentEventsMessageFormatterTests.cs | 0 .../ServerSentEventsTests.cs | 0 .../TestWebSocketConnectionFeature.cs | 0 .../WebSocketsTests.cs | 0 .../HeaderUserIdProvider.cs | 0 .../HubConnectionTests.cs | 0 .../HubProtocolVersionTests.cs | 0 .../Hubs.cs | 0 ...Core.SignalR.Client.FunctionalTests.csproj | 0 .../Startup.cs | 0 .../VersionJsonHubProtocol.cs | 0 .../VersionStartup.cs | 0 .../HttpConnectionFactoryTests.cs | 0 ...HttpConnectionTests.ConnectionLifecycle.cs | 0 .../HttpConnectionTests.Helpers.cs | 0 .../HttpConnectionTests.Negotiate.cs | 0 .../HttpConnectionTests.Transport.cs | 0 .../HttpConnectionTests.cs | 0 .../HubConnectionBuilderExtensionsTests.cs | 0 .../HubConnectionBuilderTests.cs | 0 .../HubConnectionTests.ConnectionLifecycle.cs | 0 .../HubConnectionTests.Extensions.cs | 0 .../HubConnectionTests.Helpers.cs | 0 .../HubConnectionTests.Protocol.cs | 0 .../HubConnectionTests.cs | 0 .../LongPollingTransportTests.cs | 0 ...oft.AspNetCore.SignalR.Client.Tests.csproj | 0 .../ResponseUtils.cs | 0 .../ServerSentEventsParserTests.cs | 0 .../ServerSentEventsTransportTests.cs | 0 .../TestConnection.cs | 0 .../TestHttpMessageHandler.cs | 0 .../TestTransport.cs | 0 .../TestTransportFactory.cs | 0 .../Formatters/BinaryMessageFormatterTests.cs | 0 .../Formatters/BinaryMessageParserTests.cs | 0 .../Formatters/TextMessageFormatterTests.cs | 0 .../Formatters/TextMessageParserTests.cs | 0 .../Internal/Protocol/CompositeTestBinder.cs | 0 .../Internal/Protocol/CustomObject.cs | 0 .../Protocol/HandshakeProtocolTests.cs | 0 .../Internal/Protocol/HubMessageHelpers.cs | 0 .../Internal/Protocol/JsonHubProtocolTests.cs | 0 .../Protocol/MemoryBufferWriterTests.cs | 0 .../Protocol/MessagePackHubProtocolTests.cs | 0 .../Internal/Protocol/TestBinder.cs | 0 .../TestHubMessageEqualityComparer.cs | 0 .../Protocol/Utf8BufferTextReaderTests.cs | 0 .../Protocol/Utf8BufferTextWriterTests.cs | 0 ...oft.AspNetCore.SignalR.Common.Tests.csproj | 0 .../Docker.cs | 0 .../EchoHub.cs | 0 ...re.SignalR.StackExchangeRedis.Tests.csproj | 0 ...RedisDependencyInjectionExtensionsTests.cs | 0 .../RedisEndToEnd.cs | 0 .../RedisHubLifetimeManagerTests.cs | 0 .../RedisProtocolTests.cs | 0 .../RedisServerFixture.cs | 0 .../SkipIfDockerNotPresentAttribute.cs | 0 .../Startup.cs | 0 .../TestConnectionMultiplexer.cs | 0 .../CancellationTokenExtensions.cs | 0 .../ChannelExtensions.cs | 0 .../DelegateConnectionFactory.cs | 0 .../DummyHubProtocol.cs | 0 .../ExceptionMessageExtensions.cs | 0 .../FunctionalTestBase.cs | 0 .../HubConnectionBuilderTestExtensions.cs | 0 .../HubConnectionContextUtils.cs | 0 .../HubProtocolHelpers.cs | 0 .../InProcessTestServer.cs | 0 .../LogRecord.cs | 0 .../LogSinkProvider.cs | 0 ...soft.AspNetCore.SignalR.Tests.Utils.csproj | 0 .../PipeCompletionExtensions.cs | 0 .../PipeReaderExtensions.cs | 0 .../ServerLogScope.cs | 0 .../SyncPoint.cs | 0 .../TaskExtensions.cs | 0 .../TestClient.cs | 0 .../TestHelpers.cs | 0 .../VerifiableLoggedTest.cs | 0 .../VerifyNoErrorsScope.cs | 0 .../WebSocketsSupportedConditionAttribute.cs | 0 .../WrappingLoggerFactory.cs | 0 .../AddSignalRTests.cs | 0 .../AuthConnectionHandler.cs | 0 .../CancellationDisposable.cs | 0 .../ClientProxyTests.cs | 0 .../DefaultHubActivatorTests.cs | 0 .../DefaultHubLifetimeManagerTests.cs | 0 .../DefaultTransportFactoryTests.cs | 0 .../EchoConnectionHandler.cs | 0 .../EndToEndTests.cs | 0 .../HttpHeaderConnectionHandler.cs | 0 .../HubConnectionHandlerTestUtils/Hubs.cs | 0 .../HubConnectionHandlerTestUtils/Utils.cs | 0 .../HubConnectionHandlerTests.cs | 0 .../HubReflectionHelperTests.cs | 0 .../DefaultHubProtocolResolverTests.cs | 0 .../Internal/TypedClientBuilderTests.cs | 0 .../MapSignalRTests.cs | 0 .../Microsoft.AspNetCore.SignalR.Tests.csproj | 0 .../SerializedHubMessageTests.cs | 0 .../Startup.cs | 0 .../UncreatableHub.cs | 0 .../WebSocketsTransportTests.cs | 0 .../WriteThenCloseConnectionHandler.cs | 0 {test => src/SignalR/test}/xunit.runner.json | 0 version.props => src/SignalR/version.props | 0 824 files changed, 935 deletions(-) delete mode 100644 .gitattributes delete mode 100644 .github/ISSUE_TEMPLATE.md delete mode 100644 .travis.yml delete mode 100644 .vscode/launch.json delete mode 100644 .vsts-pipelines/builds/ci-internal.yml delete mode 100644 .vsts-pipelines/builds/ci-public.yml delete mode 100644 .vsts-pipelines/builds/slow-tests-internal.yml delete mode 100644 CONTRIBUTING.md delete mode 100644 LICENSE.txt delete mode 100644 NuGet.config delete mode 100644 build.cmd delete mode 100755 build.sh delete mode 160000 clients/cpp/test/gtest/googletest delete mode 100644 korebuild-lock.txt delete mode 100644 korebuild.json delete mode 100644 run.cmd delete mode 100644 run.ps1 delete mode 100755 run.sh rename .gitignore => src/SignalR/.gitignore (100%) rename .gitmodules => src/SignalR/.gitmodules (100%) rename Directory.Build.props => src/SignalR/Directory.Build.props (100%) rename Directory.Build.targets => src/SignalR/Directory.Build.targets (100%) rename NuGetPackageVerifier.json => src/SignalR/NuGetPackageVerifier.json (100%) rename README.md => src/SignalR/README.md (100%) rename SignalR.sln => src/SignalR/SignalR.sln (100%) rename THIRD-PARTY-NOTICES => src/SignalR/THIRD-PARTY-NOTICES (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/BenchmarkServer/BenchmarkServer.csproj (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/BenchmarkServer/Hubs/EchoHub.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/BenchmarkServer/Program.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/BenchmarkServer/README.md (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/BenchmarkServer/Startup.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/BenchmarkServer/signalr.json (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/Agent.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/AgentHeartbeatInformation.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/AgentReceiver.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/AgentSender.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/AgentWorker.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/Client.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/Commands/AgentCommand.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/Commands/CommandLineUtilities.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/Commands/Defaults.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/Commands/LocalCommand.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/Commands/WorkerCommand.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/ConnectionState.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/Crankier.csproj (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/IAgent.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/IRunner.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/IWorker.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/Message.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/Program.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/Runner.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/StatusInformation.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/Worker.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/WorkerHeartbeatInformation.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/WorkerReceiver.cs (100%) rename {benchmarkapps => src/SignalR/benchmarkapps}/Crankier/WorkerSender.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/AssemblyInfo.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/BroadcastBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubActivatorBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubDispatcherBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubLifetimeManagerBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/HandshakeProtocolBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionContextBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionReceiveBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionSendBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionStartBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubProtocolBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/MessageParserBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/NegotiateProtocolBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/RedisHubLifetimeManagerBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/RedisProtocolBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/ServerSentEventsBenchmark.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestConnectionContext.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestDuplexPipe.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestPipeReader.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestPipeWriter.cs (100%) rename {benchmarks => src/SignalR/benchmarks}/Microsoft.AspNetCore.SignalR.Microbenchmarks/TestBinder.cs (100%) rename {build => src/SignalR/build}/Key.snk (100%) rename {build => src/SignalR/build}/dependencies.props (100%) rename {build => src/SignalR/build}/publish-apps.ps1 (100%) rename {build => src/SignalR/build}/repo.props (100%) rename {build => src/SignalR/build}/repo.targets (100%) rename {build => src/SignalR/build}/sources.props (100%) rename {clients => src/SignalR/clients}/cpp/.nuget/NuGet.Config (100%) rename {clients => src/SignalR/clients}/cpp/.nuget/NuGet.exe (100%) rename {clients => src/SignalR/clients}/cpp/.nuget/NuGet.targets (100%) rename {clients => src/SignalR/clients}/cpp/Build/Common.Build.Settings (100%) rename {clients => src/SignalR/clients}/cpp/Build/Common.tasks (100%) rename {clients => src/SignalR/clients}/cpp/Build/Config.Definitions.Props (100%) rename {clients => src/SignalR/clients}/cpp/Build/SignalRClient.Build.Settings (100%) rename {clients => src/SignalR/clients}/cpp/Build/Version.props (100%) rename {clients => src/SignalR/clients}/cpp/Build/build.msbuild (100%) rename {clients => src/SignalR/clients}/cpp/CMakeLists.txt (100%) rename {clients => src/SignalR/clients}/cpp/CONTRIBUTING.md (100%) rename {clients => src/SignalR/clients}/cpp/NuGet.config (100%) rename {clients => src/SignalR/clients}/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.UWP.targets.template (100%) rename {clients => src/SignalR/clients}/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.WinDesktop.targets.template (100%) rename {clients => src/SignalR/clients}/cpp/NuGet/signalrclientcpp.nuspec.template (100%) rename {clients => src/SignalR/clients}/cpp/README.md (100%) rename {clients => src/SignalR/clients}/cpp/build.cmd (100%) rename {clients => src/SignalR/clients}/cpp/include/signalrclient/_exports.h (100%) rename {clients => src/SignalR/clients}/cpp/include/signalrclient/connection.h (100%) rename {clients => src/SignalR/clients}/cpp/include/signalrclient/connection_state.h (100%) rename {clients => src/SignalR/clients}/cpp/include/signalrclient/hub_connection.h (100%) rename {clients => src/SignalR/clients}/cpp/include/signalrclient/hub_exception.h (100%) rename {clients => src/SignalR/clients}/cpp/include/signalrclient/log_writer.h (100%) rename {clients => src/SignalR/clients}/cpp/include/signalrclient/signalr_client_config.h (100%) rename {clients => src/SignalR/clients}/cpp/include/signalrclient/signalr_exception.h (100%) rename {clients => src/SignalR/clients}/cpp/include/signalrclient/trace_level.h (100%) rename {clients => src/SignalR/clients}/cpp/include/signalrclient/transport_type.h (100%) rename {clients => src/SignalR/clients}/cpp/include/signalrclient/web_exception.h (100%) rename {clients => src/SignalR/clients}/cpp/samples.sln (100%) rename {clients => src/SignalR/clients}/cpp/samples/HubConnectionSample/HubConnectionSample.cpp (100%) rename {clients => src/SignalR/clients}/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj (100%) rename {clients => src/SignalR/clients}/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj.filters (100%) rename {clients => src/SignalR/clients}/cpp/samples/HubConnectionSample/packages.config (100%) rename {clients => src/SignalR/clients}/cpp/samples/HubConnectionSample/stdafx.cpp (100%) rename {clients => src/SignalR/clients}/cpp/samples/HubConnectionSample/stdafx.h (100%) rename {clients => src/SignalR/clients}/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.cpp (100%) rename {clients => src/SignalR/clients}/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj (100%) rename {clients => src/SignalR/clients}/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj.filters (100%) rename {clients => src/SignalR/clients}/cpp/samples/PersistentConnectionSample/packages.config (100%) rename {clients => src/SignalR/clients}/cpp/samples/PersistentConnectionSample/stdafx.cpp (100%) rename {clients => src/SignalR/clients}/cpp/samples/PersistentConnectionSample/stdafx.h (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/ChatHub.cs (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/EchoConnection.cs (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/Properties/AssemblyInfo.cs (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.intellisense.js (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.js (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.js (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.map (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.js (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.min.js (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/SignalRServer.csproj (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/Startup.cs (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/Web.Debug.config (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/Web.Release.config (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/Web.config (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/index.html (100%) rename {clients => src/SignalR/clients}/cpp/samples/SignalRServer/packages.config (100%) rename {clients => src/SignalR/clients}/cpp/signalrclient.sln (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/Build/VS/packages.config (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj.filters (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/CMakeLists.txt (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/callback_manager.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/callback_manager.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/case_insensitive_comparison_utils.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/connection.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/connection_impl.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/connection_impl.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/constants.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/default_websocket_client.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/default_websocket_client.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/event.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/http_sender.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/http_sender.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/hub_connection.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/hub_connection_impl.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/hub_connection_impl.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/logger.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/logger.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/make_unique.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/negotiation_response.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/negotiation_response.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/request_sender.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/request_sender.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/signalr_client_config.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/stdafx.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/stdafx.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/trace_log_writer.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/trace_log_writer.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/transport.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/transport.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/transport_factory.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/transport_factory.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/url_builder.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/url_builder.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/web_request.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/web_request.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/web_request_factory.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/web_request_factory.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/web_response.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/websocket_client.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/websocket_transport.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclient/websocket_transport.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclientdll/Build/VS/packages.config (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj.filters (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclientdll/Resource.rc (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclientdll/dllmain.cpp (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclientdll/resource.h (100%) rename {clients => src/SignalR/clients}/cpp/src/signalrclientdll/version.h (100%) rename {clients => src/SignalR/clients}/cpp/test/CMakeLists.txt (100%) rename {clients => src/SignalR/clients}/cpp/test/gtest/gtest.vcxproj (100%) rename {clients => src/SignalR/clients}/cpp/test/gtest/gtest.vcxproj.filters (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-e2e-tests/Build/VS/packages.config (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj.filters (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-e2e-tests/connection_tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-e2e-tests/hub_connection_tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-e2e-tests/signalrclient-e2e-tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-e2e-tests/stdafx.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-e2e-tests/stdafx.h (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-e2e-tests/test_utils.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-e2e-tests/test_utils.h (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-testhost/App.config (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-testhost/Connections/HubConnection.cs (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-testhost/Connections/RawConnection.cs (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-testhost/Program.cs (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-testhost/Properties/AssemblyInfo.cs (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-testhost/Startup.cs (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-testhost/packages.config (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclient-testhost/signalrclient-testhost.csproj (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/Build/VS/packages.config (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj.filters (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/CMakeLists.txt (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/callback_manager_tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/case_insensitive_comparison_utils_tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/connection_impl_tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/http_sender_tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/hub_connection_impl_tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/hub_exception_tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/internal_hub_proxy_tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/logger_tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/memory_log_writer.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/memory_log_writer.h (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/request_sender_tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/signalrclienttests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/stdafx.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/stdafx.h (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/targetver.h (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/test_transport_factory.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/test_transport_factory.h (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/test_utils.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/test_utils.h (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/test_web_request_factory.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/test_web_request_factory.h (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/test_websocket_client.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/test_websocket_client.h (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/url_builder_tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/web_request_stub.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/web_request_stub.h (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/web_request_tests.cpp (100%) rename {clients => src/SignalR/clients}/cpp/test/signalrclienttests/websocket_transport_tests.cpp (100%) rename {clients => src/SignalR/clients}/java/signalr/.gitignore (100%) rename {clients => src/SignalR/clients}/java/signalr/build.gradle (100%) rename {clients => src/SignalR/clients}/java/signalr/gradle/wrapper/gradle-wrapper.jar (100%) rename {clients => src/SignalR/clients}/java/signalr/gradle/wrapper/gradle-wrapper.properties (100%) rename {clients => src/SignalR/clients}/java/signalr/gradlew (100%) mode change 100755 => 100644 rename {clients => src/SignalR/clients}/java/signalr/gradlew.bat (100%) rename {clients => src/SignalR/clients}/java/signalr/settings.gradle (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/Action.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/Action1.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/Action2.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/Action3.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/Action4.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/Action5.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/Action6.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/Action7.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/Action8.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/ActionBase.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/CallbackMap.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/CancelInvocationMessage.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/CloseMessage.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/CompletionMessage.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/DefaultHttpClient.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/HandshakeProtocol.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/HandshakeRequestMessage.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/HandshakeResponseMessage.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/HttpClient.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/HttpHubConnectionBuilder.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/HubConnectionBuilder.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/HubConnectionState.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/HubException.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/HubMessage.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/HubMessageType.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/HubProtocol.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/InvocationBinder.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/InvocationBindingFailureMessage.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/InvocationHandler.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/InvocationMessage.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/InvocationRequest.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/JsonHubProtocol.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/Negotiate.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/NegotiateResponse.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/OkHttpWebSocketWrapper.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/OnClosedCallback.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/OnReceiveCallBack.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/PingMessage.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/StreamInvocationMessage.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/StreamItem.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/Subscription.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/TransferFormat.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/Transport.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/TransportOnClosedCallback.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/WebSocketTransport.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/WebSocketWrapper.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/WebsocketWrapperOnClosed.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/main/java/com/microsoft/signalr/package-info.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/test/java/com/microsoft/signalr/HandshakeProtocolTest.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionBuilderTest.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/test/java/com/microsoft/signalr/HubExceptionTest.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/test/java/com/microsoft/signalr/JsonHubProtocolTest.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/test/java/com/microsoft/signalr/MockTransport.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/test/java/com/microsoft/signalr/NegotiateResponseTest.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/test/java/com/microsoft/signalr/ResolveNegotiateUrlTest.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/test/java/com/microsoft/signalr/TestHttpClient.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/test/java/com/microsoft/signalr/TestUtils.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/test/java/com/microsoft/signalr/WebSocketTransportTest.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/test/java/com/microsoft/signalr/WebSocketTransportUrlFormatTest.java (100%) rename {clients => src/SignalR/clients}/java/signalr/src/test/java/com/microsoft/signalr/sample/Chat.java (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/.gitignore (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/AuthorizedHub.cs (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/ComplexObject.cs (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/EchoConnectionHandler.cs (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/FunctionalTests.csproj (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/Program.cs (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/Startup.cs (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/TestHub.cs (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/UncreatableHub.cs (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/func.jest.config.js (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/package-lock.json (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/package.json (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/scripts/karma.base.conf.js (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/scripts/karma.local.conf.js (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/scripts/karma.sauce.conf.js (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/scripts/run-tests.ts (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/scripts/tsconfig.json (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/testCert.pfx (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/testCertECC.pfx (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/ts/Common.ts (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/ts/ConnectionTests.ts (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/ts/HubConnectionTests.ts (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/ts/LogBannerReporter.ts (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/ts/TestLogger.ts (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/ts/Utils.ts (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/ts/WebSocketTests.ts (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/ts/index.ts (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/tsconfig.json (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/web.config (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/webpack.config.js (100%) rename {clients => src/SignalR/clients}/ts/FunctionalTests/wwwroot/default.html (100%) rename {clients => src/SignalR/clients}/ts/build/embed-version.js (100%) rename {clients => src/SignalR/clients}/ts/common/package-lock.json (100%) rename {clients => src/SignalR/clients}/ts/common/package.json (100%) rename {clients => src/SignalR/clients}/ts/jest.config.js (100%) rename {clients => src/SignalR/clients}/ts/package-lock.json (100%) rename {clients => src/SignalR/clients}/ts/package.json (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/README.md (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/package-lock.json (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/package.json (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/rollup.config.js (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/src/BinaryMessageFormat.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/src/Utils.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/src/browser-index.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/src/index.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/src/third-party-notices.txt (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/tests/BinaryMessageFormatter.test.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/tests/MessagePackHubProtocol.test.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/tests/tsconfig.json (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/tsconfig.json (100%) rename {clients => src/SignalR/clients}/ts/signalr-protocol-msgpack/webpack.config.js (100%) rename {clients => src/SignalR/clients}/ts/signalr/README.md (100%) rename {clients => src/SignalR/clients}/ts/signalr/build/process-dts.js (100%) rename {clients => src/SignalR/clients}/ts/signalr/package-lock.json (100%) rename {clients => src/SignalR/clients}/ts/signalr/package.json (100%) rename {clients => src/SignalR/clients}/ts/signalr/rollup.config.js (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/AbortController.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/DefaultHttpClient.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/Errors.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/HandshakeProtocol.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/HttpClient.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/HttpConnection.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/HubConnection.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/HubConnectionBuilder.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/IConnection.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/IHttpConnectionOptions.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/IHubProtocol.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/ILogger.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/ITransport.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/JsonHubProtocol.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/Loggers.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/LongPollingTransport.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/NodeHttpClient.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/Polyfills.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/ServerSentEventsTransport.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/Stream.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/TextMessageFormat.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/Utils.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/WebSocketTransport.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/XhrHttpClient.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/browser-index.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/index.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/src/third-party-notices.txt (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/AbortSignal.test.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/Common.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/HttpClient.test.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/HttpConnection.test.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/HubConnection.test.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/HubConnectionBuilder.test.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/JsonHubProtocol.test.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/LongPollingTransport.test.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/ServerSentEventsTransport.test.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/TestEventSource.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/TestHttpClient.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/TestWebSocket.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/TextMessageFormat.test.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/Utils.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/WebSocketTransport.test.ts (100%) rename {clients => src/SignalR/clients}/ts/signalr/tests/tsconfig.json (100%) rename {clients => src/SignalR/clients}/ts/signalr/tsconfig.json (100%) rename {clients => src/SignalR/clients}/ts/signalr/webpack.config.js (100%) rename {clients => src/SignalR/clients}/ts/tsconfig.base.json (100%) rename {clients => src/SignalR/clients}/ts/tsconfig.jest.json (100%) rename {clients => src/SignalR/clients}/ts/tslint.json (100%) rename {clients => src/SignalR/clients}/ts/webpack.config.base.js (100%) rename {docs => src/SignalR/docs}/GettingStarted.md (100%) rename {docs => src/SignalR/docs}/JSFunctionalTests.md (100%) rename {docs => src/SignalR/docs}/JSUnitTests.md (100%) rename {samples => src/SignalR/samples}/ClientSample/ClientSample.csproj (100%) rename {samples => src/SignalR/samples}/ClientSample/HubSample.cs (100%) rename {samples => src/SignalR/samples}/ClientSample/LoggingMessageHandler.cs (100%) rename {samples => src/SignalR/samples}/ClientSample/Program.cs (100%) rename {samples => src/SignalR/samples}/ClientSample/RawSample.cs (100%) rename {samples => src/SignalR/samples}/ClientSample/StreamingSample.cs (100%) rename {samples => src/SignalR/samples}/ClientSample/Tcp/BufferExtensions.cs (100%) rename {samples => src/SignalR/samples}/ClientSample/Tcp/SocketAwaitable.cs (100%) rename {samples => src/SignalR/samples}/ClientSample/Tcp/SocketReceiver.cs (100%) rename {samples => src/SignalR/samples}/ClientSample/Tcp/SocketSender.cs (100%) rename {samples => src/SignalR/samples}/ClientSample/Tcp/TcpConnection.cs (100%) rename {samples => src/SignalR/samples}/ClientSample/Tcp/TcpHubConnectionBuilderExtensions.cs (100%) rename {samples => src/SignalR/samples}/ClientSample/UploadSample.cs (100%) rename {samples => src/SignalR/samples}/JwtClientSample/JwtClientSample.csproj (100%) rename {samples => src/SignalR/samples}/JwtClientSample/Program.cs (100%) rename {samples => src/SignalR/samples}/JwtSample/.gitignore (100%) rename {samples => src/SignalR/samples}/JwtSample/Broadcaster.cs (100%) rename {samples => src/SignalR/samples}/JwtSample/JwtSample.csproj (100%) rename {samples => src/SignalR/samples}/JwtSample/Program.cs (100%) rename {samples => src/SignalR/samples}/JwtSample/Properties/launchSettings.json (100%) rename {samples => src/SignalR/samples}/JwtSample/Startup.cs (100%) rename {samples => src/SignalR/samples}/JwtSample/wwwroot/index.html (100%) rename {samples => src/SignalR/samples}/SignalRSamples/.gitignore (100%) rename {samples => src/SignalR/samples}/SignalRSamples/ConnectionHandlers/MessagesConnectionHandler.cs (100%) rename {samples => src/SignalR/samples}/SignalRSamples/ConnectionList.cs (100%) rename {samples => src/SignalR/samples}/SignalRSamples/Hubs/Chat.cs (100%) rename {samples => src/SignalR/samples}/SignalRSamples/Hubs/DynamicChat.cs (100%) rename {samples => src/SignalR/samples}/SignalRSamples/Hubs/HubTChat.cs (100%) rename {samples => src/SignalR/samples}/SignalRSamples/Hubs/Streaming.cs (100%) rename {samples => src/SignalR/samples}/SignalRSamples/Hubs/UploadHub.cs (100%) rename {samples => src/SignalR/samples}/SignalRSamples/ObservableExtensions.cs (100%) rename {samples => src/SignalR/samples}/SignalRSamples/Program.cs (100%) rename {samples => src/SignalR/samples}/SignalRSamples/SignalRSamples.csproj (100%) rename {samples => src/SignalR/samples}/SignalRSamples/Startup.cs (100%) rename {samples => src/SignalR/samples}/SignalRSamples/web.config (100%) rename {samples => src/SignalR/samples}/SignalRSamples/wwwroot/hubs.html (100%) rename {samples => src/SignalR/samples}/SignalRSamples/wwwroot/index.html (100%) rename {samples => src/SignalR/samples}/SignalRSamples/wwwroot/sockets.html (100%) rename {samples => src/SignalR/samples}/SignalRSamples/wwwroot/streaming.html (100%) rename {samples => src/SignalR/samples}/SignalRSamples/wwwroot/utils.js (100%) rename {samples => src/SignalR/samples}/SignalRSamples/wwwroot/ws.html (100%) rename {samples => src/SignalR/samples}/SocialWeather/ConnectionList.cs (100%) rename {samples => src/SignalR/samples}/SocialWeather/FormatterResolver.cs (100%) rename {samples => src/SignalR/samples}/SocialWeather/IStreamFormatter.cs (100%) rename {samples => src/SignalR/samples}/SocialWeather/Json/JSonStreamFormatter.cs (100%) rename {samples => src/SignalR/samples}/SocialWeather/PersistentConnectionLifeTimeManager.cs (100%) rename {samples => src/SignalR/samples}/SocialWeather/Pipe/PipeWeatherStreamFormatter.cs (100%) rename {samples => src/SignalR/samples}/SocialWeather/Program.cs (100%) rename {samples => src/SignalR/samples}/SocialWeather/Protobuf/ProtobufWeatherStreamFormatter.cs (100%) rename {samples => src/SignalR/samples}/SocialWeather/Protobuf/WeatherReport.cs (100%) rename {samples => src/SignalR/samples}/SocialWeather/Protobuf/WeatherReport.proto (100%) rename {samples => src/SignalR/samples}/SocialWeather/SocialWeather.csproj (100%) rename {samples => src/SignalR/samples}/SocialWeather/SocialWeatherConnectionHandler.cs (100%) rename {samples => src/SignalR/samples}/SocialWeather/Startup.cs (100%) rename {samples => src/SignalR/samples}/SocialWeather/WeatherReport.cs (100%) rename {samples => src/SignalR/samples}/SocialWeather/web.config (100%) rename {samples => src/SignalR/samples}/SocialWeather/wwwroot/index.html (100%) rename {samples => src/SignalR/samples}/WebSocketSample/Program.cs (100%) rename {samples => src/SignalR/samples}/WebSocketSample/WebSocketSample.csproj (100%) rename {specs => src/SignalR/specs}/HubProtocol.md (100%) rename {specs => src/SignalR/specs}/TransportProtocols.md (100%) rename src/{ => SignalR/src}/Common/AwaitableThreadPool.cs (100%) rename src/{ => SignalR/src}/Common/BinaryMessageFormatter.cs (100%) rename src/{ => SignalR/src}/Common/BinaryMessageParser.cs (100%) rename src/{ => SignalR/src}/Common/DuplexPipe.cs (100%) rename src/{ => SignalR/src}/Common/ForceAsyncAwaiter.cs (100%) rename src/{ => SignalR/src}/Common/JsonUtils.cs (100%) rename src/{ => SignalR/src}/Common/MemoryBufferWriter.cs (100%) rename src/{ => SignalR/src}/Common/PipeWriterStream.cs (100%) rename src/{ => SignalR/src}/Common/ReflectionHelper.cs (100%) rename src/{ => SignalR/src}/Common/StreamExtensions.cs (100%) rename src/{ => SignalR/src}/Common/TextMessageFormatter.cs (100%) rename src/{ => SignalR/src}/Common/TextMessageParser.cs (100%) rename src/{ => SignalR/src}/Common/TimerAwaitable.cs (100%) rename src/{ => SignalR/src}/Common/Utf8BufferTextReader.cs (100%) rename src/{ => SignalR/src}/Common/Utf8BufferTextWriter.cs (100%) rename src/{ => SignalR/src}/Common/WebSocketExtensions.cs (100%) rename src/{ => SignalR/src}/Directory.Build.props (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.Log.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/HttpConnectionOptions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/AccessTokenHttpMessageHandler.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/ClientPipeOptions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/ConnectionLogScope.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/Constants.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/DefaultTransportFactory.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/ITransport.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/ITransportFactory.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/LoggingHttpMessageHandler.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/LongPollingTransport.Log.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/LongPollingTransport.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/PipeReaderFactory.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/SendUtils.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsMessageParser.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsTransport.Log.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsTransport.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/TaskExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/Utils.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.Log.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Microsoft.AspNetCore.Http.Connections.Client.csproj (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/Properties/AssemblyInfo.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Client/baseline.netcore.json (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Common/AvailableTransport.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Common/HttpTransportType.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Common/HttpTransports.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Common/Microsoft.AspNetCore.Http.Connections.Common.csproj (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Common/NegotiateProtocol.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Common/NegotiationResponse.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections.Common/baseline.netcore.json (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/ConnectionsAppBuilderExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/ConnectionsDependencyInjectionExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/ConnectionsRouteBuilder.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Features/IHttpContextFeature.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Features/IHttpTransportFeature.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/HttpConnectionContextExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/HttpConnectionDispatcherOptions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/AuthorizeHelper.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/ConnectionLogScope.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionContext.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.Log.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionManager.Log.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionManager.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionStatus.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionsEventSource.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/Transports/IHttpTransport.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/Transports/LongPollingTransport.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/Transports/ServerSentEventsMessageFormatter.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/Transports/ServerSentEventsTransport.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.Log.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/LongPollingOptions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Microsoft.AspNetCore.Http.Connections.csproj (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/Properties/AssemblyInfo.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/WebSocketOptions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.Http.Connections/baseline.netcore.json (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.Log.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilder.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilderExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.InvokeAsync.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.InvokeAsyncGeneric.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.SendAsync.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.StreamAsChannelAsync.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionState.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/IConnectionFactory.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/IHubConnectionBuilder.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/Internal/ConnectionLogScope.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/Internal/InvocationRequest.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/Microsoft.AspNetCore.SignalR.Client.Core.csproj (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/Properties/AssemblyInfo.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client.Core/baseline.netcore.json (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client/HttpConnectionFactory.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client/HubConnectionBuilderHttpExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client/Microsoft.AspNetCore.SignalR.Client.csproj (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Client/baseline.netcore.json (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/HubException.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/IInvocationBinder.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/ISignalRBuilder.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Properties/AssemblyInfo.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/CancelInvocationMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/CloseMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/CompletionMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeProtocol.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeRequestMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeResponseMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/HubInvocationMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/HubMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/HubMethodInvocationMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolConstants.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/IHubProtocol.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/InvocationBindingFailureMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/PingMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamBindingFailureMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamCompleteMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamDataMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamItemMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamPlaceholder.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/baseline.netcore.json (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Common/breakingchanges.netcore.json (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/ClientProxyExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/DefaultHubLifetimeManager.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/DefaultUserIdProvider.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/DynamicHub.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/DynamicHubClients.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Hub.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/HubCallerContext.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/HubClientsExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/HubConnectionHandler.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/HubConnectionStore.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/HubLifetimeManager.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/HubMethodNameAttribute.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/HubOptions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/HubOptions`T.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Hub`T.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/IClientProxy.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/IGroupManager.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/IHubActivator.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/IHubCallerClients.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/IHubCallerClients`T.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/IHubClients.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/IHubClients`T.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/IHubContext.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/IHubContext`T.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/IHubProtocolResolver.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/ISignalRServerBuilder.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/IUserIdProvider.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/AsyncEnumeratorAdapters.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubActivator.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubCallerContext.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.Log.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubProtocolResolver.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/DynamicClientProxy.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/ErrorMessageHelper.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/GroupManager.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/HubCallerClients.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/HubClients.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/HubClients`T.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/HubConnectionBinder.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/HubContext.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/HubContext`T.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/HubDispatcher.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/HubGroupList.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/HubMethodDescriptor.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/HubOptionsSetup.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/HubOptionsSetup`T.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/HubReflectionHelper.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/Proxies.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRBuilder.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRCoreMarkerService.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/TaskCache.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/TypeBaseEnumerationExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/TypedClientBuilder.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Internal/TypedHubClients.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Microsoft.AspNetCore.SignalR.Core.csproj (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/Properties/AssemblyInfo.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/SerializedHubMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/SerializedMessage.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/SignalRConnectionBuilderExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/SignalRDependencyInjectionExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/StreamTracker.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Core/baseline.netcore.json (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Protocols.Json/JsonHubProtocolOptions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Protocols.Json/JsonProtocolDependencyInjectionExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Protocols.Json/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Protocols.Json/Protocol/JsonHubProtocol.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Protocols.Json/baseline.netcore.json (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/MessagePackHubProtocolOptions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/MessagePackProtocolDependencyInjectionExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Protocol/MessagePackHubProtocol.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/baseline.netcore.json (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Specification.Tests/HubLifetimeManagerTestBase.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Specification.Tests/Microsoft.AspNetCore.SignalR.Specification.Tests.csproj (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.Specification.Tests/ScaleoutHubLifetimeManagerTests.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/AckHandler.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/GroupAction.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/MessagePackUtil.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisChannels.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisGroupCommand.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisInvocation.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisLog.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisProtocol.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisSubscriptionManager.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisDependencyInjectionExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisHubLifetimeManager.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisOptions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR/GetHttpContextExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR/HubRouteBuilder.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR/Microsoft.AspNetCore.SignalR.csproj (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR/SignalRAppBuilderExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR/SignalRDependencyInjectionExtensions.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR/SignalRMarkerService.cs (100%) rename src/{ => SignalR/src}/Microsoft.AspNetCore.SignalR/baseline.netcore.json (100%) rename {test => src/SignalR/test}/Directory.Build.props (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.Http.Connections.Tests/ApplicationLifetime.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.Http.Connections.Tests/HttpConnectionDispatcherTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.Http.Connections.Tests/HttpConnectionManagerTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.Http.Connections.Tests/LongPollingTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.Http.Connections.Tests/MapConnectionHandlerTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.Http.Connections.Tests/Microsoft.AspNetCore.Http.Connections.Tests.csproj (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.Http.Connections.Tests/NegotiateProtocolTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.Http.Connections.Tests/ServerSentEventsMessageFormatterTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.Http.Connections.Tests/ServerSentEventsTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.Http.Connections.Tests/TestWebSocketConnectionFeature.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.Http.Connections.Tests/WebSocketsTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HeaderUserIdProvider.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubConnectionTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubProtocolVersionTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Hubs.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Startup.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/VersionJsonHubProtocol.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/VersionStartup.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionFactoryTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.ConnectionLifecycle.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Helpers.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Negotiate.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Transport.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderExtensionsTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.ConnectionLifecycle.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Extensions.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Helpers.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Protocol.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/LongPollingTransportTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/Microsoft.AspNetCore.SignalR.Client.Tests.csproj (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/ResponseUtils.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsParserTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsTransportTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/TestConnection.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/TestHttpMessageHandler.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/TestTransport.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Client.Tests/TestTransportFactory.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageFormatterTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageParserTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageFormatterTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageParserTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CompositeTestBinder.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CustomObject.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/HandshakeProtocolTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/HubMessageHelpers.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MemoryBufferWriterTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MessagePackHubProtocolTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestBinder.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestHubMessageEqualityComparer.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/Utf8BufferTextReaderTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/Utf8BufferTextWriterTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Common.Tests/Microsoft.AspNetCore.SignalR.Common.Tests.csproj (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Docker.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/EchoHub.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests.csproj (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisDependencyInjectionExtensionsTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisEndToEnd.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisHubLifetimeManagerTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisProtocolTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisServerFixture.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/SkipIfDockerNotPresentAttribute.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Startup.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/TestConnectionMultiplexer.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/CancellationTokenExtensions.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/ChannelExtensions.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/DelegateConnectionFactory.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/DummyHubProtocol.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/ExceptionMessageExtensions.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/FunctionalTestBase.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/HubConnectionBuilderTestExtensions.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/HubConnectionContextUtils.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/HubProtocolHelpers.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/InProcessTestServer.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/LogRecord.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/LogSinkProvider.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/Microsoft.AspNetCore.SignalR.Tests.Utils.csproj (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/PipeCompletionExtensions.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/PipeReaderExtensions.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/ServerLogScope.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/SyncPoint.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/TaskExtensions.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/TestClient.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/TestHelpers.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/VerifiableLoggedTest.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/VerifyNoErrorsScope.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/WebSocketsSupportedConditionAttribute.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests.Utils/WrappingLoggerFactory.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/AddSignalRTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/AuthConnectionHandler.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/CancellationDisposable.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/ClientProxyTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/DefaultHubActivatorTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/DefaultHubLifetimeManagerTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/DefaultTransportFactoryTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/EchoConnectionHandler.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/EndToEndTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/HttpHeaderConnectionHandler.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Hubs.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Utils.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/HubReflectionHelperTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/Internal/DefaultHubProtocolResolverTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/Internal/TypedClientBuilderTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/MapSignalRTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/SerializedHubMessageTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/Startup.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/UncreatableHub.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/WebSocketsTransportTests.cs (100%) rename {test => src/SignalR/test}/Microsoft.AspNetCore.SignalR.Tests/WriteThenCloseConnectionHandler.cs (100%) rename {test => src/SignalR/test}/xunit.runner.json (100%) rename version.props => src/SignalR/version.props (100%) diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index cc84a50010..0000000000 --- a/.gitattributes +++ /dev/null @@ -1,58 +0,0 @@ -*.doc diff=astextplain -*.DOC diff=astextplain -*.docx diff=astextplain -*.DOCX diff=astextplain -*.dot diff=astextplain -*.DOT diff=astextplain -*.pdf diff=astextplain -*.PDF diff=astextplain -*.rtf diff=astextplain -*.RTF diff=astextplain - -*.jpg binary -*.png binary -*.gif binary - -*.cs text=auto diff=csharp -*.vb text=auto -*.resx text=auto -*.c text=auto -*.cpp text=auto -*.cxx text=auto -*.h text=auto -*.hxx text=auto -*.py text=auto -*.rb text=auto -*.java text=auto -*.html text=auto -*.htm text=auto -*.css text=auto -*.scss text=auto -*.sass text=auto -*.less text=auto -*.js text=auto -*.lisp text=auto -*.clj text=auto -*.sql text=auto -*.php text=auto -*.lua text=auto -*.m text=auto -*.asm text=auto -*.erl text=auto -*.fs text=auto -*.fsx text=auto -*.hs text=auto - -*.csproj text=auto -*.vbproj text=auto -*.fsproj text=auto -*.dbproj text=auto -*.sln text=auto eol=crlf - -*.sh eol=lf - -# Workaround for npm changing line endings from CRLF to LF on Windows. Should be fixed in npm 5.8.0. -# https://github.com/npm/npm/issues/17161#issuecomment-337696678 -# https://github.com/npm/npm/releases/tag/v5.8.0-next.0 -package.json text eol=lf -package-lock.json text eol=lf diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index 09e555e864..0000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,19 +0,0 @@ -### If you believe you have an issue that affects the security of the platform please do NOT create an issue and instead email your issue details to secure@microsoft.com. Your report may be eligible for our [bug bounty](https://technet.microsoft.com/en-us/mt764065.aspx). - -### Please consider the following before filing an issue - -* If you are using NuGet Packages that start with `Microsoft.AspNet.SignalR`, use the issue tracker at https://github.com/SignalR/SignalR to report the issue. This -repository is for packages that start with `Microsoft.AspNetCore.SignalR` (and NPM packages that start with `@aspnet/signalr`) - -### Please include as much of the following as you can in your bug report - -* Versions of Server-Side NuGet Packages: -* Versions of Client-Side NuGet/NPM Packages: -* Are you using the C# client or the JavaScript client: -* The Server you are using (Kestrel/HttpSysServer/IIS/IIS Express/Azure Web App/etc.): -* The Operating System on the Server (Windows/Linux/macOS): -* The Operating System on the Client (Windows/Linux/macOS): -* The Browser on the client, if using the JavaScript client (IE/Chrome/Edge/Firefox/etc.): -* Please use the Diagnostics Guide at https://github.com/aspnet/SignalR/wiki/Diagnostics-Guide to collect server-side and client-side logs and network traces if possible. Please **do not** put the traces and logs in the Issue text as they are quite large. The Diagnostics Guide describes how to attach them to the issue. - -When in doubt, feel free to file the issue, we're happy to help answer questions. We also suggest using the `asp.net-core-signalr` tag on StackOverflow to ask questions. diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 537cb2cac5..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -language: csharp -sudo: required -dist: trusty -services: -- docker -env: - global: - - SIGNALR_TESTS_VERBOSE: 1 - - TRAVIS_NODE_VERSION: 8.9.3 -mono: none -os: -- linux -- osx -osx_image: xcode8.2 -addons: - chrome: stable - apt: - packages: - - libunwind8 -branches: - only: - - master - - /^release\/.*$/ - - /^(.*\/)?ci-.*$/ -before_install: -- nvm install $TRAVIS_NODE_VERSION -- if test "$TRAVIS_OS_NAME" == "linux"; then docker pull redis; fi -script: -- ./build.sh --ci diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index cc0f2cbe68..0000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "type": "java", - "name": "Java - Debug (Launch)", - "request": "launch", - "cwd": "${workspaceFolder}/clients/java/", - "console": "externalTerminal", - "stopOnEntry": false, - "mainClass": "com.microsoft.signalr.sample.Chat", - "args": "" - }, - { - "type": "node", - "request": "attach", - "name": "Node - Attach by Process ID", - "processId": "${command:PickProcess}" - }, - { - "type": "node", - "request": "launch", - "name": "Jest - All", - "program": "${workspaceFolder}/clients/ts/common/node_modules/jest/bin/jest", - "cwd": "${workspaceFolder}/clients/ts", - "args": ["--runInBand"], - "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen" - }, - { - "type": "node", - "request": "launch", - "name": "Jest - Current File", - "program": "${workspaceFolder}/clients/ts/common/node_modules/jest/bin/jest", - "cwd": "${workspaceFolder}/clients/ts", - "args": ["${relativeFile}"], - "console": "integratedTerminal", - "internalConsoleOptions": "neverOpen" - } - ] -} \ No newline at end of file diff --git a/.vsts-pipelines/builds/ci-internal.yml b/.vsts-pipelines/builds/ci-internal.yml deleted file mode 100644 index 4d6b5c7444..0000000000 --- a/.vsts-pipelines/builds/ci-internal.yml +++ /dev/null @@ -1,19 +0,0 @@ -trigger: -- master -- release/* - -resources: - repositories: - - repository: buildtools - type: git - name: aspnet-BuildTools - ref: refs/heads/master - -jobs: -- template: .azure/templates/project-ci.yml@buildtools - parameters: - beforeBuild: - - task: NodeTool@0 - displayName: Use Node 8.x - inputs: - versionSpec: 8.x diff --git a/.vsts-pipelines/builds/ci-public.yml b/.vsts-pipelines/builds/ci-public.yml deleted file mode 100644 index 5662cbc57b..0000000000 --- a/.vsts-pipelines/builds/ci-public.yml +++ /dev/null @@ -1,21 +0,0 @@ -trigger: -- master -- release/* - -# See https://github.com/aspnet/BuildTools -resources: - repositories: - - repository: buildtools - type: github - endpoint: DotNet-Bot GitHub Connection - name: aspnet/BuildTools - ref: refs/heads/master - -jobs: -- template: .azure/templates/project-ci.yml@buildtools - parameters: - beforeBuild: - - task: NodeTool@0 - displayName: Use Node 8.x - inputs: - versionSpec: 8.x diff --git a/.vsts-pipelines/builds/slow-tests-internal.yml b/.vsts-pipelines/builds/slow-tests-internal.yml deleted file mode 100644 index dbb62aacfb..0000000000 --- a/.vsts-pipelines/builds/slow-tests-internal.yml +++ /dev/null @@ -1,46 +0,0 @@ -trigger: -- master -- release/* - -phases: - - phase: "Build" - queue: - name: Hosted VS2017 - steps: - - task: NodeTool@0 - displayName: Use Node >=9.11.1 - inputs: - versionSpec: '>=9.11.1' - checkLatest: true - - - task: BatchScript@1 - displayName: Build - inputs: - filename: './build.cmd' - arguments: '/p:SkipTests=true' - modifyEnvironment: false - - - task: PowerShell@1 - displayName: Publish Samples - inputs: - scriptName: './build/publish-apps.ps1' - arguments: '-RootDirectory $(Build.SourcesDirectory) -CommitHash $(Build.SourceVersion) -BranchName $(Build.SourceBranch) -BuildNumber $(Build.BuildNumber)' - - - task: AzureRmWebAppDeployment@3 - displayName: Deploy FunctionalTests - inputs: - azureSubscription: SignalR Functional Testing Azure Connection - WebAppName: '$(Parameters.FunctionalTestAppName)' - Package: '$(Build.SourcesDirectory)/artifacts/apps/FunctionalTests' - TakeAppOfflineFlag: true - continueOnError: true - - - task: AzureRmWebAppDeployment@3 - displayName: Deploy SignalRSamples - inputs: - azureSubscription: SignalR Functional Testing Azure Connection - WebAppName: '$(Parameters.SamplesAppName)' - Package: '$(Build.SourcesDirectory)/artifacts/apps/SignalRSamples' - TakeAppOfflineFlag: true - continueOnError: true - diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index eac4268e4c..0000000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,4 +0,0 @@ -Contributing -====== - -Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/master/CONTRIBUTING.md) in the Home repo. diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index b3b180cd51..0000000000 --- a/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright (c) .NET Foundation and Contributors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/NuGet.config b/NuGet.config deleted file mode 100644 index 1280d2db38..0000000000 --- a/NuGet.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/build.cmd b/build.cmd deleted file mode 100644 index c0050bda12..0000000000 --- a/build.cmd +++ /dev/null @@ -1,2 +0,0 @@ -@ECHO OFF -PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' default-build %*; exit $LASTEXITCODE" diff --git a/build.sh b/build.sh deleted file mode 100755 index 98a4b22765..0000000000 --- a/build.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -# Call "sync" between "chmod" and execution to prevent "text file busy" error in Docker (aufs) -chmod +x "$DIR/run.sh"; sync -"$DIR/run.sh" default-build "$@" diff --git a/clients/cpp/test/gtest/googletest b/clients/cpp/test/gtest/googletest deleted file mode 160000 index 4e4df226fc..0000000000 --- a/clients/cpp/test/gtest/googletest +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4e4df226fc197c0dda6e37f5c8c3845ca1e73a49 diff --git a/korebuild-lock.txt b/korebuild-lock.txt deleted file mode 100644 index 3400cb92d8..0000000000 --- a/korebuild-lock.txt +++ /dev/null @@ -1,2 +0,0 @@ -version:3.0.0-build-20181114.5 -commithash:880e9a204d4ee4a18dfd83c9fb05a192a28bca60 diff --git a/korebuild.json b/korebuild.json deleted file mode 100644 index ce2e15a055..0000000000 --- a/korebuild.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json", - "channel": "master", - "toolsets": { - "nodejs": { - "required": true, - "minVersion": "8.0" - } - } -} diff --git a/run.cmd b/run.cmd deleted file mode 100644 index d52d5c7e68..0000000000 --- a/run.cmd +++ /dev/null @@ -1,2 +0,0 @@ -@ECHO OFF -PowerShell -NoProfile -NoLogo -ExecutionPolicy unrestricted -Command "[System.Threading.Thread]::CurrentThread.CurrentCulture = ''; [System.Threading.Thread]::CurrentThread.CurrentUICulture = '';& '%~dp0run.ps1' %*; exit $LASTEXITCODE" diff --git a/run.ps1 b/run.ps1 deleted file mode 100644 index 34604c7175..0000000000 --- a/run.ps1 +++ /dev/null @@ -1,209 +0,0 @@ -#!/usr/bin/env powershell -#requires -version 4 - -<# -.SYNOPSIS -Executes KoreBuild commands. - -.DESCRIPTION -Downloads korebuild if required. Then executes the KoreBuild command. To see available commands, execute with `-Command help`. - -.PARAMETER Command -The KoreBuild command to run. - -.PARAMETER Path -The folder to build. Defaults to the folder containing this script. - -.PARAMETER Channel -The channel of KoreBuild to download. Overrides the value from the config file. - -.PARAMETER DotNetHome -The directory where .NET Core tools will be stored. - -.PARAMETER ToolsSource -The base url where build tools can be downloaded. Overrides the value from the config file. - -.PARAMETER Update -Updates KoreBuild to the latest version even if a lock file is present. - -.PARAMETER Reinstall -Re-installs KoreBuild - -.PARAMETER ConfigFile -The path to the configuration file that stores values. Defaults to korebuild.json. - -.PARAMETER ToolsSourceSuffix -The Suffix to append to the end of the ToolsSource. Useful for query strings in blob stores. - -.PARAMETER CI -Sets up CI specific settings and variables. - -.PARAMETER Arguments -Arguments to be passed to the command - -.NOTES -This function will create a file $PSScriptRoot/korebuild-lock.txt. This lock file can be committed to source, but does not have to be. -When the lockfile is not present, KoreBuild will create one using latest available version from $Channel. - -The $ConfigFile is expected to be an JSON file. It is optional, and the configuration values in it are optional as well. Any options set -in the file are overridden by command line parameters. - -.EXAMPLE -Example config file: -```json -{ - "$schema": "https://raw.githubusercontent.com/aspnet/BuildTools/master/tools/korebuild.schema.json", - "channel": "master", - "toolsSource": "https://aspnetcore.blob.core.windows.net/buildtools" -} -``` -#> -[CmdletBinding(PositionalBinding = $false)] -param( - [Parameter(Mandatory = $true, Position = 0)] - [string]$Command, - [string]$Path = $PSScriptRoot, - [Alias('c')] - [string]$Channel, - [Alias('d')] - [string]$DotNetHome, - [Alias('s')] - [string]$ToolsSource, - [Alias('u')] - [switch]$Update, - [switch]$Reinstall, - [string]$ToolsSourceSuffix, - [string]$ConfigFile = $null, - [switch]$CI, - [Parameter(ValueFromRemainingArguments = $true)] - [string[]]$Arguments -) - -Set-StrictMode -Version 2 -$ErrorActionPreference = 'Stop' - -# -# Functions -# - -function Get-KoreBuild { - - $lockFile = Join-Path $Path 'korebuild-lock.txt' - - if (!(Test-Path $lockFile) -or $Update) { - Get-RemoteFile "$ToolsSource/korebuild/channels/$Channel/latest.txt" $lockFile $ToolsSourceSuffix - } - - $version = Get-Content $lockFile | Where-Object { $_ -like 'version:*' } | Select-Object -first 1 - if (!$version) { - Write-Error "Failed to parse version from $lockFile. Expected a line that begins with 'version:'" - } - $version = $version.TrimStart('version:').Trim() - $korebuildPath = Join-Paths $DotNetHome ('buildtools', 'korebuild', $version) - - if ($Reinstall -and (Test-Path $korebuildPath)) { - Remove-Item -Force -Recurse $korebuildPath - } - - if (!(Test-Path $korebuildPath)) { - Write-Host -ForegroundColor Magenta "Downloading KoreBuild $version" - New-Item -ItemType Directory -Path $korebuildPath | Out-Null - $remotePath = "$ToolsSource/korebuild/artifacts/$version/korebuild.$version.zip" - - try { - $tmpfile = Join-Path ([IO.Path]::GetTempPath()) "KoreBuild-$([guid]::NewGuid()).zip" - Get-RemoteFile $remotePath $tmpfile $ToolsSourceSuffix - if (Get-Command -Name 'Microsoft.PowerShell.Archive\Expand-Archive' -ErrorAction Ignore) { - # Use built-in commands where possible as they are cross-plat compatible - Microsoft.PowerShell.Archive\Expand-Archive -Path $tmpfile -DestinationPath $korebuildPath - } - else { - # Fallback to old approach for old installations of PowerShell - Add-Type -AssemblyName System.IO.Compression.FileSystem - [System.IO.Compression.ZipFile]::ExtractToDirectory($tmpfile, $korebuildPath) - } - } - catch { - Remove-Item -Recurse -Force $korebuildPath -ErrorAction Ignore - throw - } - finally { - Remove-Item $tmpfile -ErrorAction Ignore - } - } - - return $korebuildPath -} - -function Join-Paths([string]$path, [string[]]$childPaths) { - $childPaths | ForEach-Object { $path = Join-Path $path $_ } - return $path -} - -function Get-RemoteFile([string]$RemotePath, [string]$LocalPath, [string]$RemoteSuffix) { - if ($RemotePath -notlike 'http*') { - Copy-Item $RemotePath $LocalPath - return - } - - $retries = 10 - while ($retries -gt 0) { - $retries -= 1 - try { - Invoke-WebRequest -UseBasicParsing -Uri $($RemotePath + $RemoteSuffix) -OutFile $LocalPath - return - } - catch { - Write-Verbose "Request failed. $retries retries remaining" - } - } - - Write-Error "Download failed: '$RemotePath'." -} - -# -# Main -# - -# Load configuration or set defaults - -$Path = Resolve-Path $Path -if (!$ConfigFile) { $ConfigFile = Join-Path $Path 'korebuild.json' } - -if (Test-Path $ConfigFile) { - try { - $config = Get-Content -Raw -Encoding UTF8 -Path $ConfigFile | ConvertFrom-Json - if ($config) { - if (!($Channel) -and (Get-Member -Name 'channel' -InputObject $config)) { [string] $Channel = $config.channel } - if (!($ToolsSource) -and (Get-Member -Name 'toolsSource' -InputObject $config)) { [string] $ToolsSource = $config.toolsSource} - } - } - catch { - Write-Host -ForegroundColor Red $Error[0] - Write-Error "$ConfigFile contains invalid JSON." - exit 1 - } -} - -if (!$DotNetHome) { - $DotNetHome = if ($env:DOTNET_HOME) { $env:DOTNET_HOME } ` - elseif ($env:USERPROFILE) { Join-Path $env:USERPROFILE '.dotnet'} ` - elseif ($env:HOME) {Join-Path $env:HOME '.dotnet'}` - else { Join-Path $PSScriptRoot '.dotnet'} -} - -if (!$Channel) { $Channel = 'master' } -if (!$ToolsSource) { $ToolsSource = 'https://aspnetcore.blob.core.windows.net/buildtools' } - -# Execute - -$korebuildPath = Get-KoreBuild -Import-Module -Force -Scope Local (Join-Path $korebuildPath 'KoreBuild.psd1') - -try { - Set-KoreBuildSettings -ToolsSource $ToolsSource -DotNetHome $DotNetHome -RepoPath $Path -ConfigFile $ConfigFile -CI:$CI - Invoke-KoreBuildCommand $Command @Arguments -} -finally { - Remove-Module 'KoreBuild' -ErrorAction Ignore -} diff --git a/run.sh b/run.sh deleted file mode 100755 index 4c1fed5646..0000000000 --- a/run.sh +++ /dev/null @@ -1,256 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -# -# variables -# - -RESET="\033[0m" -RED="\033[0;31m" -YELLOW="\033[0;33m" -MAGENTA="\033[0;95m" -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -[ -z "${DOTNET_HOME:-}" ] && DOTNET_HOME="$HOME/.dotnet" -verbose=false -update=false -reinstall=false -repo_path="$DIR" -channel='' -tools_source='' -tools_source_suffix='' -ci=false - -# -# Functions -# -__usage() { - echo "Usage: $(basename "${BASH_SOURCE[0]}") command [options] [[--] ...]" - echo "" - echo "Arguments:" - echo " command The command to be run." - echo " ... Arguments passed to the command. Variable number of arguments allowed." - echo "" - echo "Options:" - echo " --verbose Show verbose output." - echo " -c|--channel The channel of KoreBuild to download. Overrides the value from the config file.." - echo " --config-file The path to the configuration file that stores values. Defaults to korebuild.json." - echo " -d|--dotnet-home The directory where .NET Core tools will be stored. Defaults to '\$DOTNET_HOME' or '\$HOME/.dotnet." - echo " --path The directory to build. Defaults to the directory containing the script." - echo " -s|--tools-source|-ToolsSource The base url where build tools can be downloaded. Overrides the value from the config file." - echo " --tools-source-suffix|-ToolsSourceSuffix The suffix to append to tools-source. Useful for query strings." - echo " -u|--update Update to the latest KoreBuild even if the lock file is present." - echo " --reinstall Reinstall KoreBuild." - echo " --ci Apply CI specific settings and environment variables." - echo "" - echo "Description:" - echo " This function will create a file \$DIR/korebuild-lock.txt. This lock file can be committed to source, but does not have to be." - echo " When the lockfile is not present, KoreBuild will create one using latest available version from \$channel." - - if [[ "${1:-}" != '--no-exit' ]]; then - exit 2 - fi -} - -get_korebuild() { - local version - local lock_file="$repo_path/korebuild-lock.txt" - if [ ! -f "$lock_file" ] || [ "$update" = true ]; then - __get_remote_file "$tools_source/korebuild/channels/$channel/latest.txt" "$lock_file" "$tools_source_suffix" - fi - version="$(grep 'version:*' -m 1 "$lock_file")" - if [[ "$version" == '' ]]; then - __error "Failed to parse version from $lock_file. Expected a line that begins with 'version:'" - return 1 - fi - version="$(echo "${version#version:}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" - local korebuild_path="$DOTNET_HOME/buildtools/korebuild/$version" - - if [ "$reinstall" = true ] && [ -d "$korebuild_path" ]; then - rm -rf "$korebuild_path" - fi - - { - if [ ! -d "$korebuild_path" ]; then - mkdir -p "$korebuild_path" - local remote_path="$tools_source/korebuild/artifacts/$version/korebuild.$version.zip" - tmpfile="$(mktemp)" - echo -e "${MAGENTA}Downloading KoreBuild ${version}${RESET}" - if __get_remote_file "$remote_path" "$tmpfile" "$tools_source_suffix"; then - unzip -q -d "$korebuild_path" "$tmpfile" - fi - rm "$tmpfile" || true - fi - - source "$korebuild_path/KoreBuild.sh" - } || { - if [ -d "$korebuild_path" ]; then - echo "Cleaning up after failed installation" - rm -rf "$korebuild_path" || true - fi - return 1 - } -} - -__error() { - echo -e "${RED}error: $*${RESET}" 1>&2 -} - -__warn() { - echo -e "${YELLOW}warning: $*${RESET}" -} - -__machine_has() { - hash "$1" > /dev/null 2>&1 - return $? -} - -__get_remote_file() { - local remote_path=$1 - local local_path=$2 - local remote_path_suffix=$3 - - if [[ "$remote_path" != 'http'* ]]; then - cp "$remote_path" "$local_path" - return 0 - fi - - local failed=false - if __machine_has wget; then - wget --tries 10 --quiet -O "$local_path" "${remote_path}${remote_path_suffix}" || failed=true - else - failed=true - fi - - if [ "$failed" = true ] && __machine_has curl; then - failed=false - curl --retry 10 -sSL -f --create-dirs -o "$local_path" "${remote_path}${remote_path_suffix}" || failed=true - fi - - if [ "$failed" = true ]; then - __error "Download failed: $remote_path" 1>&2 - return 1 - fi -} - -# -# main -# - -command="${1:-}" -shift - -while [[ $# -gt 0 ]]; do - case $1 in - -\?|-h|--help) - __usage --no-exit - exit 0 - ;; - -c|--channel|-Channel) - shift - channel="${1:-}" - [ -z "$channel" ] && __usage - ;; - --config-file|-ConfigFile) - shift - config_file="${1:-}" - [ -z "$config_file" ] && __usage - if [ ! -f "$config_file" ]; then - __error "Invalid value for --config-file. $config_file does not exist." - exit 1 - fi - ;; - -d|--dotnet-home|-DotNetHome) - shift - DOTNET_HOME="${1:-}" - [ -z "$DOTNET_HOME" ] && __usage - ;; - --path|-Path) - shift - repo_path="${1:-}" - [ -z "$repo_path" ] && __usage - ;; - -s|--tools-source|-ToolsSource) - shift - tools_source="${1:-}" - [ -z "$tools_source" ] && __usage - ;; - --tools-source-suffix|-ToolsSourceSuffix) - shift - tools_source_suffix="${1:-}" - [ -z "$tools_source_suffix" ] && __usage - ;; - -u|--update|-Update) - update=true - ;; - --reinstall|-[Rr]einstall) - reinstall=true - ;; - --ci|-[Cc][Ii]) - ci=true - ;; - --verbose|-Verbose) - verbose=true - ;; - --) - shift - break - ;; - *) - break - ;; - esac - shift -done - -if ! __machine_has unzip; then - __error 'Missing required command: unzip' - exit 1 -fi - -if ! __machine_has curl && ! __machine_has wget; then - __error 'Missing required command. Either wget or curl is required.' - exit 1 -fi - -[ -z "${config_file:-}" ] && config_file="$repo_path/korebuild.json" -if [ -f "$config_file" ]; then - if __machine_has jq ; then - if jq '.' "$config_file" >/dev/null ; then - config_channel="$(jq -r 'select(.channel!=null) | .channel' "$config_file")" - config_tools_source="$(jq -r 'select(.toolsSource!=null) | .toolsSource' "$config_file")" - else - __error "$config_file contains invalid JSON." - exit 1 - fi - elif __machine_has python ; then - if python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then - config_channel="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")" - config_tools_source="$(python -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")" - else - __error "$config_file contains invalid JSON." - exit 1 - fi - elif __machine_has python3 ; then - if python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'))" >/dev/null ; then - config_channel="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['channel'] if 'channel' in obj else '')")" - config_tools_source="$(python3 -c "import json,codecs;obj=json.load(codecs.open('$config_file', 'r', 'utf-8-sig'));print(obj['toolsSource'] if 'toolsSource' in obj else '')")" - else - __error "$config_file contains invalid JSON." - exit 1 - fi - else - __error 'Missing required command: jq or python. Could not parse the JSON file.' - exit 1 - fi - - [ ! -z "${config_channel:-}" ] && channel="$config_channel" - [ ! -z "${config_tools_source:-}" ] && tools_source="$config_tools_source" -fi - -[ -z "$channel" ] && channel='master' -[ -z "$tools_source" ] && tools_source='https://aspnetcore.blob.core.windows.net/buildtools' - -get_korebuild -set_korebuildsettings "$tools_source" "$DOTNET_HOME" "$repo_path" "$config_file" "$ci" -invoke_korebuild_command "$command" "$@" diff --git a/.gitignore b/src/SignalR/.gitignore similarity index 100% rename from .gitignore rename to src/SignalR/.gitignore diff --git a/.gitmodules b/src/SignalR/.gitmodules similarity index 100% rename from .gitmodules rename to src/SignalR/.gitmodules diff --git a/Directory.Build.props b/src/SignalR/Directory.Build.props similarity index 100% rename from Directory.Build.props rename to src/SignalR/Directory.Build.props diff --git a/Directory.Build.targets b/src/SignalR/Directory.Build.targets similarity index 100% rename from Directory.Build.targets rename to src/SignalR/Directory.Build.targets diff --git a/NuGetPackageVerifier.json b/src/SignalR/NuGetPackageVerifier.json similarity index 100% rename from NuGetPackageVerifier.json rename to src/SignalR/NuGetPackageVerifier.json diff --git a/README.md b/src/SignalR/README.md similarity index 100% rename from README.md rename to src/SignalR/README.md diff --git a/SignalR.sln b/src/SignalR/SignalR.sln similarity index 100% rename from SignalR.sln rename to src/SignalR/SignalR.sln diff --git a/THIRD-PARTY-NOTICES b/src/SignalR/THIRD-PARTY-NOTICES similarity index 100% rename from THIRD-PARTY-NOTICES rename to src/SignalR/THIRD-PARTY-NOTICES diff --git a/benchmarkapps/BenchmarkServer/BenchmarkServer.csproj b/src/SignalR/benchmarkapps/BenchmarkServer/BenchmarkServer.csproj similarity index 100% rename from benchmarkapps/BenchmarkServer/BenchmarkServer.csproj rename to src/SignalR/benchmarkapps/BenchmarkServer/BenchmarkServer.csproj diff --git a/benchmarkapps/BenchmarkServer/Hubs/EchoHub.cs b/src/SignalR/benchmarkapps/BenchmarkServer/Hubs/EchoHub.cs similarity index 100% rename from benchmarkapps/BenchmarkServer/Hubs/EchoHub.cs rename to src/SignalR/benchmarkapps/BenchmarkServer/Hubs/EchoHub.cs diff --git a/benchmarkapps/BenchmarkServer/Program.cs b/src/SignalR/benchmarkapps/BenchmarkServer/Program.cs similarity index 100% rename from benchmarkapps/BenchmarkServer/Program.cs rename to src/SignalR/benchmarkapps/BenchmarkServer/Program.cs diff --git a/benchmarkapps/BenchmarkServer/README.md b/src/SignalR/benchmarkapps/BenchmarkServer/README.md similarity index 100% rename from benchmarkapps/BenchmarkServer/README.md rename to src/SignalR/benchmarkapps/BenchmarkServer/README.md diff --git a/benchmarkapps/BenchmarkServer/Startup.cs b/src/SignalR/benchmarkapps/BenchmarkServer/Startup.cs similarity index 100% rename from benchmarkapps/BenchmarkServer/Startup.cs rename to src/SignalR/benchmarkapps/BenchmarkServer/Startup.cs diff --git a/benchmarkapps/BenchmarkServer/signalr.json b/src/SignalR/benchmarkapps/BenchmarkServer/signalr.json similarity index 100% rename from benchmarkapps/BenchmarkServer/signalr.json rename to src/SignalR/benchmarkapps/BenchmarkServer/signalr.json diff --git a/benchmarkapps/Crankier/Agent.cs b/src/SignalR/benchmarkapps/Crankier/Agent.cs similarity index 100% rename from benchmarkapps/Crankier/Agent.cs rename to src/SignalR/benchmarkapps/Crankier/Agent.cs diff --git a/benchmarkapps/Crankier/AgentHeartbeatInformation.cs b/src/SignalR/benchmarkapps/Crankier/AgentHeartbeatInformation.cs similarity index 100% rename from benchmarkapps/Crankier/AgentHeartbeatInformation.cs rename to src/SignalR/benchmarkapps/Crankier/AgentHeartbeatInformation.cs diff --git a/benchmarkapps/Crankier/AgentReceiver.cs b/src/SignalR/benchmarkapps/Crankier/AgentReceiver.cs similarity index 100% rename from benchmarkapps/Crankier/AgentReceiver.cs rename to src/SignalR/benchmarkapps/Crankier/AgentReceiver.cs diff --git a/benchmarkapps/Crankier/AgentSender.cs b/src/SignalR/benchmarkapps/Crankier/AgentSender.cs similarity index 100% rename from benchmarkapps/Crankier/AgentSender.cs rename to src/SignalR/benchmarkapps/Crankier/AgentSender.cs diff --git a/benchmarkapps/Crankier/AgentWorker.cs b/src/SignalR/benchmarkapps/Crankier/AgentWorker.cs similarity index 100% rename from benchmarkapps/Crankier/AgentWorker.cs rename to src/SignalR/benchmarkapps/Crankier/AgentWorker.cs diff --git a/benchmarkapps/Crankier/Client.cs b/src/SignalR/benchmarkapps/Crankier/Client.cs similarity index 100% rename from benchmarkapps/Crankier/Client.cs rename to src/SignalR/benchmarkapps/Crankier/Client.cs diff --git a/benchmarkapps/Crankier/Commands/AgentCommand.cs b/src/SignalR/benchmarkapps/Crankier/Commands/AgentCommand.cs similarity index 100% rename from benchmarkapps/Crankier/Commands/AgentCommand.cs rename to src/SignalR/benchmarkapps/Crankier/Commands/AgentCommand.cs diff --git a/benchmarkapps/Crankier/Commands/CommandLineUtilities.cs b/src/SignalR/benchmarkapps/Crankier/Commands/CommandLineUtilities.cs similarity index 100% rename from benchmarkapps/Crankier/Commands/CommandLineUtilities.cs rename to src/SignalR/benchmarkapps/Crankier/Commands/CommandLineUtilities.cs diff --git a/benchmarkapps/Crankier/Commands/Defaults.cs b/src/SignalR/benchmarkapps/Crankier/Commands/Defaults.cs similarity index 100% rename from benchmarkapps/Crankier/Commands/Defaults.cs rename to src/SignalR/benchmarkapps/Crankier/Commands/Defaults.cs diff --git a/benchmarkapps/Crankier/Commands/LocalCommand.cs b/src/SignalR/benchmarkapps/Crankier/Commands/LocalCommand.cs similarity index 100% rename from benchmarkapps/Crankier/Commands/LocalCommand.cs rename to src/SignalR/benchmarkapps/Crankier/Commands/LocalCommand.cs diff --git a/benchmarkapps/Crankier/Commands/WorkerCommand.cs b/src/SignalR/benchmarkapps/Crankier/Commands/WorkerCommand.cs similarity index 100% rename from benchmarkapps/Crankier/Commands/WorkerCommand.cs rename to src/SignalR/benchmarkapps/Crankier/Commands/WorkerCommand.cs diff --git a/benchmarkapps/Crankier/ConnectionState.cs b/src/SignalR/benchmarkapps/Crankier/ConnectionState.cs similarity index 100% rename from benchmarkapps/Crankier/ConnectionState.cs rename to src/SignalR/benchmarkapps/Crankier/ConnectionState.cs diff --git a/benchmarkapps/Crankier/Crankier.csproj b/src/SignalR/benchmarkapps/Crankier/Crankier.csproj similarity index 100% rename from benchmarkapps/Crankier/Crankier.csproj rename to src/SignalR/benchmarkapps/Crankier/Crankier.csproj diff --git a/benchmarkapps/Crankier/IAgent.cs b/src/SignalR/benchmarkapps/Crankier/IAgent.cs similarity index 100% rename from benchmarkapps/Crankier/IAgent.cs rename to src/SignalR/benchmarkapps/Crankier/IAgent.cs diff --git a/benchmarkapps/Crankier/IRunner.cs b/src/SignalR/benchmarkapps/Crankier/IRunner.cs similarity index 100% rename from benchmarkapps/Crankier/IRunner.cs rename to src/SignalR/benchmarkapps/Crankier/IRunner.cs diff --git a/benchmarkapps/Crankier/IWorker.cs b/src/SignalR/benchmarkapps/Crankier/IWorker.cs similarity index 100% rename from benchmarkapps/Crankier/IWorker.cs rename to src/SignalR/benchmarkapps/Crankier/IWorker.cs diff --git a/benchmarkapps/Crankier/Message.cs b/src/SignalR/benchmarkapps/Crankier/Message.cs similarity index 100% rename from benchmarkapps/Crankier/Message.cs rename to src/SignalR/benchmarkapps/Crankier/Message.cs diff --git a/benchmarkapps/Crankier/Program.cs b/src/SignalR/benchmarkapps/Crankier/Program.cs similarity index 100% rename from benchmarkapps/Crankier/Program.cs rename to src/SignalR/benchmarkapps/Crankier/Program.cs diff --git a/benchmarkapps/Crankier/Runner.cs b/src/SignalR/benchmarkapps/Crankier/Runner.cs similarity index 100% rename from benchmarkapps/Crankier/Runner.cs rename to src/SignalR/benchmarkapps/Crankier/Runner.cs diff --git a/benchmarkapps/Crankier/StatusInformation.cs b/src/SignalR/benchmarkapps/Crankier/StatusInformation.cs similarity index 100% rename from benchmarkapps/Crankier/StatusInformation.cs rename to src/SignalR/benchmarkapps/Crankier/StatusInformation.cs diff --git a/benchmarkapps/Crankier/Worker.cs b/src/SignalR/benchmarkapps/Crankier/Worker.cs similarity index 100% rename from benchmarkapps/Crankier/Worker.cs rename to src/SignalR/benchmarkapps/Crankier/Worker.cs diff --git a/benchmarkapps/Crankier/WorkerHeartbeatInformation.cs b/src/SignalR/benchmarkapps/Crankier/WorkerHeartbeatInformation.cs similarity index 100% rename from benchmarkapps/Crankier/WorkerHeartbeatInformation.cs rename to src/SignalR/benchmarkapps/Crankier/WorkerHeartbeatInformation.cs diff --git a/benchmarkapps/Crankier/WorkerReceiver.cs b/src/SignalR/benchmarkapps/Crankier/WorkerReceiver.cs similarity index 100% rename from benchmarkapps/Crankier/WorkerReceiver.cs rename to src/SignalR/benchmarkapps/Crankier/WorkerReceiver.cs diff --git a/benchmarkapps/Crankier/WorkerSender.cs b/src/SignalR/benchmarkapps/Crankier/WorkerSender.cs similarity index 100% rename from benchmarkapps/Crankier/WorkerSender.cs rename to src/SignalR/benchmarkapps/Crankier/WorkerSender.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/AssemblyInfo.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/AssemblyInfo.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/AssemblyInfo.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/AssemblyInfo.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/BroadcastBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/BroadcastBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/BroadcastBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/BroadcastBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubActivatorBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubActivatorBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubActivatorBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubActivatorBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubDispatcherBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubDispatcherBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubDispatcherBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubDispatcherBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubLifetimeManagerBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubLifetimeManagerBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubLifetimeManagerBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/DefaultHubLifetimeManagerBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HandshakeProtocolBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HandshakeProtocolBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HandshakeProtocolBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HandshakeProtocolBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionContextBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionContextBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionContextBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionContextBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionReceiveBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionReceiveBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionReceiveBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionReceiveBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionSendBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionSendBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionSendBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionSendBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionStartBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionStartBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionStartBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubConnectionStartBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubProtocolBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubProtocolBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubProtocolBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/HubProtocolBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/MessageParserBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/MessageParserBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/MessageParserBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/MessageParserBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/NegotiateProtocolBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/NegotiateProtocolBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/NegotiateProtocolBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/NegotiateProtocolBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/RedisHubLifetimeManagerBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/RedisHubLifetimeManagerBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/RedisHubLifetimeManagerBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/RedisHubLifetimeManagerBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/RedisProtocolBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/RedisProtocolBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/RedisProtocolBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/RedisProtocolBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/ServerSentEventsBenchmark.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/ServerSentEventsBenchmark.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/ServerSentEventsBenchmark.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/ServerSentEventsBenchmark.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestConnectionContext.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestConnectionContext.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestConnectionContext.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestConnectionContext.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestDuplexPipe.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestDuplexPipe.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestDuplexPipe.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestDuplexPipe.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestPipeReader.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestPipeReader.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestPipeReader.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestPipeReader.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestPipeWriter.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestPipeWriter.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestPipeWriter.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Shared/TestPipeWriter.cs diff --git a/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/TestBinder.cs b/src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/TestBinder.cs similarity index 100% rename from benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/TestBinder.cs rename to src/SignalR/benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/TestBinder.cs diff --git a/build/Key.snk b/src/SignalR/build/Key.snk similarity index 100% rename from build/Key.snk rename to src/SignalR/build/Key.snk diff --git a/build/dependencies.props b/src/SignalR/build/dependencies.props similarity index 100% rename from build/dependencies.props rename to src/SignalR/build/dependencies.props diff --git a/build/publish-apps.ps1 b/src/SignalR/build/publish-apps.ps1 similarity index 100% rename from build/publish-apps.ps1 rename to src/SignalR/build/publish-apps.ps1 diff --git a/build/repo.props b/src/SignalR/build/repo.props similarity index 100% rename from build/repo.props rename to src/SignalR/build/repo.props diff --git a/build/repo.targets b/src/SignalR/build/repo.targets similarity index 100% rename from build/repo.targets rename to src/SignalR/build/repo.targets diff --git a/build/sources.props b/src/SignalR/build/sources.props similarity index 100% rename from build/sources.props rename to src/SignalR/build/sources.props diff --git a/clients/cpp/.nuget/NuGet.Config b/src/SignalR/clients/cpp/.nuget/NuGet.Config similarity index 100% rename from clients/cpp/.nuget/NuGet.Config rename to src/SignalR/clients/cpp/.nuget/NuGet.Config diff --git a/clients/cpp/.nuget/NuGet.exe b/src/SignalR/clients/cpp/.nuget/NuGet.exe similarity index 100% rename from clients/cpp/.nuget/NuGet.exe rename to src/SignalR/clients/cpp/.nuget/NuGet.exe diff --git a/clients/cpp/.nuget/NuGet.targets b/src/SignalR/clients/cpp/.nuget/NuGet.targets similarity index 100% rename from clients/cpp/.nuget/NuGet.targets rename to src/SignalR/clients/cpp/.nuget/NuGet.targets diff --git a/clients/cpp/Build/Common.Build.Settings b/src/SignalR/clients/cpp/Build/Common.Build.Settings similarity index 100% rename from clients/cpp/Build/Common.Build.Settings rename to src/SignalR/clients/cpp/Build/Common.Build.Settings diff --git a/clients/cpp/Build/Common.tasks b/src/SignalR/clients/cpp/Build/Common.tasks similarity index 100% rename from clients/cpp/Build/Common.tasks rename to src/SignalR/clients/cpp/Build/Common.tasks diff --git a/clients/cpp/Build/Config.Definitions.Props b/src/SignalR/clients/cpp/Build/Config.Definitions.Props similarity index 100% rename from clients/cpp/Build/Config.Definitions.Props rename to src/SignalR/clients/cpp/Build/Config.Definitions.Props diff --git a/clients/cpp/Build/SignalRClient.Build.Settings b/src/SignalR/clients/cpp/Build/SignalRClient.Build.Settings similarity index 100% rename from clients/cpp/Build/SignalRClient.Build.Settings rename to src/SignalR/clients/cpp/Build/SignalRClient.Build.Settings diff --git a/clients/cpp/Build/Version.props b/src/SignalR/clients/cpp/Build/Version.props similarity index 100% rename from clients/cpp/Build/Version.props rename to src/SignalR/clients/cpp/Build/Version.props diff --git a/clients/cpp/Build/build.msbuild b/src/SignalR/clients/cpp/Build/build.msbuild similarity index 100% rename from clients/cpp/Build/build.msbuild rename to src/SignalR/clients/cpp/Build/build.msbuild diff --git a/clients/cpp/CMakeLists.txt b/src/SignalR/clients/cpp/CMakeLists.txt similarity index 100% rename from clients/cpp/CMakeLists.txt rename to src/SignalR/clients/cpp/CMakeLists.txt diff --git a/clients/cpp/CONTRIBUTING.md b/src/SignalR/clients/cpp/CONTRIBUTING.md similarity index 100% rename from clients/cpp/CONTRIBUTING.md rename to src/SignalR/clients/cpp/CONTRIBUTING.md diff --git a/clients/cpp/NuGet.config b/src/SignalR/clients/cpp/NuGet.config similarity index 100% rename from clients/cpp/NuGet.config rename to src/SignalR/clients/cpp/NuGet.config diff --git a/clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.UWP.targets.template b/src/SignalR/clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.UWP.targets.template similarity index 100% rename from clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.UWP.targets.template rename to src/SignalR/clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.UWP.targets.template diff --git a/clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.WinDesktop.targets.template b/src/SignalR/clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.WinDesktop.targets.template similarity index 100% rename from clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.WinDesktop.targets.template rename to src/SignalR/clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.WinDesktop.targets.template diff --git a/clients/cpp/NuGet/signalrclientcpp.nuspec.template b/src/SignalR/clients/cpp/NuGet/signalrclientcpp.nuspec.template similarity index 100% rename from clients/cpp/NuGet/signalrclientcpp.nuspec.template rename to src/SignalR/clients/cpp/NuGet/signalrclientcpp.nuspec.template diff --git a/clients/cpp/README.md b/src/SignalR/clients/cpp/README.md similarity index 100% rename from clients/cpp/README.md rename to src/SignalR/clients/cpp/README.md diff --git a/clients/cpp/build.cmd b/src/SignalR/clients/cpp/build.cmd similarity index 100% rename from clients/cpp/build.cmd rename to src/SignalR/clients/cpp/build.cmd diff --git a/clients/cpp/include/signalrclient/_exports.h b/src/SignalR/clients/cpp/include/signalrclient/_exports.h similarity index 100% rename from clients/cpp/include/signalrclient/_exports.h rename to src/SignalR/clients/cpp/include/signalrclient/_exports.h diff --git a/clients/cpp/include/signalrclient/connection.h b/src/SignalR/clients/cpp/include/signalrclient/connection.h similarity index 100% rename from clients/cpp/include/signalrclient/connection.h rename to src/SignalR/clients/cpp/include/signalrclient/connection.h diff --git a/clients/cpp/include/signalrclient/connection_state.h b/src/SignalR/clients/cpp/include/signalrclient/connection_state.h similarity index 100% rename from clients/cpp/include/signalrclient/connection_state.h rename to src/SignalR/clients/cpp/include/signalrclient/connection_state.h diff --git a/clients/cpp/include/signalrclient/hub_connection.h b/src/SignalR/clients/cpp/include/signalrclient/hub_connection.h similarity index 100% rename from clients/cpp/include/signalrclient/hub_connection.h rename to src/SignalR/clients/cpp/include/signalrclient/hub_connection.h diff --git a/clients/cpp/include/signalrclient/hub_exception.h b/src/SignalR/clients/cpp/include/signalrclient/hub_exception.h similarity index 100% rename from clients/cpp/include/signalrclient/hub_exception.h rename to src/SignalR/clients/cpp/include/signalrclient/hub_exception.h diff --git a/clients/cpp/include/signalrclient/log_writer.h b/src/SignalR/clients/cpp/include/signalrclient/log_writer.h similarity index 100% rename from clients/cpp/include/signalrclient/log_writer.h rename to src/SignalR/clients/cpp/include/signalrclient/log_writer.h diff --git a/clients/cpp/include/signalrclient/signalr_client_config.h b/src/SignalR/clients/cpp/include/signalrclient/signalr_client_config.h similarity index 100% rename from clients/cpp/include/signalrclient/signalr_client_config.h rename to src/SignalR/clients/cpp/include/signalrclient/signalr_client_config.h diff --git a/clients/cpp/include/signalrclient/signalr_exception.h b/src/SignalR/clients/cpp/include/signalrclient/signalr_exception.h similarity index 100% rename from clients/cpp/include/signalrclient/signalr_exception.h rename to src/SignalR/clients/cpp/include/signalrclient/signalr_exception.h diff --git a/clients/cpp/include/signalrclient/trace_level.h b/src/SignalR/clients/cpp/include/signalrclient/trace_level.h similarity index 100% rename from clients/cpp/include/signalrclient/trace_level.h rename to src/SignalR/clients/cpp/include/signalrclient/trace_level.h diff --git a/clients/cpp/include/signalrclient/transport_type.h b/src/SignalR/clients/cpp/include/signalrclient/transport_type.h similarity index 100% rename from clients/cpp/include/signalrclient/transport_type.h rename to src/SignalR/clients/cpp/include/signalrclient/transport_type.h diff --git a/clients/cpp/include/signalrclient/web_exception.h b/src/SignalR/clients/cpp/include/signalrclient/web_exception.h similarity index 100% rename from clients/cpp/include/signalrclient/web_exception.h rename to src/SignalR/clients/cpp/include/signalrclient/web_exception.h diff --git a/clients/cpp/samples.sln b/src/SignalR/clients/cpp/samples.sln similarity index 100% rename from clients/cpp/samples.sln rename to src/SignalR/clients/cpp/samples.sln diff --git a/clients/cpp/samples/HubConnectionSample/HubConnectionSample.cpp b/src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.cpp similarity index 100% rename from clients/cpp/samples/HubConnectionSample/HubConnectionSample.cpp rename to src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.cpp diff --git a/clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj b/src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj similarity index 100% rename from clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj rename to src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj diff --git a/clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj.filters b/src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj.filters similarity index 100% rename from clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj.filters rename to src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj.filters diff --git a/clients/cpp/samples/HubConnectionSample/packages.config b/src/SignalR/clients/cpp/samples/HubConnectionSample/packages.config similarity index 100% rename from clients/cpp/samples/HubConnectionSample/packages.config rename to src/SignalR/clients/cpp/samples/HubConnectionSample/packages.config diff --git a/clients/cpp/samples/HubConnectionSample/stdafx.cpp b/src/SignalR/clients/cpp/samples/HubConnectionSample/stdafx.cpp similarity index 100% rename from clients/cpp/samples/HubConnectionSample/stdafx.cpp rename to src/SignalR/clients/cpp/samples/HubConnectionSample/stdafx.cpp diff --git a/clients/cpp/samples/HubConnectionSample/stdafx.h b/src/SignalR/clients/cpp/samples/HubConnectionSample/stdafx.h similarity index 100% rename from clients/cpp/samples/HubConnectionSample/stdafx.h rename to src/SignalR/clients/cpp/samples/HubConnectionSample/stdafx.h diff --git a/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.cpp b/src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.cpp similarity index 100% rename from clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.cpp rename to src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.cpp diff --git a/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj b/src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj similarity index 100% rename from clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj rename to src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj diff --git a/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj.filters b/src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj.filters similarity index 100% rename from clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj.filters rename to src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj.filters diff --git a/clients/cpp/samples/PersistentConnectionSample/packages.config b/src/SignalR/clients/cpp/samples/PersistentConnectionSample/packages.config similarity index 100% rename from clients/cpp/samples/PersistentConnectionSample/packages.config rename to src/SignalR/clients/cpp/samples/PersistentConnectionSample/packages.config diff --git a/clients/cpp/samples/PersistentConnectionSample/stdafx.cpp b/src/SignalR/clients/cpp/samples/PersistentConnectionSample/stdafx.cpp similarity index 100% rename from clients/cpp/samples/PersistentConnectionSample/stdafx.cpp rename to src/SignalR/clients/cpp/samples/PersistentConnectionSample/stdafx.cpp diff --git a/clients/cpp/samples/PersistentConnectionSample/stdafx.h b/src/SignalR/clients/cpp/samples/PersistentConnectionSample/stdafx.h similarity index 100% rename from clients/cpp/samples/PersistentConnectionSample/stdafx.h rename to src/SignalR/clients/cpp/samples/PersistentConnectionSample/stdafx.h diff --git a/clients/cpp/samples/SignalRServer/ChatHub.cs b/src/SignalR/clients/cpp/samples/SignalRServer/ChatHub.cs similarity index 100% rename from clients/cpp/samples/SignalRServer/ChatHub.cs rename to src/SignalR/clients/cpp/samples/SignalRServer/ChatHub.cs diff --git a/clients/cpp/samples/SignalRServer/EchoConnection.cs b/src/SignalR/clients/cpp/samples/SignalRServer/EchoConnection.cs similarity index 100% rename from clients/cpp/samples/SignalRServer/EchoConnection.cs rename to src/SignalR/clients/cpp/samples/SignalRServer/EchoConnection.cs diff --git a/clients/cpp/samples/SignalRServer/Properties/AssemblyInfo.cs b/src/SignalR/clients/cpp/samples/SignalRServer/Properties/AssemblyInfo.cs similarity index 100% rename from clients/cpp/samples/SignalRServer/Properties/AssemblyInfo.cs rename to src/SignalR/clients/cpp/samples/SignalRServer/Properties/AssemblyInfo.cs diff --git a/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.intellisense.js b/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.intellisense.js similarity index 100% rename from clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.intellisense.js rename to src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.intellisense.js diff --git a/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.js b/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.js similarity index 100% rename from clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.js rename to src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.js diff --git a/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.js b/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.js similarity index 100% rename from clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.js rename to src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.js diff --git a/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.map b/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.map similarity index 100% rename from clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.map rename to src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.map diff --git a/clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.js b/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.js similarity index 100% rename from clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.js rename to src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.js diff --git a/clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.min.js b/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.min.js similarity index 100% rename from clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.min.js rename to src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.min.js diff --git a/clients/cpp/samples/SignalRServer/SignalRServer.csproj b/src/SignalR/clients/cpp/samples/SignalRServer/SignalRServer.csproj similarity index 100% rename from clients/cpp/samples/SignalRServer/SignalRServer.csproj rename to src/SignalR/clients/cpp/samples/SignalRServer/SignalRServer.csproj diff --git a/clients/cpp/samples/SignalRServer/Startup.cs b/src/SignalR/clients/cpp/samples/SignalRServer/Startup.cs similarity index 100% rename from clients/cpp/samples/SignalRServer/Startup.cs rename to src/SignalR/clients/cpp/samples/SignalRServer/Startup.cs diff --git a/clients/cpp/samples/SignalRServer/Web.Debug.config b/src/SignalR/clients/cpp/samples/SignalRServer/Web.Debug.config similarity index 100% rename from clients/cpp/samples/SignalRServer/Web.Debug.config rename to src/SignalR/clients/cpp/samples/SignalRServer/Web.Debug.config diff --git a/clients/cpp/samples/SignalRServer/Web.Release.config b/src/SignalR/clients/cpp/samples/SignalRServer/Web.Release.config similarity index 100% rename from clients/cpp/samples/SignalRServer/Web.Release.config rename to src/SignalR/clients/cpp/samples/SignalRServer/Web.Release.config diff --git a/clients/cpp/samples/SignalRServer/Web.config b/src/SignalR/clients/cpp/samples/SignalRServer/Web.config similarity index 100% rename from clients/cpp/samples/SignalRServer/Web.config rename to src/SignalR/clients/cpp/samples/SignalRServer/Web.config diff --git a/clients/cpp/samples/SignalRServer/index.html b/src/SignalR/clients/cpp/samples/SignalRServer/index.html similarity index 100% rename from clients/cpp/samples/SignalRServer/index.html rename to src/SignalR/clients/cpp/samples/SignalRServer/index.html diff --git a/clients/cpp/samples/SignalRServer/packages.config b/src/SignalR/clients/cpp/samples/SignalRServer/packages.config similarity index 100% rename from clients/cpp/samples/SignalRServer/packages.config rename to src/SignalR/clients/cpp/samples/SignalRServer/packages.config diff --git a/clients/cpp/signalrclient.sln b/src/SignalR/clients/cpp/signalrclient.sln similarity index 100% rename from clients/cpp/signalrclient.sln rename to src/SignalR/clients/cpp/signalrclient.sln diff --git a/clients/cpp/src/signalrclient/Build/VS/packages.config b/src/SignalR/clients/cpp/src/signalrclient/Build/VS/packages.config similarity index 100% rename from clients/cpp/src/signalrclient/Build/VS/packages.config rename to src/SignalR/clients/cpp/src/signalrclient/Build/VS/packages.config diff --git a/clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj b/src/SignalR/clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj similarity index 100% rename from clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj rename to src/SignalR/clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj diff --git a/clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj.filters b/src/SignalR/clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj.filters similarity index 100% rename from clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj.filters rename to src/SignalR/clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj.filters diff --git a/clients/cpp/src/signalrclient/CMakeLists.txt b/src/SignalR/clients/cpp/src/signalrclient/CMakeLists.txt similarity index 100% rename from clients/cpp/src/signalrclient/CMakeLists.txt rename to src/SignalR/clients/cpp/src/signalrclient/CMakeLists.txt diff --git a/clients/cpp/src/signalrclient/callback_manager.cpp b/src/SignalR/clients/cpp/src/signalrclient/callback_manager.cpp similarity index 100% rename from clients/cpp/src/signalrclient/callback_manager.cpp rename to src/SignalR/clients/cpp/src/signalrclient/callback_manager.cpp diff --git a/clients/cpp/src/signalrclient/callback_manager.h b/src/SignalR/clients/cpp/src/signalrclient/callback_manager.h similarity index 100% rename from clients/cpp/src/signalrclient/callback_manager.h rename to src/SignalR/clients/cpp/src/signalrclient/callback_manager.h diff --git a/clients/cpp/src/signalrclient/case_insensitive_comparison_utils.h b/src/SignalR/clients/cpp/src/signalrclient/case_insensitive_comparison_utils.h similarity index 100% rename from clients/cpp/src/signalrclient/case_insensitive_comparison_utils.h rename to src/SignalR/clients/cpp/src/signalrclient/case_insensitive_comparison_utils.h diff --git a/clients/cpp/src/signalrclient/connection.cpp b/src/SignalR/clients/cpp/src/signalrclient/connection.cpp similarity index 100% rename from clients/cpp/src/signalrclient/connection.cpp rename to src/SignalR/clients/cpp/src/signalrclient/connection.cpp diff --git a/clients/cpp/src/signalrclient/connection_impl.cpp b/src/SignalR/clients/cpp/src/signalrclient/connection_impl.cpp similarity index 100% rename from clients/cpp/src/signalrclient/connection_impl.cpp rename to src/SignalR/clients/cpp/src/signalrclient/connection_impl.cpp diff --git a/clients/cpp/src/signalrclient/connection_impl.h b/src/SignalR/clients/cpp/src/signalrclient/connection_impl.h similarity index 100% rename from clients/cpp/src/signalrclient/connection_impl.h rename to src/SignalR/clients/cpp/src/signalrclient/connection_impl.h diff --git a/clients/cpp/src/signalrclient/constants.h b/src/SignalR/clients/cpp/src/signalrclient/constants.h similarity index 100% rename from clients/cpp/src/signalrclient/constants.h rename to src/SignalR/clients/cpp/src/signalrclient/constants.h diff --git a/clients/cpp/src/signalrclient/default_websocket_client.cpp b/src/SignalR/clients/cpp/src/signalrclient/default_websocket_client.cpp similarity index 100% rename from clients/cpp/src/signalrclient/default_websocket_client.cpp rename to src/SignalR/clients/cpp/src/signalrclient/default_websocket_client.cpp diff --git a/clients/cpp/src/signalrclient/default_websocket_client.h b/src/SignalR/clients/cpp/src/signalrclient/default_websocket_client.h similarity index 100% rename from clients/cpp/src/signalrclient/default_websocket_client.h rename to src/SignalR/clients/cpp/src/signalrclient/default_websocket_client.h diff --git a/clients/cpp/src/signalrclient/event.h b/src/SignalR/clients/cpp/src/signalrclient/event.h similarity index 100% rename from clients/cpp/src/signalrclient/event.h rename to src/SignalR/clients/cpp/src/signalrclient/event.h diff --git a/clients/cpp/src/signalrclient/http_sender.cpp b/src/SignalR/clients/cpp/src/signalrclient/http_sender.cpp similarity index 100% rename from clients/cpp/src/signalrclient/http_sender.cpp rename to src/SignalR/clients/cpp/src/signalrclient/http_sender.cpp diff --git a/clients/cpp/src/signalrclient/http_sender.h b/src/SignalR/clients/cpp/src/signalrclient/http_sender.h similarity index 100% rename from clients/cpp/src/signalrclient/http_sender.h rename to src/SignalR/clients/cpp/src/signalrclient/http_sender.h diff --git a/clients/cpp/src/signalrclient/hub_connection.cpp b/src/SignalR/clients/cpp/src/signalrclient/hub_connection.cpp similarity index 100% rename from clients/cpp/src/signalrclient/hub_connection.cpp rename to src/SignalR/clients/cpp/src/signalrclient/hub_connection.cpp diff --git a/clients/cpp/src/signalrclient/hub_connection_impl.cpp b/src/SignalR/clients/cpp/src/signalrclient/hub_connection_impl.cpp similarity index 100% rename from clients/cpp/src/signalrclient/hub_connection_impl.cpp rename to src/SignalR/clients/cpp/src/signalrclient/hub_connection_impl.cpp diff --git a/clients/cpp/src/signalrclient/hub_connection_impl.h b/src/SignalR/clients/cpp/src/signalrclient/hub_connection_impl.h similarity index 100% rename from clients/cpp/src/signalrclient/hub_connection_impl.h rename to src/SignalR/clients/cpp/src/signalrclient/hub_connection_impl.h diff --git a/clients/cpp/src/signalrclient/logger.cpp b/src/SignalR/clients/cpp/src/signalrclient/logger.cpp similarity index 100% rename from clients/cpp/src/signalrclient/logger.cpp rename to src/SignalR/clients/cpp/src/signalrclient/logger.cpp diff --git a/clients/cpp/src/signalrclient/logger.h b/src/SignalR/clients/cpp/src/signalrclient/logger.h similarity index 100% rename from clients/cpp/src/signalrclient/logger.h rename to src/SignalR/clients/cpp/src/signalrclient/logger.h diff --git a/clients/cpp/src/signalrclient/make_unique.h b/src/SignalR/clients/cpp/src/signalrclient/make_unique.h similarity index 100% rename from clients/cpp/src/signalrclient/make_unique.h rename to src/SignalR/clients/cpp/src/signalrclient/make_unique.h diff --git a/clients/cpp/src/signalrclient/negotiation_response.cpp b/src/SignalR/clients/cpp/src/signalrclient/negotiation_response.cpp similarity index 100% rename from clients/cpp/src/signalrclient/negotiation_response.cpp rename to src/SignalR/clients/cpp/src/signalrclient/negotiation_response.cpp diff --git a/clients/cpp/src/signalrclient/negotiation_response.h b/src/SignalR/clients/cpp/src/signalrclient/negotiation_response.h similarity index 100% rename from clients/cpp/src/signalrclient/negotiation_response.h rename to src/SignalR/clients/cpp/src/signalrclient/negotiation_response.h diff --git a/clients/cpp/src/signalrclient/request_sender.cpp b/src/SignalR/clients/cpp/src/signalrclient/request_sender.cpp similarity index 100% rename from clients/cpp/src/signalrclient/request_sender.cpp rename to src/SignalR/clients/cpp/src/signalrclient/request_sender.cpp diff --git a/clients/cpp/src/signalrclient/request_sender.h b/src/SignalR/clients/cpp/src/signalrclient/request_sender.h similarity index 100% rename from clients/cpp/src/signalrclient/request_sender.h rename to src/SignalR/clients/cpp/src/signalrclient/request_sender.h diff --git a/clients/cpp/src/signalrclient/signalr_client_config.cpp b/src/SignalR/clients/cpp/src/signalrclient/signalr_client_config.cpp similarity index 100% rename from clients/cpp/src/signalrclient/signalr_client_config.cpp rename to src/SignalR/clients/cpp/src/signalrclient/signalr_client_config.cpp diff --git a/clients/cpp/src/signalrclient/stdafx.cpp b/src/SignalR/clients/cpp/src/signalrclient/stdafx.cpp similarity index 100% rename from clients/cpp/src/signalrclient/stdafx.cpp rename to src/SignalR/clients/cpp/src/signalrclient/stdafx.cpp diff --git a/clients/cpp/src/signalrclient/stdafx.h b/src/SignalR/clients/cpp/src/signalrclient/stdafx.h similarity index 100% rename from clients/cpp/src/signalrclient/stdafx.h rename to src/SignalR/clients/cpp/src/signalrclient/stdafx.h diff --git a/clients/cpp/src/signalrclient/trace_log_writer.cpp b/src/SignalR/clients/cpp/src/signalrclient/trace_log_writer.cpp similarity index 100% rename from clients/cpp/src/signalrclient/trace_log_writer.cpp rename to src/SignalR/clients/cpp/src/signalrclient/trace_log_writer.cpp diff --git a/clients/cpp/src/signalrclient/trace_log_writer.h b/src/SignalR/clients/cpp/src/signalrclient/trace_log_writer.h similarity index 100% rename from clients/cpp/src/signalrclient/trace_log_writer.h rename to src/SignalR/clients/cpp/src/signalrclient/trace_log_writer.h diff --git a/clients/cpp/src/signalrclient/transport.cpp b/src/SignalR/clients/cpp/src/signalrclient/transport.cpp similarity index 100% rename from clients/cpp/src/signalrclient/transport.cpp rename to src/SignalR/clients/cpp/src/signalrclient/transport.cpp diff --git a/clients/cpp/src/signalrclient/transport.h b/src/SignalR/clients/cpp/src/signalrclient/transport.h similarity index 100% rename from clients/cpp/src/signalrclient/transport.h rename to src/SignalR/clients/cpp/src/signalrclient/transport.h diff --git a/clients/cpp/src/signalrclient/transport_factory.cpp b/src/SignalR/clients/cpp/src/signalrclient/transport_factory.cpp similarity index 100% rename from clients/cpp/src/signalrclient/transport_factory.cpp rename to src/SignalR/clients/cpp/src/signalrclient/transport_factory.cpp diff --git a/clients/cpp/src/signalrclient/transport_factory.h b/src/SignalR/clients/cpp/src/signalrclient/transport_factory.h similarity index 100% rename from clients/cpp/src/signalrclient/transport_factory.h rename to src/SignalR/clients/cpp/src/signalrclient/transport_factory.h diff --git a/clients/cpp/src/signalrclient/url_builder.cpp b/src/SignalR/clients/cpp/src/signalrclient/url_builder.cpp similarity index 100% rename from clients/cpp/src/signalrclient/url_builder.cpp rename to src/SignalR/clients/cpp/src/signalrclient/url_builder.cpp diff --git a/clients/cpp/src/signalrclient/url_builder.h b/src/SignalR/clients/cpp/src/signalrclient/url_builder.h similarity index 100% rename from clients/cpp/src/signalrclient/url_builder.h rename to src/SignalR/clients/cpp/src/signalrclient/url_builder.h diff --git a/clients/cpp/src/signalrclient/web_request.cpp b/src/SignalR/clients/cpp/src/signalrclient/web_request.cpp similarity index 100% rename from clients/cpp/src/signalrclient/web_request.cpp rename to src/SignalR/clients/cpp/src/signalrclient/web_request.cpp diff --git a/clients/cpp/src/signalrclient/web_request.h b/src/SignalR/clients/cpp/src/signalrclient/web_request.h similarity index 100% rename from clients/cpp/src/signalrclient/web_request.h rename to src/SignalR/clients/cpp/src/signalrclient/web_request.h diff --git a/clients/cpp/src/signalrclient/web_request_factory.cpp b/src/SignalR/clients/cpp/src/signalrclient/web_request_factory.cpp similarity index 100% rename from clients/cpp/src/signalrclient/web_request_factory.cpp rename to src/SignalR/clients/cpp/src/signalrclient/web_request_factory.cpp diff --git a/clients/cpp/src/signalrclient/web_request_factory.h b/src/SignalR/clients/cpp/src/signalrclient/web_request_factory.h similarity index 100% rename from clients/cpp/src/signalrclient/web_request_factory.h rename to src/SignalR/clients/cpp/src/signalrclient/web_request_factory.h diff --git a/clients/cpp/src/signalrclient/web_response.h b/src/SignalR/clients/cpp/src/signalrclient/web_response.h similarity index 100% rename from clients/cpp/src/signalrclient/web_response.h rename to src/SignalR/clients/cpp/src/signalrclient/web_response.h diff --git a/clients/cpp/src/signalrclient/websocket_client.h b/src/SignalR/clients/cpp/src/signalrclient/websocket_client.h similarity index 100% rename from clients/cpp/src/signalrclient/websocket_client.h rename to src/SignalR/clients/cpp/src/signalrclient/websocket_client.h diff --git a/clients/cpp/src/signalrclient/websocket_transport.cpp b/src/SignalR/clients/cpp/src/signalrclient/websocket_transport.cpp similarity index 100% rename from clients/cpp/src/signalrclient/websocket_transport.cpp rename to src/SignalR/clients/cpp/src/signalrclient/websocket_transport.cpp diff --git a/clients/cpp/src/signalrclient/websocket_transport.h b/src/SignalR/clients/cpp/src/signalrclient/websocket_transport.h similarity index 100% rename from clients/cpp/src/signalrclient/websocket_transport.h rename to src/SignalR/clients/cpp/src/signalrclient/websocket_transport.h diff --git a/clients/cpp/src/signalrclientdll/Build/VS/packages.config b/src/SignalR/clients/cpp/src/signalrclientdll/Build/VS/packages.config similarity index 100% rename from clients/cpp/src/signalrclientdll/Build/VS/packages.config rename to src/SignalR/clients/cpp/src/signalrclientdll/Build/VS/packages.config diff --git a/clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj b/src/SignalR/clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj similarity index 100% rename from clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj rename to src/SignalR/clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj diff --git a/clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj.filters b/src/SignalR/clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj.filters similarity index 100% rename from clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj.filters rename to src/SignalR/clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj.filters diff --git a/clients/cpp/src/signalrclientdll/Resource.rc b/src/SignalR/clients/cpp/src/signalrclientdll/Resource.rc similarity index 100% rename from clients/cpp/src/signalrclientdll/Resource.rc rename to src/SignalR/clients/cpp/src/signalrclientdll/Resource.rc diff --git a/clients/cpp/src/signalrclientdll/dllmain.cpp b/src/SignalR/clients/cpp/src/signalrclientdll/dllmain.cpp similarity index 100% rename from clients/cpp/src/signalrclientdll/dllmain.cpp rename to src/SignalR/clients/cpp/src/signalrclientdll/dllmain.cpp diff --git a/clients/cpp/src/signalrclientdll/resource.h b/src/SignalR/clients/cpp/src/signalrclientdll/resource.h similarity index 100% rename from clients/cpp/src/signalrclientdll/resource.h rename to src/SignalR/clients/cpp/src/signalrclientdll/resource.h diff --git a/clients/cpp/src/signalrclientdll/version.h b/src/SignalR/clients/cpp/src/signalrclientdll/version.h similarity index 100% rename from clients/cpp/src/signalrclientdll/version.h rename to src/SignalR/clients/cpp/src/signalrclientdll/version.h diff --git a/clients/cpp/test/CMakeLists.txt b/src/SignalR/clients/cpp/test/CMakeLists.txt similarity index 100% rename from clients/cpp/test/CMakeLists.txt rename to src/SignalR/clients/cpp/test/CMakeLists.txt diff --git a/clients/cpp/test/gtest/gtest.vcxproj b/src/SignalR/clients/cpp/test/gtest/gtest.vcxproj similarity index 100% rename from clients/cpp/test/gtest/gtest.vcxproj rename to src/SignalR/clients/cpp/test/gtest/gtest.vcxproj diff --git a/clients/cpp/test/gtest/gtest.vcxproj.filters b/src/SignalR/clients/cpp/test/gtest/gtest.vcxproj.filters similarity index 100% rename from clients/cpp/test/gtest/gtest.vcxproj.filters rename to src/SignalR/clients/cpp/test/gtest/gtest.vcxproj.filters diff --git a/clients/cpp/test/signalrclient-e2e-tests/Build/VS/packages.config b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/Build/VS/packages.config similarity index 100% rename from clients/cpp/test/signalrclient-e2e-tests/Build/VS/packages.config rename to src/SignalR/clients/cpp/test/signalrclient-e2e-tests/Build/VS/packages.config diff --git a/clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj similarity index 100% rename from clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj rename to src/SignalR/clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj diff --git a/clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj.filters b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj.filters similarity index 100% rename from clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj.filters rename to src/SignalR/clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj.filters diff --git a/clients/cpp/test/signalrclient-e2e-tests/connection_tests.cpp b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/connection_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclient-e2e-tests/connection_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclient-e2e-tests/connection_tests.cpp diff --git a/clients/cpp/test/signalrclient-e2e-tests/hub_connection_tests.cpp b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/hub_connection_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclient-e2e-tests/hub_connection_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclient-e2e-tests/hub_connection_tests.cpp diff --git a/clients/cpp/test/signalrclient-e2e-tests/signalrclient-e2e-tests.cpp b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/signalrclient-e2e-tests.cpp similarity index 100% rename from clients/cpp/test/signalrclient-e2e-tests/signalrclient-e2e-tests.cpp rename to src/SignalR/clients/cpp/test/signalrclient-e2e-tests/signalrclient-e2e-tests.cpp diff --git a/clients/cpp/test/signalrclient-e2e-tests/stdafx.cpp b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/stdafx.cpp similarity index 100% rename from clients/cpp/test/signalrclient-e2e-tests/stdafx.cpp rename to src/SignalR/clients/cpp/test/signalrclient-e2e-tests/stdafx.cpp diff --git a/clients/cpp/test/signalrclient-e2e-tests/stdafx.h b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/stdafx.h similarity index 100% rename from clients/cpp/test/signalrclient-e2e-tests/stdafx.h rename to src/SignalR/clients/cpp/test/signalrclient-e2e-tests/stdafx.h diff --git a/clients/cpp/test/signalrclient-e2e-tests/test_utils.cpp b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/test_utils.cpp similarity index 100% rename from clients/cpp/test/signalrclient-e2e-tests/test_utils.cpp rename to src/SignalR/clients/cpp/test/signalrclient-e2e-tests/test_utils.cpp diff --git a/clients/cpp/test/signalrclient-e2e-tests/test_utils.h b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/test_utils.h similarity index 100% rename from clients/cpp/test/signalrclient-e2e-tests/test_utils.h rename to src/SignalR/clients/cpp/test/signalrclient-e2e-tests/test_utils.h diff --git a/clients/cpp/test/signalrclient-testhost/App.config b/src/SignalR/clients/cpp/test/signalrclient-testhost/App.config similarity index 100% rename from clients/cpp/test/signalrclient-testhost/App.config rename to src/SignalR/clients/cpp/test/signalrclient-testhost/App.config diff --git a/clients/cpp/test/signalrclient-testhost/Connections/HubConnection.cs b/src/SignalR/clients/cpp/test/signalrclient-testhost/Connections/HubConnection.cs similarity index 100% rename from clients/cpp/test/signalrclient-testhost/Connections/HubConnection.cs rename to src/SignalR/clients/cpp/test/signalrclient-testhost/Connections/HubConnection.cs diff --git a/clients/cpp/test/signalrclient-testhost/Connections/RawConnection.cs b/src/SignalR/clients/cpp/test/signalrclient-testhost/Connections/RawConnection.cs similarity index 100% rename from clients/cpp/test/signalrclient-testhost/Connections/RawConnection.cs rename to src/SignalR/clients/cpp/test/signalrclient-testhost/Connections/RawConnection.cs diff --git a/clients/cpp/test/signalrclient-testhost/Program.cs b/src/SignalR/clients/cpp/test/signalrclient-testhost/Program.cs similarity index 100% rename from clients/cpp/test/signalrclient-testhost/Program.cs rename to src/SignalR/clients/cpp/test/signalrclient-testhost/Program.cs diff --git a/clients/cpp/test/signalrclient-testhost/Properties/AssemblyInfo.cs b/src/SignalR/clients/cpp/test/signalrclient-testhost/Properties/AssemblyInfo.cs similarity index 100% rename from clients/cpp/test/signalrclient-testhost/Properties/AssemblyInfo.cs rename to src/SignalR/clients/cpp/test/signalrclient-testhost/Properties/AssemblyInfo.cs diff --git a/clients/cpp/test/signalrclient-testhost/Startup.cs b/src/SignalR/clients/cpp/test/signalrclient-testhost/Startup.cs similarity index 100% rename from clients/cpp/test/signalrclient-testhost/Startup.cs rename to src/SignalR/clients/cpp/test/signalrclient-testhost/Startup.cs diff --git a/clients/cpp/test/signalrclient-testhost/packages.config b/src/SignalR/clients/cpp/test/signalrclient-testhost/packages.config similarity index 100% rename from clients/cpp/test/signalrclient-testhost/packages.config rename to src/SignalR/clients/cpp/test/signalrclient-testhost/packages.config diff --git a/clients/cpp/test/signalrclient-testhost/signalrclient-testhost.csproj b/src/SignalR/clients/cpp/test/signalrclient-testhost/signalrclient-testhost.csproj similarity index 100% rename from clients/cpp/test/signalrclient-testhost/signalrclient-testhost.csproj rename to src/SignalR/clients/cpp/test/signalrclient-testhost/signalrclient-testhost.csproj diff --git a/clients/cpp/test/signalrclienttests/Build/VS/packages.config b/src/SignalR/clients/cpp/test/signalrclienttests/Build/VS/packages.config similarity index 100% rename from clients/cpp/test/signalrclienttests/Build/VS/packages.config rename to src/SignalR/clients/cpp/test/signalrclienttests/Build/VS/packages.config diff --git a/clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj b/src/SignalR/clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj similarity index 100% rename from clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj rename to src/SignalR/clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj diff --git a/clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj.filters b/src/SignalR/clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj.filters similarity index 100% rename from clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj.filters rename to src/SignalR/clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj.filters diff --git a/clients/cpp/test/signalrclienttests/CMakeLists.txt b/src/SignalR/clients/cpp/test/signalrclienttests/CMakeLists.txt similarity index 100% rename from clients/cpp/test/signalrclienttests/CMakeLists.txt rename to src/SignalR/clients/cpp/test/signalrclienttests/CMakeLists.txt diff --git a/clients/cpp/test/signalrclienttests/callback_manager_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/callback_manager_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/callback_manager_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/callback_manager_tests.cpp diff --git a/clients/cpp/test/signalrclienttests/case_insensitive_comparison_utils_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/case_insensitive_comparison_utils_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/case_insensitive_comparison_utils_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/case_insensitive_comparison_utils_tests.cpp diff --git a/clients/cpp/test/signalrclienttests/connection_impl_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/connection_impl_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/connection_impl_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/connection_impl_tests.cpp diff --git a/clients/cpp/test/signalrclienttests/http_sender_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/http_sender_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/http_sender_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/http_sender_tests.cpp diff --git a/clients/cpp/test/signalrclienttests/hub_connection_impl_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/hub_connection_impl_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/hub_connection_impl_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/hub_connection_impl_tests.cpp diff --git a/clients/cpp/test/signalrclienttests/hub_exception_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/hub_exception_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/hub_exception_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/hub_exception_tests.cpp diff --git a/clients/cpp/test/signalrclienttests/internal_hub_proxy_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/internal_hub_proxy_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/internal_hub_proxy_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/internal_hub_proxy_tests.cpp diff --git a/clients/cpp/test/signalrclienttests/logger_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/logger_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/logger_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/logger_tests.cpp diff --git a/clients/cpp/test/signalrclienttests/memory_log_writer.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/memory_log_writer.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/memory_log_writer.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/memory_log_writer.cpp diff --git a/clients/cpp/test/signalrclienttests/memory_log_writer.h b/src/SignalR/clients/cpp/test/signalrclienttests/memory_log_writer.h similarity index 100% rename from clients/cpp/test/signalrclienttests/memory_log_writer.h rename to src/SignalR/clients/cpp/test/signalrclienttests/memory_log_writer.h diff --git a/clients/cpp/test/signalrclienttests/request_sender_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/request_sender_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/request_sender_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/request_sender_tests.cpp diff --git a/clients/cpp/test/signalrclienttests/signalrclienttests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/signalrclienttests.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/signalrclienttests.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/signalrclienttests.cpp diff --git a/clients/cpp/test/signalrclienttests/stdafx.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/stdafx.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/stdafx.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/stdafx.cpp diff --git a/clients/cpp/test/signalrclienttests/stdafx.h b/src/SignalR/clients/cpp/test/signalrclienttests/stdafx.h similarity index 100% rename from clients/cpp/test/signalrclienttests/stdafx.h rename to src/SignalR/clients/cpp/test/signalrclienttests/stdafx.h diff --git a/clients/cpp/test/signalrclienttests/targetver.h b/src/SignalR/clients/cpp/test/signalrclienttests/targetver.h similarity index 100% rename from clients/cpp/test/signalrclienttests/targetver.h rename to src/SignalR/clients/cpp/test/signalrclienttests/targetver.h diff --git a/clients/cpp/test/signalrclienttests/test_transport_factory.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/test_transport_factory.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/test_transport_factory.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/test_transport_factory.cpp diff --git a/clients/cpp/test/signalrclienttests/test_transport_factory.h b/src/SignalR/clients/cpp/test/signalrclienttests/test_transport_factory.h similarity index 100% rename from clients/cpp/test/signalrclienttests/test_transport_factory.h rename to src/SignalR/clients/cpp/test/signalrclienttests/test_transport_factory.h diff --git a/clients/cpp/test/signalrclienttests/test_utils.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/test_utils.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/test_utils.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/test_utils.cpp diff --git a/clients/cpp/test/signalrclienttests/test_utils.h b/src/SignalR/clients/cpp/test/signalrclienttests/test_utils.h similarity index 100% rename from clients/cpp/test/signalrclienttests/test_utils.h rename to src/SignalR/clients/cpp/test/signalrclienttests/test_utils.h diff --git a/clients/cpp/test/signalrclienttests/test_web_request_factory.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/test_web_request_factory.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/test_web_request_factory.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/test_web_request_factory.cpp diff --git a/clients/cpp/test/signalrclienttests/test_web_request_factory.h b/src/SignalR/clients/cpp/test/signalrclienttests/test_web_request_factory.h similarity index 100% rename from clients/cpp/test/signalrclienttests/test_web_request_factory.h rename to src/SignalR/clients/cpp/test/signalrclienttests/test_web_request_factory.h diff --git a/clients/cpp/test/signalrclienttests/test_websocket_client.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/test_websocket_client.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/test_websocket_client.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/test_websocket_client.cpp diff --git a/clients/cpp/test/signalrclienttests/test_websocket_client.h b/src/SignalR/clients/cpp/test/signalrclienttests/test_websocket_client.h similarity index 100% rename from clients/cpp/test/signalrclienttests/test_websocket_client.h rename to src/SignalR/clients/cpp/test/signalrclienttests/test_websocket_client.h diff --git a/clients/cpp/test/signalrclienttests/url_builder_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/url_builder_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/url_builder_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/url_builder_tests.cpp diff --git a/clients/cpp/test/signalrclienttests/web_request_stub.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/web_request_stub.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/web_request_stub.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/web_request_stub.cpp diff --git a/clients/cpp/test/signalrclienttests/web_request_stub.h b/src/SignalR/clients/cpp/test/signalrclienttests/web_request_stub.h similarity index 100% rename from clients/cpp/test/signalrclienttests/web_request_stub.h rename to src/SignalR/clients/cpp/test/signalrclienttests/web_request_stub.h diff --git a/clients/cpp/test/signalrclienttests/web_request_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/web_request_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/web_request_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/web_request_tests.cpp diff --git a/clients/cpp/test/signalrclienttests/websocket_transport_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/websocket_transport_tests.cpp similarity index 100% rename from clients/cpp/test/signalrclienttests/websocket_transport_tests.cpp rename to src/SignalR/clients/cpp/test/signalrclienttests/websocket_transport_tests.cpp diff --git a/clients/java/signalr/.gitignore b/src/SignalR/clients/java/signalr/.gitignore similarity index 100% rename from clients/java/signalr/.gitignore rename to src/SignalR/clients/java/signalr/.gitignore diff --git a/clients/java/signalr/build.gradle b/src/SignalR/clients/java/signalr/build.gradle similarity index 100% rename from clients/java/signalr/build.gradle rename to src/SignalR/clients/java/signalr/build.gradle diff --git a/clients/java/signalr/gradle/wrapper/gradle-wrapper.jar b/src/SignalR/clients/java/signalr/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from clients/java/signalr/gradle/wrapper/gradle-wrapper.jar rename to src/SignalR/clients/java/signalr/gradle/wrapper/gradle-wrapper.jar diff --git a/clients/java/signalr/gradle/wrapper/gradle-wrapper.properties b/src/SignalR/clients/java/signalr/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from clients/java/signalr/gradle/wrapper/gradle-wrapper.properties rename to src/SignalR/clients/java/signalr/gradle/wrapper/gradle-wrapper.properties diff --git a/clients/java/signalr/gradlew b/src/SignalR/clients/java/signalr/gradlew old mode 100755 new mode 100644 similarity index 100% rename from clients/java/signalr/gradlew rename to src/SignalR/clients/java/signalr/gradlew diff --git a/clients/java/signalr/gradlew.bat b/src/SignalR/clients/java/signalr/gradlew.bat similarity index 100% rename from clients/java/signalr/gradlew.bat rename to src/SignalR/clients/java/signalr/gradlew.bat diff --git a/clients/java/signalr/settings.gradle b/src/SignalR/clients/java/signalr/settings.gradle similarity index 100% rename from clients/java/signalr/settings.gradle rename to src/SignalR/clients/java/signalr/settings.gradle diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/Action.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/Action.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/Action1.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action1.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/Action1.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action1.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/Action2.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action2.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/Action2.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action2.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/Action3.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action3.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/Action3.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action3.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/Action4.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action4.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/Action4.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action4.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/Action5.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action5.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/Action5.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action5.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/Action6.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action6.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/Action6.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action6.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/Action7.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action7.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/Action7.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action7.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/Action8.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action8.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/Action8.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Action8.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/ActionBase.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/ActionBase.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/ActionBase.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/ActionBase.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/CallbackMap.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/CallbackMap.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/CallbackMap.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/CallbackMap.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/CancelInvocationMessage.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/CancelInvocationMessage.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/CancelInvocationMessage.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/CancelInvocationMessage.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/CloseMessage.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/CloseMessage.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/CloseMessage.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/CloseMessage.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/CompletionMessage.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/CompletionMessage.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/CompletionMessage.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/CompletionMessage.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/DefaultHttpClient.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/DefaultHttpClient.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/DefaultHttpClient.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/DefaultHttpClient.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/HandshakeProtocol.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HandshakeProtocol.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/HandshakeProtocol.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HandshakeProtocol.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/HandshakeRequestMessage.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HandshakeRequestMessage.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/HandshakeRequestMessage.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HandshakeRequestMessage.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/HandshakeResponseMessage.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HandshakeResponseMessage.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/HandshakeResponseMessage.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HandshakeResponseMessage.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/HttpClient.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HttpClient.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/HttpClient.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HttpClient.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/HttpHubConnectionBuilder.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HttpHubConnectionBuilder.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/HttpHubConnectionBuilder.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HttpHubConnectionBuilder.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnection.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnectionBuilder.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnectionBuilder.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnectionBuilder.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnectionBuilder.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnectionState.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnectionState.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnectionState.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubConnectionState.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/HubException.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubException.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/HubException.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubException.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/HubMessage.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubMessage.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/HubMessage.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubMessage.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/HubMessageType.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubMessageType.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/HubMessageType.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubMessageType.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/HubProtocol.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubProtocol.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/HubProtocol.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/HubProtocol.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationBinder.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationBinder.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationBinder.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationBinder.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationBindingFailureMessage.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationBindingFailureMessage.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationBindingFailureMessage.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationBindingFailureMessage.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationHandler.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationHandler.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationHandler.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationHandler.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationMessage.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationMessage.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationMessage.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationMessage.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationRequest.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationRequest.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationRequest.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/InvocationRequest.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/JsonHubProtocol.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/JsonHubProtocol.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/JsonHubProtocol.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/JsonHubProtocol.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/Negotiate.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Negotiate.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/Negotiate.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Negotiate.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/NegotiateResponse.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/NegotiateResponse.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/NegotiateResponse.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/NegotiateResponse.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/OkHttpWebSocketWrapper.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/OkHttpWebSocketWrapper.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/OkHttpWebSocketWrapper.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/OkHttpWebSocketWrapper.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/OnClosedCallback.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/OnClosedCallback.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/OnClosedCallback.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/OnClosedCallback.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/OnReceiveCallBack.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/OnReceiveCallBack.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/OnReceiveCallBack.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/OnReceiveCallBack.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/PingMessage.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/PingMessage.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/PingMessage.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/PingMessage.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamInvocationMessage.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamInvocationMessage.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/StreamInvocationMessage.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamInvocationMessage.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamItem.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamItem.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/StreamItem.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/StreamItem.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/Subscription.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Subscription.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/Subscription.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Subscription.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/TransferFormat.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/TransferFormat.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/TransferFormat.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/TransferFormat.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/Transport.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Transport.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/Transport.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/Transport.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/TransportOnClosedCallback.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/TransportOnClosedCallback.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/TransportOnClosedCallback.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/TransportOnClosedCallback.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/WebSocketTransport.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/WebSocketTransport.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/WebSocketTransport.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/WebSocketTransport.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/WebSocketWrapper.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/WebSocketWrapper.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/WebSocketWrapper.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/WebSocketWrapper.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/WebsocketWrapperOnClosed.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/WebsocketWrapperOnClosed.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/WebsocketWrapperOnClosed.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/WebsocketWrapperOnClosed.java diff --git a/clients/java/signalr/src/main/java/com/microsoft/signalr/package-info.java b/src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/package-info.java similarity index 100% rename from clients/java/signalr/src/main/java/com/microsoft/signalr/package-info.java rename to src/SignalR/clients/java/signalr/src/main/java/com/microsoft/signalr/package-info.java diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/HandshakeProtocolTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HandshakeProtocolTest.java similarity index 100% rename from clients/java/signalr/src/test/java/com/microsoft/signalr/HandshakeProtocolTest.java rename to src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HandshakeProtocolTest.java diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionBuilderTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionBuilderTest.java similarity index 100% rename from clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionBuilderTest.java rename to src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionBuilderTest.java diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java similarity index 100% rename from clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java rename to src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubConnectionTest.java diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/HubExceptionTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubExceptionTest.java similarity index 100% rename from clients/java/signalr/src/test/java/com/microsoft/signalr/HubExceptionTest.java rename to src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/HubExceptionTest.java diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/JsonHubProtocolTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/JsonHubProtocolTest.java similarity index 100% rename from clients/java/signalr/src/test/java/com/microsoft/signalr/JsonHubProtocolTest.java rename to src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/JsonHubProtocolTest.java diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/MockTransport.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/MockTransport.java similarity index 100% rename from clients/java/signalr/src/test/java/com/microsoft/signalr/MockTransport.java rename to src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/MockTransport.java diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/NegotiateResponseTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/NegotiateResponseTest.java similarity index 100% rename from clients/java/signalr/src/test/java/com/microsoft/signalr/NegotiateResponseTest.java rename to src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/NegotiateResponseTest.java diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/ResolveNegotiateUrlTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/ResolveNegotiateUrlTest.java similarity index 100% rename from clients/java/signalr/src/test/java/com/microsoft/signalr/ResolveNegotiateUrlTest.java rename to src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/ResolveNegotiateUrlTest.java diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/TestHttpClient.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/TestHttpClient.java similarity index 100% rename from clients/java/signalr/src/test/java/com/microsoft/signalr/TestHttpClient.java rename to src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/TestHttpClient.java diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/TestUtils.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/TestUtils.java similarity index 100% rename from clients/java/signalr/src/test/java/com/microsoft/signalr/TestUtils.java rename to src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/TestUtils.java diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/WebSocketTransportTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/WebSocketTransportTest.java similarity index 100% rename from clients/java/signalr/src/test/java/com/microsoft/signalr/WebSocketTransportTest.java rename to src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/WebSocketTransportTest.java diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/WebSocketTransportUrlFormatTest.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/WebSocketTransportUrlFormatTest.java similarity index 100% rename from clients/java/signalr/src/test/java/com/microsoft/signalr/WebSocketTransportUrlFormatTest.java rename to src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/WebSocketTransportUrlFormatTest.java diff --git a/clients/java/signalr/src/test/java/com/microsoft/signalr/sample/Chat.java b/src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/sample/Chat.java similarity index 100% rename from clients/java/signalr/src/test/java/com/microsoft/signalr/sample/Chat.java rename to src/SignalR/clients/java/signalr/src/test/java/com/microsoft/signalr/sample/Chat.java diff --git a/clients/ts/FunctionalTests/.gitignore b/src/SignalR/clients/ts/FunctionalTests/.gitignore similarity index 100% rename from clients/ts/FunctionalTests/.gitignore rename to src/SignalR/clients/ts/FunctionalTests/.gitignore diff --git a/clients/ts/FunctionalTests/AuthorizedHub.cs b/src/SignalR/clients/ts/FunctionalTests/AuthorizedHub.cs similarity index 100% rename from clients/ts/FunctionalTests/AuthorizedHub.cs rename to src/SignalR/clients/ts/FunctionalTests/AuthorizedHub.cs diff --git a/clients/ts/FunctionalTests/ComplexObject.cs b/src/SignalR/clients/ts/FunctionalTests/ComplexObject.cs similarity index 100% rename from clients/ts/FunctionalTests/ComplexObject.cs rename to src/SignalR/clients/ts/FunctionalTests/ComplexObject.cs diff --git a/clients/ts/FunctionalTests/EchoConnectionHandler.cs b/src/SignalR/clients/ts/FunctionalTests/EchoConnectionHandler.cs similarity index 100% rename from clients/ts/FunctionalTests/EchoConnectionHandler.cs rename to src/SignalR/clients/ts/FunctionalTests/EchoConnectionHandler.cs diff --git a/clients/ts/FunctionalTests/FunctionalTests.csproj b/src/SignalR/clients/ts/FunctionalTests/FunctionalTests.csproj similarity index 100% rename from clients/ts/FunctionalTests/FunctionalTests.csproj rename to src/SignalR/clients/ts/FunctionalTests/FunctionalTests.csproj diff --git a/clients/ts/FunctionalTests/Program.cs b/src/SignalR/clients/ts/FunctionalTests/Program.cs similarity index 100% rename from clients/ts/FunctionalTests/Program.cs rename to src/SignalR/clients/ts/FunctionalTests/Program.cs diff --git a/clients/ts/FunctionalTests/Startup.cs b/src/SignalR/clients/ts/FunctionalTests/Startup.cs similarity index 100% rename from clients/ts/FunctionalTests/Startup.cs rename to src/SignalR/clients/ts/FunctionalTests/Startup.cs diff --git a/clients/ts/FunctionalTests/TestHub.cs b/src/SignalR/clients/ts/FunctionalTests/TestHub.cs similarity index 100% rename from clients/ts/FunctionalTests/TestHub.cs rename to src/SignalR/clients/ts/FunctionalTests/TestHub.cs diff --git a/clients/ts/FunctionalTests/UncreatableHub.cs b/src/SignalR/clients/ts/FunctionalTests/UncreatableHub.cs similarity index 100% rename from clients/ts/FunctionalTests/UncreatableHub.cs rename to src/SignalR/clients/ts/FunctionalTests/UncreatableHub.cs diff --git a/clients/ts/FunctionalTests/func.jest.config.js b/src/SignalR/clients/ts/FunctionalTests/func.jest.config.js similarity index 100% rename from clients/ts/FunctionalTests/func.jest.config.js rename to src/SignalR/clients/ts/FunctionalTests/func.jest.config.js diff --git a/clients/ts/FunctionalTests/package-lock.json b/src/SignalR/clients/ts/FunctionalTests/package-lock.json similarity index 100% rename from clients/ts/FunctionalTests/package-lock.json rename to src/SignalR/clients/ts/FunctionalTests/package-lock.json diff --git a/clients/ts/FunctionalTests/package.json b/src/SignalR/clients/ts/FunctionalTests/package.json similarity index 100% rename from clients/ts/FunctionalTests/package.json rename to src/SignalR/clients/ts/FunctionalTests/package.json diff --git a/clients/ts/FunctionalTests/scripts/karma.base.conf.js b/src/SignalR/clients/ts/FunctionalTests/scripts/karma.base.conf.js similarity index 100% rename from clients/ts/FunctionalTests/scripts/karma.base.conf.js rename to src/SignalR/clients/ts/FunctionalTests/scripts/karma.base.conf.js diff --git a/clients/ts/FunctionalTests/scripts/karma.local.conf.js b/src/SignalR/clients/ts/FunctionalTests/scripts/karma.local.conf.js similarity index 100% rename from clients/ts/FunctionalTests/scripts/karma.local.conf.js rename to src/SignalR/clients/ts/FunctionalTests/scripts/karma.local.conf.js diff --git a/clients/ts/FunctionalTests/scripts/karma.sauce.conf.js b/src/SignalR/clients/ts/FunctionalTests/scripts/karma.sauce.conf.js similarity index 100% rename from clients/ts/FunctionalTests/scripts/karma.sauce.conf.js rename to src/SignalR/clients/ts/FunctionalTests/scripts/karma.sauce.conf.js diff --git a/clients/ts/FunctionalTests/scripts/run-tests.ts b/src/SignalR/clients/ts/FunctionalTests/scripts/run-tests.ts similarity index 100% rename from clients/ts/FunctionalTests/scripts/run-tests.ts rename to src/SignalR/clients/ts/FunctionalTests/scripts/run-tests.ts diff --git a/clients/ts/FunctionalTests/scripts/tsconfig.json b/src/SignalR/clients/ts/FunctionalTests/scripts/tsconfig.json similarity index 100% rename from clients/ts/FunctionalTests/scripts/tsconfig.json rename to src/SignalR/clients/ts/FunctionalTests/scripts/tsconfig.json diff --git a/clients/ts/FunctionalTests/testCert.pfx b/src/SignalR/clients/ts/FunctionalTests/testCert.pfx similarity index 100% rename from clients/ts/FunctionalTests/testCert.pfx rename to src/SignalR/clients/ts/FunctionalTests/testCert.pfx diff --git a/clients/ts/FunctionalTests/testCertECC.pfx b/src/SignalR/clients/ts/FunctionalTests/testCertECC.pfx similarity index 100% rename from clients/ts/FunctionalTests/testCertECC.pfx rename to src/SignalR/clients/ts/FunctionalTests/testCertECC.pfx diff --git a/clients/ts/FunctionalTests/ts/Common.ts b/src/SignalR/clients/ts/FunctionalTests/ts/Common.ts similarity index 100% rename from clients/ts/FunctionalTests/ts/Common.ts rename to src/SignalR/clients/ts/FunctionalTests/ts/Common.ts diff --git a/clients/ts/FunctionalTests/ts/ConnectionTests.ts b/src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts similarity index 100% rename from clients/ts/FunctionalTests/ts/ConnectionTests.ts rename to src/SignalR/clients/ts/FunctionalTests/ts/ConnectionTests.ts diff --git a/clients/ts/FunctionalTests/ts/HubConnectionTests.ts b/src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts similarity index 100% rename from clients/ts/FunctionalTests/ts/HubConnectionTests.ts rename to src/SignalR/clients/ts/FunctionalTests/ts/HubConnectionTests.ts diff --git a/clients/ts/FunctionalTests/ts/LogBannerReporter.ts b/src/SignalR/clients/ts/FunctionalTests/ts/LogBannerReporter.ts similarity index 100% rename from clients/ts/FunctionalTests/ts/LogBannerReporter.ts rename to src/SignalR/clients/ts/FunctionalTests/ts/LogBannerReporter.ts diff --git a/clients/ts/FunctionalTests/ts/TestLogger.ts b/src/SignalR/clients/ts/FunctionalTests/ts/TestLogger.ts similarity index 100% rename from clients/ts/FunctionalTests/ts/TestLogger.ts rename to src/SignalR/clients/ts/FunctionalTests/ts/TestLogger.ts diff --git a/clients/ts/FunctionalTests/ts/Utils.ts b/src/SignalR/clients/ts/FunctionalTests/ts/Utils.ts similarity index 100% rename from clients/ts/FunctionalTests/ts/Utils.ts rename to src/SignalR/clients/ts/FunctionalTests/ts/Utils.ts diff --git a/clients/ts/FunctionalTests/ts/WebSocketTests.ts b/src/SignalR/clients/ts/FunctionalTests/ts/WebSocketTests.ts similarity index 100% rename from clients/ts/FunctionalTests/ts/WebSocketTests.ts rename to src/SignalR/clients/ts/FunctionalTests/ts/WebSocketTests.ts diff --git a/clients/ts/FunctionalTests/ts/index.ts b/src/SignalR/clients/ts/FunctionalTests/ts/index.ts similarity index 100% rename from clients/ts/FunctionalTests/ts/index.ts rename to src/SignalR/clients/ts/FunctionalTests/ts/index.ts diff --git a/clients/ts/FunctionalTests/tsconfig.json b/src/SignalR/clients/ts/FunctionalTests/tsconfig.json similarity index 100% rename from clients/ts/FunctionalTests/tsconfig.json rename to src/SignalR/clients/ts/FunctionalTests/tsconfig.json diff --git a/clients/ts/FunctionalTests/web.config b/src/SignalR/clients/ts/FunctionalTests/web.config similarity index 100% rename from clients/ts/FunctionalTests/web.config rename to src/SignalR/clients/ts/FunctionalTests/web.config diff --git a/clients/ts/FunctionalTests/webpack.config.js b/src/SignalR/clients/ts/FunctionalTests/webpack.config.js similarity index 100% rename from clients/ts/FunctionalTests/webpack.config.js rename to src/SignalR/clients/ts/FunctionalTests/webpack.config.js diff --git a/clients/ts/FunctionalTests/wwwroot/default.html b/src/SignalR/clients/ts/FunctionalTests/wwwroot/default.html similarity index 100% rename from clients/ts/FunctionalTests/wwwroot/default.html rename to src/SignalR/clients/ts/FunctionalTests/wwwroot/default.html diff --git a/clients/ts/build/embed-version.js b/src/SignalR/clients/ts/build/embed-version.js similarity index 100% rename from clients/ts/build/embed-version.js rename to src/SignalR/clients/ts/build/embed-version.js diff --git a/clients/ts/common/package-lock.json b/src/SignalR/clients/ts/common/package-lock.json similarity index 100% rename from clients/ts/common/package-lock.json rename to src/SignalR/clients/ts/common/package-lock.json diff --git a/clients/ts/common/package.json b/src/SignalR/clients/ts/common/package.json similarity index 100% rename from clients/ts/common/package.json rename to src/SignalR/clients/ts/common/package.json diff --git a/clients/ts/jest.config.js b/src/SignalR/clients/ts/jest.config.js similarity index 100% rename from clients/ts/jest.config.js rename to src/SignalR/clients/ts/jest.config.js diff --git a/clients/ts/package-lock.json b/src/SignalR/clients/ts/package-lock.json similarity index 100% rename from clients/ts/package-lock.json rename to src/SignalR/clients/ts/package-lock.json diff --git a/clients/ts/package.json b/src/SignalR/clients/ts/package.json similarity index 100% rename from clients/ts/package.json rename to src/SignalR/clients/ts/package.json diff --git a/clients/ts/signalr-protocol-msgpack/README.md b/src/SignalR/clients/ts/signalr-protocol-msgpack/README.md similarity index 100% rename from clients/ts/signalr-protocol-msgpack/README.md rename to src/SignalR/clients/ts/signalr-protocol-msgpack/README.md diff --git a/clients/ts/signalr-protocol-msgpack/package-lock.json b/src/SignalR/clients/ts/signalr-protocol-msgpack/package-lock.json similarity index 100% rename from clients/ts/signalr-protocol-msgpack/package-lock.json rename to src/SignalR/clients/ts/signalr-protocol-msgpack/package-lock.json diff --git a/clients/ts/signalr-protocol-msgpack/package.json b/src/SignalR/clients/ts/signalr-protocol-msgpack/package.json similarity index 100% rename from clients/ts/signalr-protocol-msgpack/package.json rename to src/SignalR/clients/ts/signalr-protocol-msgpack/package.json diff --git a/clients/ts/signalr-protocol-msgpack/rollup.config.js b/src/SignalR/clients/ts/signalr-protocol-msgpack/rollup.config.js similarity index 100% rename from clients/ts/signalr-protocol-msgpack/rollup.config.js rename to src/SignalR/clients/ts/signalr-protocol-msgpack/rollup.config.js diff --git a/clients/ts/signalr-protocol-msgpack/src/BinaryMessageFormat.ts b/src/SignalR/clients/ts/signalr-protocol-msgpack/src/BinaryMessageFormat.ts similarity index 100% rename from clients/ts/signalr-protocol-msgpack/src/BinaryMessageFormat.ts rename to src/SignalR/clients/ts/signalr-protocol-msgpack/src/BinaryMessageFormat.ts diff --git a/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts b/src/SignalR/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts similarity index 100% rename from clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts rename to src/SignalR/clients/ts/signalr-protocol-msgpack/src/MessagePackHubProtocol.ts diff --git a/clients/ts/signalr-protocol-msgpack/src/Utils.ts b/src/SignalR/clients/ts/signalr-protocol-msgpack/src/Utils.ts similarity index 100% rename from clients/ts/signalr-protocol-msgpack/src/Utils.ts rename to src/SignalR/clients/ts/signalr-protocol-msgpack/src/Utils.ts diff --git a/clients/ts/signalr-protocol-msgpack/src/browser-index.ts b/src/SignalR/clients/ts/signalr-protocol-msgpack/src/browser-index.ts similarity index 100% rename from clients/ts/signalr-protocol-msgpack/src/browser-index.ts rename to src/SignalR/clients/ts/signalr-protocol-msgpack/src/browser-index.ts diff --git a/clients/ts/signalr-protocol-msgpack/src/index.ts b/src/SignalR/clients/ts/signalr-protocol-msgpack/src/index.ts similarity index 100% rename from clients/ts/signalr-protocol-msgpack/src/index.ts rename to src/SignalR/clients/ts/signalr-protocol-msgpack/src/index.ts diff --git a/clients/ts/signalr-protocol-msgpack/src/third-party-notices.txt b/src/SignalR/clients/ts/signalr-protocol-msgpack/src/third-party-notices.txt similarity index 100% rename from clients/ts/signalr-protocol-msgpack/src/third-party-notices.txt rename to src/SignalR/clients/ts/signalr-protocol-msgpack/src/third-party-notices.txt diff --git a/clients/ts/signalr-protocol-msgpack/tests/BinaryMessageFormatter.test.ts b/src/SignalR/clients/ts/signalr-protocol-msgpack/tests/BinaryMessageFormatter.test.ts similarity index 100% rename from clients/ts/signalr-protocol-msgpack/tests/BinaryMessageFormatter.test.ts rename to src/SignalR/clients/ts/signalr-protocol-msgpack/tests/BinaryMessageFormatter.test.ts diff --git a/clients/ts/signalr-protocol-msgpack/tests/MessagePackHubProtocol.test.ts b/src/SignalR/clients/ts/signalr-protocol-msgpack/tests/MessagePackHubProtocol.test.ts similarity index 100% rename from clients/ts/signalr-protocol-msgpack/tests/MessagePackHubProtocol.test.ts rename to src/SignalR/clients/ts/signalr-protocol-msgpack/tests/MessagePackHubProtocol.test.ts diff --git a/clients/ts/signalr-protocol-msgpack/tests/tsconfig.json b/src/SignalR/clients/ts/signalr-protocol-msgpack/tests/tsconfig.json similarity index 100% rename from clients/ts/signalr-protocol-msgpack/tests/tsconfig.json rename to src/SignalR/clients/ts/signalr-protocol-msgpack/tests/tsconfig.json diff --git a/clients/ts/signalr-protocol-msgpack/tsconfig.json b/src/SignalR/clients/ts/signalr-protocol-msgpack/tsconfig.json similarity index 100% rename from clients/ts/signalr-protocol-msgpack/tsconfig.json rename to src/SignalR/clients/ts/signalr-protocol-msgpack/tsconfig.json diff --git a/clients/ts/signalr-protocol-msgpack/webpack.config.js b/src/SignalR/clients/ts/signalr-protocol-msgpack/webpack.config.js similarity index 100% rename from clients/ts/signalr-protocol-msgpack/webpack.config.js rename to src/SignalR/clients/ts/signalr-protocol-msgpack/webpack.config.js diff --git a/clients/ts/signalr/README.md b/src/SignalR/clients/ts/signalr/README.md similarity index 100% rename from clients/ts/signalr/README.md rename to src/SignalR/clients/ts/signalr/README.md diff --git a/clients/ts/signalr/build/process-dts.js b/src/SignalR/clients/ts/signalr/build/process-dts.js similarity index 100% rename from clients/ts/signalr/build/process-dts.js rename to src/SignalR/clients/ts/signalr/build/process-dts.js diff --git a/clients/ts/signalr/package-lock.json b/src/SignalR/clients/ts/signalr/package-lock.json similarity index 100% rename from clients/ts/signalr/package-lock.json rename to src/SignalR/clients/ts/signalr/package-lock.json diff --git a/clients/ts/signalr/package.json b/src/SignalR/clients/ts/signalr/package.json similarity index 100% rename from clients/ts/signalr/package.json rename to src/SignalR/clients/ts/signalr/package.json diff --git a/clients/ts/signalr/rollup.config.js b/src/SignalR/clients/ts/signalr/rollup.config.js similarity index 100% rename from clients/ts/signalr/rollup.config.js rename to src/SignalR/clients/ts/signalr/rollup.config.js diff --git a/clients/ts/signalr/src/AbortController.ts b/src/SignalR/clients/ts/signalr/src/AbortController.ts similarity index 100% rename from clients/ts/signalr/src/AbortController.ts rename to src/SignalR/clients/ts/signalr/src/AbortController.ts diff --git a/clients/ts/signalr/src/DefaultHttpClient.ts b/src/SignalR/clients/ts/signalr/src/DefaultHttpClient.ts similarity index 100% rename from clients/ts/signalr/src/DefaultHttpClient.ts rename to src/SignalR/clients/ts/signalr/src/DefaultHttpClient.ts diff --git a/clients/ts/signalr/src/Errors.ts b/src/SignalR/clients/ts/signalr/src/Errors.ts similarity index 100% rename from clients/ts/signalr/src/Errors.ts rename to src/SignalR/clients/ts/signalr/src/Errors.ts diff --git a/clients/ts/signalr/src/HandshakeProtocol.ts b/src/SignalR/clients/ts/signalr/src/HandshakeProtocol.ts similarity index 100% rename from clients/ts/signalr/src/HandshakeProtocol.ts rename to src/SignalR/clients/ts/signalr/src/HandshakeProtocol.ts diff --git a/clients/ts/signalr/src/HttpClient.ts b/src/SignalR/clients/ts/signalr/src/HttpClient.ts similarity index 100% rename from clients/ts/signalr/src/HttpClient.ts rename to src/SignalR/clients/ts/signalr/src/HttpClient.ts diff --git a/clients/ts/signalr/src/HttpConnection.ts b/src/SignalR/clients/ts/signalr/src/HttpConnection.ts similarity index 100% rename from clients/ts/signalr/src/HttpConnection.ts rename to src/SignalR/clients/ts/signalr/src/HttpConnection.ts diff --git a/clients/ts/signalr/src/HubConnection.ts b/src/SignalR/clients/ts/signalr/src/HubConnection.ts similarity index 100% rename from clients/ts/signalr/src/HubConnection.ts rename to src/SignalR/clients/ts/signalr/src/HubConnection.ts diff --git a/clients/ts/signalr/src/HubConnectionBuilder.ts b/src/SignalR/clients/ts/signalr/src/HubConnectionBuilder.ts similarity index 100% rename from clients/ts/signalr/src/HubConnectionBuilder.ts rename to src/SignalR/clients/ts/signalr/src/HubConnectionBuilder.ts diff --git a/clients/ts/signalr/src/IConnection.ts b/src/SignalR/clients/ts/signalr/src/IConnection.ts similarity index 100% rename from clients/ts/signalr/src/IConnection.ts rename to src/SignalR/clients/ts/signalr/src/IConnection.ts diff --git a/clients/ts/signalr/src/IHttpConnectionOptions.ts b/src/SignalR/clients/ts/signalr/src/IHttpConnectionOptions.ts similarity index 100% rename from clients/ts/signalr/src/IHttpConnectionOptions.ts rename to src/SignalR/clients/ts/signalr/src/IHttpConnectionOptions.ts diff --git a/clients/ts/signalr/src/IHubProtocol.ts b/src/SignalR/clients/ts/signalr/src/IHubProtocol.ts similarity index 100% rename from clients/ts/signalr/src/IHubProtocol.ts rename to src/SignalR/clients/ts/signalr/src/IHubProtocol.ts diff --git a/clients/ts/signalr/src/ILogger.ts b/src/SignalR/clients/ts/signalr/src/ILogger.ts similarity index 100% rename from clients/ts/signalr/src/ILogger.ts rename to src/SignalR/clients/ts/signalr/src/ILogger.ts diff --git a/clients/ts/signalr/src/ITransport.ts b/src/SignalR/clients/ts/signalr/src/ITransport.ts similarity index 100% rename from clients/ts/signalr/src/ITransport.ts rename to src/SignalR/clients/ts/signalr/src/ITransport.ts diff --git a/clients/ts/signalr/src/JsonHubProtocol.ts b/src/SignalR/clients/ts/signalr/src/JsonHubProtocol.ts similarity index 100% rename from clients/ts/signalr/src/JsonHubProtocol.ts rename to src/SignalR/clients/ts/signalr/src/JsonHubProtocol.ts diff --git a/clients/ts/signalr/src/Loggers.ts b/src/SignalR/clients/ts/signalr/src/Loggers.ts similarity index 100% rename from clients/ts/signalr/src/Loggers.ts rename to src/SignalR/clients/ts/signalr/src/Loggers.ts diff --git a/clients/ts/signalr/src/LongPollingTransport.ts b/src/SignalR/clients/ts/signalr/src/LongPollingTransport.ts similarity index 100% rename from clients/ts/signalr/src/LongPollingTransport.ts rename to src/SignalR/clients/ts/signalr/src/LongPollingTransport.ts diff --git a/clients/ts/signalr/src/NodeHttpClient.ts b/src/SignalR/clients/ts/signalr/src/NodeHttpClient.ts similarity index 100% rename from clients/ts/signalr/src/NodeHttpClient.ts rename to src/SignalR/clients/ts/signalr/src/NodeHttpClient.ts diff --git a/clients/ts/signalr/src/Polyfills.ts b/src/SignalR/clients/ts/signalr/src/Polyfills.ts similarity index 100% rename from clients/ts/signalr/src/Polyfills.ts rename to src/SignalR/clients/ts/signalr/src/Polyfills.ts diff --git a/clients/ts/signalr/src/ServerSentEventsTransport.ts b/src/SignalR/clients/ts/signalr/src/ServerSentEventsTransport.ts similarity index 100% rename from clients/ts/signalr/src/ServerSentEventsTransport.ts rename to src/SignalR/clients/ts/signalr/src/ServerSentEventsTransport.ts diff --git a/clients/ts/signalr/src/Stream.ts b/src/SignalR/clients/ts/signalr/src/Stream.ts similarity index 100% rename from clients/ts/signalr/src/Stream.ts rename to src/SignalR/clients/ts/signalr/src/Stream.ts diff --git a/clients/ts/signalr/src/TextMessageFormat.ts b/src/SignalR/clients/ts/signalr/src/TextMessageFormat.ts similarity index 100% rename from clients/ts/signalr/src/TextMessageFormat.ts rename to src/SignalR/clients/ts/signalr/src/TextMessageFormat.ts diff --git a/clients/ts/signalr/src/Utils.ts b/src/SignalR/clients/ts/signalr/src/Utils.ts similarity index 100% rename from clients/ts/signalr/src/Utils.ts rename to src/SignalR/clients/ts/signalr/src/Utils.ts diff --git a/clients/ts/signalr/src/WebSocketTransport.ts b/src/SignalR/clients/ts/signalr/src/WebSocketTransport.ts similarity index 100% rename from clients/ts/signalr/src/WebSocketTransport.ts rename to src/SignalR/clients/ts/signalr/src/WebSocketTransport.ts diff --git a/clients/ts/signalr/src/XhrHttpClient.ts b/src/SignalR/clients/ts/signalr/src/XhrHttpClient.ts similarity index 100% rename from clients/ts/signalr/src/XhrHttpClient.ts rename to src/SignalR/clients/ts/signalr/src/XhrHttpClient.ts diff --git a/clients/ts/signalr/src/browser-index.ts b/src/SignalR/clients/ts/signalr/src/browser-index.ts similarity index 100% rename from clients/ts/signalr/src/browser-index.ts rename to src/SignalR/clients/ts/signalr/src/browser-index.ts diff --git a/clients/ts/signalr/src/index.ts b/src/SignalR/clients/ts/signalr/src/index.ts similarity index 100% rename from clients/ts/signalr/src/index.ts rename to src/SignalR/clients/ts/signalr/src/index.ts diff --git a/clients/ts/signalr/src/third-party-notices.txt b/src/SignalR/clients/ts/signalr/src/third-party-notices.txt similarity index 100% rename from clients/ts/signalr/src/third-party-notices.txt rename to src/SignalR/clients/ts/signalr/src/third-party-notices.txt diff --git a/clients/ts/signalr/tests/AbortSignal.test.ts b/src/SignalR/clients/ts/signalr/tests/AbortSignal.test.ts similarity index 100% rename from clients/ts/signalr/tests/AbortSignal.test.ts rename to src/SignalR/clients/ts/signalr/tests/AbortSignal.test.ts diff --git a/clients/ts/signalr/tests/Common.ts b/src/SignalR/clients/ts/signalr/tests/Common.ts similarity index 100% rename from clients/ts/signalr/tests/Common.ts rename to src/SignalR/clients/ts/signalr/tests/Common.ts diff --git a/clients/ts/signalr/tests/HttpClient.test.ts b/src/SignalR/clients/ts/signalr/tests/HttpClient.test.ts similarity index 100% rename from clients/ts/signalr/tests/HttpClient.test.ts rename to src/SignalR/clients/ts/signalr/tests/HttpClient.test.ts diff --git a/clients/ts/signalr/tests/HttpConnection.test.ts b/src/SignalR/clients/ts/signalr/tests/HttpConnection.test.ts similarity index 100% rename from clients/ts/signalr/tests/HttpConnection.test.ts rename to src/SignalR/clients/ts/signalr/tests/HttpConnection.test.ts diff --git a/clients/ts/signalr/tests/HubConnection.test.ts b/src/SignalR/clients/ts/signalr/tests/HubConnection.test.ts similarity index 100% rename from clients/ts/signalr/tests/HubConnection.test.ts rename to src/SignalR/clients/ts/signalr/tests/HubConnection.test.ts diff --git a/clients/ts/signalr/tests/HubConnectionBuilder.test.ts b/src/SignalR/clients/ts/signalr/tests/HubConnectionBuilder.test.ts similarity index 100% rename from clients/ts/signalr/tests/HubConnectionBuilder.test.ts rename to src/SignalR/clients/ts/signalr/tests/HubConnectionBuilder.test.ts diff --git a/clients/ts/signalr/tests/JsonHubProtocol.test.ts b/src/SignalR/clients/ts/signalr/tests/JsonHubProtocol.test.ts similarity index 100% rename from clients/ts/signalr/tests/JsonHubProtocol.test.ts rename to src/SignalR/clients/ts/signalr/tests/JsonHubProtocol.test.ts diff --git a/clients/ts/signalr/tests/LongPollingTransport.test.ts b/src/SignalR/clients/ts/signalr/tests/LongPollingTransport.test.ts similarity index 100% rename from clients/ts/signalr/tests/LongPollingTransport.test.ts rename to src/SignalR/clients/ts/signalr/tests/LongPollingTransport.test.ts diff --git a/clients/ts/signalr/tests/ServerSentEventsTransport.test.ts b/src/SignalR/clients/ts/signalr/tests/ServerSentEventsTransport.test.ts similarity index 100% rename from clients/ts/signalr/tests/ServerSentEventsTransport.test.ts rename to src/SignalR/clients/ts/signalr/tests/ServerSentEventsTransport.test.ts diff --git a/clients/ts/signalr/tests/TestEventSource.ts b/src/SignalR/clients/ts/signalr/tests/TestEventSource.ts similarity index 100% rename from clients/ts/signalr/tests/TestEventSource.ts rename to src/SignalR/clients/ts/signalr/tests/TestEventSource.ts diff --git a/clients/ts/signalr/tests/TestHttpClient.ts b/src/SignalR/clients/ts/signalr/tests/TestHttpClient.ts similarity index 100% rename from clients/ts/signalr/tests/TestHttpClient.ts rename to src/SignalR/clients/ts/signalr/tests/TestHttpClient.ts diff --git a/clients/ts/signalr/tests/TestWebSocket.ts b/src/SignalR/clients/ts/signalr/tests/TestWebSocket.ts similarity index 100% rename from clients/ts/signalr/tests/TestWebSocket.ts rename to src/SignalR/clients/ts/signalr/tests/TestWebSocket.ts diff --git a/clients/ts/signalr/tests/TextMessageFormat.test.ts b/src/SignalR/clients/ts/signalr/tests/TextMessageFormat.test.ts similarity index 100% rename from clients/ts/signalr/tests/TextMessageFormat.test.ts rename to src/SignalR/clients/ts/signalr/tests/TextMessageFormat.test.ts diff --git a/clients/ts/signalr/tests/Utils.ts b/src/SignalR/clients/ts/signalr/tests/Utils.ts similarity index 100% rename from clients/ts/signalr/tests/Utils.ts rename to src/SignalR/clients/ts/signalr/tests/Utils.ts diff --git a/clients/ts/signalr/tests/WebSocketTransport.test.ts b/src/SignalR/clients/ts/signalr/tests/WebSocketTransport.test.ts similarity index 100% rename from clients/ts/signalr/tests/WebSocketTransport.test.ts rename to src/SignalR/clients/ts/signalr/tests/WebSocketTransport.test.ts diff --git a/clients/ts/signalr/tests/tsconfig.json b/src/SignalR/clients/ts/signalr/tests/tsconfig.json similarity index 100% rename from clients/ts/signalr/tests/tsconfig.json rename to src/SignalR/clients/ts/signalr/tests/tsconfig.json diff --git a/clients/ts/signalr/tsconfig.json b/src/SignalR/clients/ts/signalr/tsconfig.json similarity index 100% rename from clients/ts/signalr/tsconfig.json rename to src/SignalR/clients/ts/signalr/tsconfig.json diff --git a/clients/ts/signalr/webpack.config.js b/src/SignalR/clients/ts/signalr/webpack.config.js similarity index 100% rename from clients/ts/signalr/webpack.config.js rename to src/SignalR/clients/ts/signalr/webpack.config.js diff --git a/clients/ts/tsconfig.base.json b/src/SignalR/clients/ts/tsconfig.base.json similarity index 100% rename from clients/ts/tsconfig.base.json rename to src/SignalR/clients/ts/tsconfig.base.json diff --git a/clients/ts/tsconfig.jest.json b/src/SignalR/clients/ts/tsconfig.jest.json similarity index 100% rename from clients/ts/tsconfig.jest.json rename to src/SignalR/clients/ts/tsconfig.jest.json diff --git a/clients/ts/tslint.json b/src/SignalR/clients/ts/tslint.json similarity index 100% rename from clients/ts/tslint.json rename to src/SignalR/clients/ts/tslint.json diff --git a/clients/ts/webpack.config.base.js b/src/SignalR/clients/ts/webpack.config.base.js similarity index 100% rename from clients/ts/webpack.config.base.js rename to src/SignalR/clients/ts/webpack.config.base.js diff --git a/docs/GettingStarted.md b/src/SignalR/docs/GettingStarted.md similarity index 100% rename from docs/GettingStarted.md rename to src/SignalR/docs/GettingStarted.md diff --git a/docs/JSFunctionalTests.md b/src/SignalR/docs/JSFunctionalTests.md similarity index 100% rename from docs/JSFunctionalTests.md rename to src/SignalR/docs/JSFunctionalTests.md diff --git a/docs/JSUnitTests.md b/src/SignalR/docs/JSUnitTests.md similarity index 100% rename from docs/JSUnitTests.md rename to src/SignalR/docs/JSUnitTests.md diff --git a/samples/ClientSample/ClientSample.csproj b/src/SignalR/samples/ClientSample/ClientSample.csproj similarity index 100% rename from samples/ClientSample/ClientSample.csproj rename to src/SignalR/samples/ClientSample/ClientSample.csproj diff --git a/samples/ClientSample/HubSample.cs b/src/SignalR/samples/ClientSample/HubSample.cs similarity index 100% rename from samples/ClientSample/HubSample.cs rename to src/SignalR/samples/ClientSample/HubSample.cs diff --git a/samples/ClientSample/LoggingMessageHandler.cs b/src/SignalR/samples/ClientSample/LoggingMessageHandler.cs similarity index 100% rename from samples/ClientSample/LoggingMessageHandler.cs rename to src/SignalR/samples/ClientSample/LoggingMessageHandler.cs diff --git a/samples/ClientSample/Program.cs b/src/SignalR/samples/ClientSample/Program.cs similarity index 100% rename from samples/ClientSample/Program.cs rename to src/SignalR/samples/ClientSample/Program.cs diff --git a/samples/ClientSample/RawSample.cs b/src/SignalR/samples/ClientSample/RawSample.cs similarity index 100% rename from samples/ClientSample/RawSample.cs rename to src/SignalR/samples/ClientSample/RawSample.cs diff --git a/samples/ClientSample/StreamingSample.cs b/src/SignalR/samples/ClientSample/StreamingSample.cs similarity index 100% rename from samples/ClientSample/StreamingSample.cs rename to src/SignalR/samples/ClientSample/StreamingSample.cs diff --git a/samples/ClientSample/Tcp/BufferExtensions.cs b/src/SignalR/samples/ClientSample/Tcp/BufferExtensions.cs similarity index 100% rename from samples/ClientSample/Tcp/BufferExtensions.cs rename to src/SignalR/samples/ClientSample/Tcp/BufferExtensions.cs diff --git a/samples/ClientSample/Tcp/SocketAwaitable.cs b/src/SignalR/samples/ClientSample/Tcp/SocketAwaitable.cs similarity index 100% rename from samples/ClientSample/Tcp/SocketAwaitable.cs rename to src/SignalR/samples/ClientSample/Tcp/SocketAwaitable.cs diff --git a/samples/ClientSample/Tcp/SocketReceiver.cs b/src/SignalR/samples/ClientSample/Tcp/SocketReceiver.cs similarity index 100% rename from samples/ClientSample/Tcp/SocketReceiver.cs rename to src/SignalR/samples/ClientSample/Tcp/SocketReceiver.cs diff --git a/samples/ClientSample/Tcp/SocketSender.cs b/src/SignalR/samples/ClientSample/Tcp/SocketSender.cs similarity index 100% rename from samples/ClientSample/Tcp/SocketSender.cs rename to src/SignalR/samples/ClientSample/Tcp/SocketSender.cs diff --git a/samples/ClientSample/Tcp/TcpConnection.cs b/src/SignalR/samples/ClientSample/Tcp/TcpConnection.cs similarity index 100% rename from samples/ClientSample/Tcp/TcpConnection.cs rename to src/SignalR/samples/ClientSample/Tcp/TcpConnection.cs diff --git a/samples/ClientSample/Tcp/TcpHubConnectionBuilderExtensions.cs b/src/SignalR/samples/ClientSample/Tcp/TcpHubConnectionBuilderExtensions.cs similarity index 100% rename from samples/ClientSample/Tcp/TcpHubConnectionBuilderExtensions.cs rename to src/SignalR/samples/ClientSample/Tcp/TcpHubConnectionBuilderExtensions.cs diff --git a/samples/ClientSample/UploadSample.cs b/src/SignalR/samples/ClientSample/UploadSample.cs similarity index 100% rename from samples/ClientSample/UploadSample.cs rename to src/SignalR/samples/ClientSample/UploadSample.cs diff --git a/samples/JwtClientSample/JwtClientSample.csproj b/src/SignalR/samples/JwtClientSample/JwtClientSample.csproj similarity index 100% rename from samples/JwtClientSample/JwtClientSample.csproj rename to src/SignalR/samples/JwtClientSample/JwtClientSample.csproj diff --git a/samples/JwtClientSample/Program.cs b/src/SignalR/samples/JwtClientSample/Program.cs similarity index 100% rename from samples/JwtClientSample/Program.cs rename to src/SignalR/samples/JwtClientSample/Program.cs diff --git a/samples/JwtSample/.gitignore b/src/SignalR/samples/JwtSample/.gitignore similarity index 100% rename from samples/JwtSample/.gitignore rename to src/SignalR/samples/JwtSample/.gitignore diff --git a/samples/JwtSample/Broadcaster.cs b/src/SignalR/samples/JwtSample/Broadcaster.cs similarity index 100% rename from samples/JwtSample/Broadcaster.cs rename to src/SignalR/samples/JwtSample/Broadcaster.cs diff --git a/samples/JwtSample/JwtSample.csproj b/src/SignalR/samples/JwtSample/JwtSample.csproj similarity index 100% rename from samples/JwtSample/JwtSample.csproj rename to src/SignalR/samples/JwtSample/JwtSample.csproj diff --git a/samples/JwtSample/Program.cs b/src/SignalR/samples/JwtSample/Program.cs similarity index 100% rename from samples/JwtSample/Program.cs rename to src/SignalR/samples/JwtSample/Program.cs diff --git a/samples/JwtSample/Properties/launchSettings.json b/src/SignalR/samples/JwtSample/Properties/launchSettings.json similarity index 100% rename from samples/JwtSample/Properties/launchSettings.json rename to src/SignalR/samples/JwtSample/Properties/launchSettings.json diff --git a/samples/JwtSample/Startup.cs b/src/SignalR/samples/JwtSample/Startup.cs similarity index 100% rename from samples/JwtSample/Startup.cs rename to src/SignalR/samples/JwtSample/Startup.cs diff --git a/samples/JwtSample/wwwroot/index.html b/src/SignalR/samples/JwtSample/wwwroot/index.html similarity index 100% rename from samples/JwtSample/wwwroot/index.html rename to src/SignalR/samples/JwtSample/wwwroot/index.html diff --git a/samples/SignalRSamples/.gitignore b/src/SignalR/samples/SignalRSamples/.gitignore similarity index 100% rename from samples/SignalRSamples/.gitignore rename to src/SignalR/samples/SignalRSamples/.gitignore diff --git a/samples/SignalRSamples/ConnectionHandlers/MessagesConnectionHandler.cs b/src/SignalR/samples/SignalRSamples/ConnectionHandlers/MessagesConnectionHandler.cs similarity index 100% rename from samples/SignalRSamples/ConnectionHandlers/MessagesConnectionHandler.cs rename to src/SignalR/samples/SignalRSamples/ConnectionHandlers/MessagesConnectionHandler.cs diff --git a/samples/SignalRSamples/ConnectionList.cs b/src/SignalR/samples/SignalRSamples/ConnectionList.cs similarity index 100% rename from samples/SignalRSamples/ConnectionList.cs rename to src/SignalR/samples/SignalRSamples/ConnectionList.cs diff --git a/samples/SignalRSamples/Hubs/Chat.cs b/src/SignalR/samples/SignalRSamples/Hubs/Chat.cs similarity index 100% rename from samples/SignalRSamples/Hubs/Chat.cs rename to src/SignalR/samples/SignalRSamples/Hubs/Chat.cs diff --git a/samples/SignalRSamples/Hubs/DynamicChat.cs b/src/SignalR/samples/SignalRSamples/Hubs/DynamicChat.cs similarity index 100% rename from samples/SignalRSamples/Hubs/DynamicChat.cs rename to src/SignalR/samples/SignalRSamples/Hubs/DynamicChat.cs diff --git a/samples/SignalRSamples/Hubs/HubTChat.cs b/src/SignalR/samples/SignalRSamples/Hubs/HubTChat.cs similarity index 100% rename from samples/SignalRSamples/Hubs/HubTChat.cs rename to src/SignalR/samples/SignalRSamples/Hubs/HubTChat.cs diff --git a/samples/SignalRSamples/Hubs/Streaming.cs b/src/SignalR/samples/SignalRSamples/Hubs/Streaming.cs similarity index 100% rename from samples/SignalRSamples/Hubs/Streaming.cs rename to src/SignalR/samples/SignalRSamples/Hubs/Streaming.cs diff --git a/samples/SignalRSamples/Hubs/UploadHub.cs b/src/SignalR/samples/SignalRSamples/Hubs/UploadHub.cs similarity index 100% rename from samples/SignalRSamples/Hubs/UploadHub.cs rename to src/SignalR/samples/SignalRSamples/Hubs/UploadHub.cs diff --git a/samples/SignalRSamples/ObservableExtensions.cs b/src/SignalR/samples/SignalRSamples/ObservableExtensions.cs similarity index 100% rename from samples/SignalRSamples/ObservableExtensions.cs rename to src/SignalR/samples/SignalRSamples/ObservableExtensions.cs diff --git a/samples/SignalRSamples/Program.cs b/src/SignalR/samples/SignalRSamples/Program.cs similarity index 100% rename from samples/SignalRSamples/Program.cs rename to src/SignalR/samples/SignalRSamples/Program.cs diff --git a/samples/SignalRSamples/SignalRSamples.csproj b/src/SignalR/samples/SignalRSamples/SignalRSamples.csproj similarity index 100% rename from samples/SignalRSamples/SignalRSamples.csproj rename to src/SignalR/samples/SignalRSamples/SignalRSamples.csproj diff --git a/samples/SignalRSamples/Startup.cs b/src/SignalR/samples/SignalRSamples/Startup.cs similarity index 100% rename from samples/SignalRSamples/Startup.cs rename to src/SignalR/samples/SignalRSamples/Startup.cs diff --git a/samples/SignalRSamples/web.config b/src/SignalR/samples/SignalRSamples/web.config similarity index 100% rename from samples/SignalRSamples/web.config rename to src/SignalR/samples/SignalRSamples/web.config diff --git a/samples/SignalRSamples/wwwroot/hubs.html b/src/SignalR/samples/SignalRSamples/wwwroot/hubs.html similarity index 100% rename from samples/SignalRSamples/wwwroot/hubs.html rename to src/SignalR/samples/SignalRSamples/wwwroot/hubs.html diff --git a/samples/SignalRSamples/wwwroot/index.html b/src/SignalR/samples/SignalRSamples/wwwroot/index.html similarity index 100% rename from samples/SignalRSamples/wwwroot/index.html rename to src/SignalR/samples/SignalRSamples/wwwroot/index.html diff --git a/samples/SignalRSamples/wwwroot/sockets.html b/src/SignalR/samples/SignalRSamples/wwwroot/sockets.html similarity index 100% rename from samples/SignalRSamples/wwwroot/sockets.html rename to src/SignalR/samples/SignalRSamples/wwwroot/sockets.html diff --git a/samples/SignalRSamples/wwwroot/streaming.html b/src/SignalR/samples/SignalRSamples/wwwroot/streaming.html similarity index 100% rename from samples/SignalRSamples/wwwroot/streaming.html rename to src/SignalR/samples/SignalRSamples/wwwroot/streaming.html diff --git a/samples/SignalRSamples/wwwroot/utils.js b/src/SignalR/samples/SignalRSamples/wwwroot/utils.js similarity index 100% rename from samples/SignalRSamples/wwwroot/utils.js rename to src/SignalR/samples/SignalRSamples/wwwroot/utils.js diff --git a/samples/SignalRSamples/wwwroot/ws.html b/src/SignalR/samples/SignalRSamples/wwwroot/ws.html similarity index 100% rename from samples/SignalRSamples/wwwroot/ws.html rename to src/SignalR/samples/SignalRSamples/wwwroot/ws.html diff --git a/samples/SocialWeather/ConnectionList.cs b/src/SignalR/samples/SocialWeather/ConnectionList.cs similarity index 100% rename from samples/SocialWeather/ConnectionList.cs rename to src/SignalR/samples/SocialWeather/ConnectionList.cs diff --git a/samples/SocialWeather/FormatterResolver.cs b/src/SignalR/samples/SocialWeather/FormatterResolver.cs similarity index 100% rename from samples/SocialWeather/FormatterResolver.cs rename to src/SignalR/samples/SocialWeather/FormatterResolver.cs diff --git a/samples/SocialWeather/IStreamFormatter.cs b/src/SignalR/samples/SocialWeather/IStreamFormatter.cs similarity index 100% rename from samples/SocialWeather/IStreamFormatter.cs rename to src/SignalR/samples/SocialWeather/IStreamFormatter.cs diff --git a/samples/SocialWeather/Json/JSonStreamFormatter.cs b/src/SignalR/samples/SocialWeather/Json/JSonStreamFormatter.cs similarity index 100% rename from samples/SocialWeather/Json/JSonStreamFormatter.cs rename to src/SignalR/samples/SocialWeather/Json/JSonStreamFormatter.cs diff --git a/samples/SocialWeather/PersistentConnectionLifeTimeManager.cs b/src/SignalR/samples/SocialWeather/PersistentConnectionLifeTimeManager.cs similarity index 100% rename from samples/SocialWeather/PersistentConnectionLifeTimeManager.cs rename to src/SignalR/samples/SocialWeather/PersistentConnectionLifeTimeManager.cs diff --git a/samples/SocialWeather/Pipe/PipeWeatherStreamFormatter.cs b/src/SignalR/samples/SocialWeather/Pipe/PipeWeatherStreamFormatter.cs similarity index 100% rename from samples/SocialWeather/Pipe/PipeWeatherStreamFormatter.cs rename to src/SignalR/samples/SocialWeather/Pipe/PipeWeatherStreamFormatter.cs diff --git a/samples/SocialWeather/Program.cs b/src/SignalR/samples/SocialWeather/Program.cs similarity index 100% rename from samples/SocialWeather/Program.cs rename to src/SignalR/samples/SocialWeather/Program.cs diff --git a/samples/SocialWeather/Protobuf/ProtobufWeatherStreamFormatter.cs b/src/SignalR/samples/SocialWeather/Protobuf/ProtobufWeatherStreamFormatter.cs similarity index 100% rename from samples/SocialWeather/Protobuf/ProtobufWeatherStreamFormatter.cs rename to src/SignalR/samples/SocialWeather/Protobuf/ProtobufWeatherStreamFormatter.cs diff --git a/samples/SocialWeather/Protobuf/WeatherReport.cs b/src/SignalR/samples/SocialWeather/Protobuf/WeatherReport.cs similarity index 100% rename from samples/SocialWeather/Protobuf/WeatherReport.cs rename to src/SignalR/samples/SocialWeather/Protobuf/WeatherReport.cs diff --git a/samples/SocialWeather/Protobuf/WeatherReport.proto b/src/SignalR/samples/SocialWeather/Protobuf/WeatherReport.proto similarity index 100% rename from samples/SocialWeather/Protobuf/WeatherReport.proto rename to src/SignalR/samples/SocialWeather/Protobuf/WeatherReport.proto diff --git a/samples/SocialWeather/SocialWeather.csproj b/src/SignalR/samples/SocialWeather/SocialWeather.csproj similarity index 100% rename from samples/SocialWeather/SocialWeather.csproj rename to src/SignalR/samples/SocialWeather/SocialWeather.csproj diff --git a/samples/SocialWeather/SocialWeatherConnectionHandler.cs b/src/SignalR/samples/SocialWeather/SocialWeatherConnectionHandler.cs similarity index 100% rename from samples/SocialWeather/SocialWeatherConnectionHandler.cs rename to src/SignalR/samples/SocialWeather/SocialWeatherConnectionHandler.cs diff --git a/samples/SocialWeather/Startup.cs b/src/SignalR/samples/SocialWeather/Startup.cs similarity index 100% rename from samples/SocialWeather/Startup.cs rename to src/SignalR/samples/SocialWeather/Startup.cs diff --git a/samples/SocialWeather/WeatherReport.cs b/src/SignalR/samples/SocialWeather/WeatherReport.cs similarity index 100% rename from samples/SocialWeather/WeatherReport.cs rename to src/SignalR/samples/SocialWeather/WeatherReport.cs diff --git a/samples/SocialWeather/web.config b/src/SignalR/samples/SocialWeather/web.config similarity index 100% rename from samples/SocialWeather/web.config rename to src/SignalR/samples/SocialWeather/web.config diff --git a/samples/SocialWeather/wwwroot/index.html b/src/SignalR/samples/SocialWeather/wwwroot/index.html similarity index 100% rename from samples/SocialWeather/wwwroot/index.html rename to src/SignalR/samples/SocialWeather/wwwroot/index.html diff --git a/samples/WebSocketSample/Program.cs b/src/SignalR/samples/WebSocketSample/Program.cs similarity index 100% rename from samples/WebSocketSample/Program.cs rename to src/SignalR/samples/WebSocketSample/Program.cs diff --git a/samples/WebSocketSample/WebSocketSample.csproj b/src/SignalR/samples/WebSocketSample/WebSocketSample.csproj similarity index 100% rename from samples/WebSocketSample/WebSocketSample.csproj rename to src/SignalR/samples/WebSocketSample/WebSocketSample.csproj diff --git a/specs/HubProtocol.md b/src/SignalR/specs/HubProtocol.md similarity index 100% rename from specs/HubProtocol.md rename to src/SignalR/specs/HubProtocol.md diff --git a/specs/TransportProtocols.md b/src/SignalR/specs/TransportProtocols.md similarity index 100% rename from specs/TransportProtocols.md rename to src/SignalR/specs/TransportProtocols.md diff --git a/src/Common/AwaitableThreadPool.cs b/src/SignalR/src/Common/AwaitableThreadPool.cs similarity index 100% rename from src/Common/AwaitableThreadPool.cs rename to src/SignalR/src/Common/AwaitableThreadPool.cs diff --git a/src/Common/BinaryMessageFormatter.cs b/src/SignalR/src/Common/BinaryMessageFormatter.cs similarity index 100% rename from src/Common/BinaryMessageFormatter.cs rename to src/SignalR/src/Common/BinaryMessageFormatter.cs diff --git a/src/Common/BinaryMessageParser.cs b/src/SignalR/src/Common/BinaryMessageParser.cs similarity index 100% rename from src/Common/BinaryMessageParser.cs rename to src/SignalR/src/Common/BinaryMessageParser.cs diff --git a/src/Common/DuplexPipe.cs b/src/SignalR/src/Common/DuplexPipe.cs similarity index 100% rename from src/Common/DuplexPipe.cs rename to src/SignalR/src/Common/DuplexPipe.cs diff --git a/src/Common/ForceAsyncAwaiter.cs b/src/SignalR/src/Common/ForceAsyncAwaiter.cs similarity index 100% rename from src/Common/ForceAsyncAwaiter.cs rename to src/SignalR/src/Common/ForceAsyncAwaiter.cs diff --git a/src/Common/JsonUtils.cs b/src/SignalR/src/Common/JsonUtils.cs similarity index 100% rename from src/Common/JsonUtils.cs rename to src/SignalR/src/Common/JsonUtils.cs diff --git a/src/Common/MemoryBufferWriter.cs b/src/SignalR/src/Common/MemoryBufferWriter.cs similarity index 100% rename from src/Common/MemoryBufferWriter.cs rename to src/SignalR/src/Common/MemoryBufferWriter.cs diff --git a/src/Common/PipeWriterStream.cs b/src/SignalR/src/Common/PipeWriterStream.cs similarity index 100% rename from src/Common/PipeWriterStream.cs rename to src/SignalR/src/Common/PipeWriterStream.cs diff --git a/src/Common/ReflectionHelper.cs b/src/SignalR/src/Common/ReflectionHelper.cs similarity index 100% rename from src/Common/ReflectionHelper.cs rename to src/SignalR/src/Common/ReflectionHelper.cs diff --git a/src/Common/StreamExtensions.cs b/src/SignalR/src/Common/StreamExtensions.cs similarity index 100% rename from src/Common/StreamExtensions.cs rename to src/SignalR/src/Common/StreamExtensions.cs diff --git a/src/Common/TextMessageFormatter.cs b/src/SignalR/src/Common/TextMessageFormatter.cs similarity index 100% rename from src/Common/TextMessageFormatter.cs rename to src/SignalR/src/Common/TextMessageFormatter.cs diff --git a/src/Common/TextMessageParser.cs b/src/SignalR/src/Common/TextMessageParser.cs similarity index 100% rename from src/Common/TextMessageParser.cs rename to src/SignalR/src/Common/TextMessageParser.cs diff --git a/src/Common/TimerAwaitable.cs b/src/SignalR/src/Common/TimerAwaitable.cs similarity index 100% rename from src/Common/TimerAwaitable.cs rename to src/SignalR/src/Common/TimerAwaitable.cs diff --git a/src/Common/Utf8BufferTextReader.cs b/src/SignalR/src/Common/Utf8BufferTextReader.cs similarity index 100% rename from src/Common/Utf8BufferTextReader.cs rename to src/SignalR/src/Common/Utf8BufferTextReader.cs diff --git a/src/Common/Utf8BufferTextWriter.cs b/src/SignalR/src/Common/Utf8BufferTextWriter.cs similarity index 100% rename from src/Common/Utf8BufferTextWriter.cs rename to src/SignalR/src/Common/Utf8BufferTextWriter.cs diff --git a/src/Common/WebSocketExtensions.cs b/src/SignalR/src/Common/WebSocketExtensions.cs similarity index 100% rename from src/Common/WebSocketExtensions.cs rename to src/SignalR/src/Common/WebSocketExtensions.cs diff --git a/src/Directory.Build.props b/src/SignalR/src/Directory.Build.props similarity index 100% rename from src/Directory.Build.props rename to src/SignalR/src/Directory.Build.props diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.Log.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.Log.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.Log.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.Log.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnection.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnectionOptions.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnectionOptions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnectionOptions.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/HttpConnectionOptions.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/AccessTokenHttpMessageHandler.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/AccessTokenHttpMessageHandler.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/AccessTokenHttpMessageHandler.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/AccessTokenHttpMessageHandler.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ClientPipeOptions.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ClientPipeOptions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ClientPipeOptions.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ClientPipeOptions.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ConnectionLogScope.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ConnectionLogScope.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ConnectionLogScope.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ConnectionLogScope.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/Constants.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/Constants.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/Constants.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/Constants.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/DefaultTransportFactory.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/DefaultTransportFactory.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/DefaultTransportFactory.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/DefaultTransportFactory.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ITransport.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ITransport.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ITransport.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ITransport.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ITransportFactory.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ITransportFactory.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ITransportFactory.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ITransportFactory.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/LoggingHttpMessageHandler.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/LoggingHttpMessageHandler.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/LoggingHttpMessageHandler.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/LoggingHttpMessageHandler.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/LongPollingTransport.Log.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/LongPollingTransport.Log.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/LongPollingTransport.Log.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/LongPollingTransport.Log.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/LongPollingTransport.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/LongPollingTransport.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/LongPollingTransport.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/LongPollingTransport.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/PipeReaderFactory.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/PipeReaderFactory.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/PipeReaderFactory.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/PipeReaderFactory.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/SendUtils.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/SendUtils.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/SendUtils.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/SendUtils.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsMessageParser.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsMessageParser.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsMessageParser.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsMessageParser.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsTransport.Log.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsTransport.Log.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsTransport.Log.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsTransport.Log.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsTransport.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsTransport.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsTransport.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/ServerSentEventsTransport.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/TaskExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/TaskExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/TaskExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/TaskExtensions.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/Utils.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/Utils.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/Utils.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/Utils.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.Log.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.Log.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.Log.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.Log.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Internal/WebSocketsTransport.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Microsoft.AspNetCore.Http.Connections.Client.csproj b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Microsoft.AspNetCore.Http.Connections.Client.csproj similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Microsoft.AspNetCore.Http.Connections.Client.csproj rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Microsoft.AspNetCore.Http.Connections.Client.csproj diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/Properties/AssemblyInfo.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Properties/AssemblyInfo.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/Properties/AssemblyInfo.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/Properties/AssemblyInfo.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Client/baseline.netcore.json b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/baseline.netcore.json similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Client/baseline.netcore.json rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Client/baseline.netcore.json diff --git a/src/Microsoft.AspNetCore.Http.Connections.Common/AvailableTransport.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/AvailableTransport.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Common/AvailableTransport.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/AvailableTransport.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Common/HttpTransportType.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/HttpTransportType.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Common/HttpTransportType.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/HttpTransportType.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Common/HttpTransports.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/HttpTransports.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Common/HttpTransports.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/HttpTransports.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Common/Microsoft.AspNetCore.Http.Connections.Common.csproj b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/Microsoft.AspNetCore.Http.Connections.Common.csproj similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Common/Microsoft.AspNetCore.Http.Connections.Common.csproj rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/Microsoft.AspNetCore.Http.Connections.Common.csproj diff --git a/src/Microsoft.AspNetCore.Http.Connections.Common/NegotiateProtocol.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/NegotiateProtocol.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Common/NegotiateProtocol.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/NegotiateProtocol.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Common/NegotiationResponse.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/NegotiationResponse.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Common/NegotiationResponse.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/NegotiationResponse.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections.Common/baseline.netcore.json b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/baseline.netcore.json similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections.Common/baseline.netcore.json rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections.Common/baseline.netcore.json diff --git a/src/Microsoft.AspNetCore.Http.Connections/ConnectionsAppBuilderExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/ConnectionsAppBuilderExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/ConnectionsAppBuilderExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/ConnectionsAppBuilderExtensions.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/ConnectionsDependencyInjectionExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/ConnectionsDependencyInjectionExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/ConnectionsDependencyInjectionExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/ConnectionsDependencyInjectionExtensions.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/ConnectionsRouteBuilder.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/ConnectionsRouteBuilder.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/ConnectionsRouteBuilder.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/ConnectionsRouteBuilder.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Features/IHttpContextFeature.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Features/IHttpContextFeature.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Features/IHttpContextFeature.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Features/IHttpContextFeature.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Features/IHttpTransportFeature.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Features/IHttpTransportFeature.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Features/IHttpTransportFeature.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Features/IHttpTransportFeature.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionContextExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionContextExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/HttpConnectionContextExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionContextExtensions.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionDispatcherOptions.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionDispatcherOptions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/HttpConnectionDispatcherOptions.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionDispatcherOptions.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/AuthorizeHelper.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/AuthorizeHelper.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/AuthorizeHelper.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/AuthorizeHelper.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/ConnectionLogScope.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/ConnectionLogScope.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/ConnectionLogScope.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/ConnectionLogScope.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionContext.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionContext.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionContext.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionContext.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.Log.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.Log.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.Log.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.Log.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionDispatcher.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionManager.Log.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionManager.Log.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionManager.Log.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionManager.Log.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionManager.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionManager.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionManager.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionManager.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionStatus.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionStatus.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionStatus.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionStatus.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionsEventSource.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionsEventSource.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionsEventSource.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/HttpConnectionsEventSource.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/IHttpTransport.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/IHttpTransport.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/IHttpTransport.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/IHttpTransport.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/LongPollingTransport.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/LongPollingTransport.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/LongPollingTransport.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/LongPollingTransport.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/ServerSentEventsMessageFormatter.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/ServerSentEventsMessageFormatter.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/ServerSentEventsMessageFormatter.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/ServerSentEventsMessageFormatter.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/ServerSentEventsTransport.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/ServerSentEventsTransport.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/ServerSentEventsTransport.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/ServerSentEventsTransport.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.Log.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.Log.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.Log.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.Log.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Internal/Transports/WebSocketsTransport.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/LongPollingOptions.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/LongPollingOptions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/LongPollingOptions.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/LongPollingOptions.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/Microsoft.AspNetCore.Http.Connections.csproj b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Microsoft.AspNetCore.Http.Connections.csproj similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Microsoft.AspNetCore.Http.Connections.csproj rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Microsoft.AspNetCore.Http.Connections.csproj diff --git a/src/Microsoft.AspNetCore.Http.Connections/Properties/AssemblyInfo.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Properties/AssemblyInfo.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/Properties/AssemblyInfo.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/Properties/AssemblyInfo.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/WebSocketOptions.cs b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/WebSocketOptions.cs similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/WebSocketOptions.cs rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/WebSocketOptions.cs diff --git a/src/Microsoft.AspNetCore.Http.Connections/baseline.netcore.json b/src/SignalR/src/Microsoft.AspNetCore.Http.Connections/baseline.netcore.json similarity index 100% rename from src/Microsoft.AspNetCore.Http.Connections/baseline.netcore.json rename to src/SignalR/src/Microsoft.AspNetCore.Http.Connections/baseline.netcore.json diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.Log.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.Log.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.Log.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.Log.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilder.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilder.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilder.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilder.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilderExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilderExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilderExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionBuilderExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.InvokeAsync.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.InvokeAsync.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.InvokeAsync.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.InvokeAsync.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.InvokeAsyncGeneric.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.InvokeAsyncGeneric.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.InvokeAsyncGeneric.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.InvokeAsyncGeneric.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.SendAsync.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.SendAsync.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.SendAsync.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.SendAsync.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.StreamAsChannelAsync.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.StreamAsChannelAsync.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.StreamAsChannelAsync.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.StreamAsChannelAsync.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionState.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionState.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionState.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnectionState.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/IConnectionFactory.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/IConnectionFactory.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/IConnectionFactory.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/IConnectionFactory.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/IHubConnectionBuilder.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/IHubConnectionBuilder.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/IHubConnectionBuilder.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/IHubConnectionBuilder.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/Internal/ConnectionLogScope.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/Internal/ConnectionLogScope.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/Internal/ConnectionLogScope.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/Internal/ConnectionLogScope.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/Internal/InvocationRequest.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/Internal/InvocationRequest.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/Internal/InvocationRequest.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/Internal/InvocationRequest.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/Microsoft.AspNetCore.SignalR.Client.Core.csproj b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/Microsoft.AspNetCore.SignalR.Client.Core.csproj similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/Microsoft.AspNetCore.SignalR.Client.Core.csproj rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/Microsoft.AspNetCore.SignalR.Client.Core.csproj diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/Properties/AssemblyInfo.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/Properties/AssemblyInfo.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/Properties/AssemblyInfo.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/Properties/AssemblyInfo.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/baseline.netcore.json b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/baseline.netcore.json similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client.Core/baseline.netcore.json rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client.Core/baseline.netcore.json diff --git a/src/Microsoft.AspNetCore.SignalR.Client/HttpConnectionFactory.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client/HttpConnectionFactory.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client/HttpConnectionFactory.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client/HttpConnectionFactory.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client/HubConnectionBuilderHttpExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client/HubConnectionBuilderHttpExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client/HubConnectionBuilderHttpExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client/HubConnectionBuilderHttpExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Client/Microsoft.AspNetCore.SignalR.Client.csproj b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client/Microsoft.AspNetCore.SignalR.Client.csproj similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client/Microsoft.AspNetCore.SignalR.Client.csproj rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client/Microsoft.AspNetCore.SignalR.Client.csproj diff --git a/src/Microsoft.AspNetCore.SignalR.Client/baseline.netcore.json b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Client/baseline.netcore.json similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Client/baseline.netcore.json rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Client/baseline.netcore.json diff --git a/src/Microsoft.AspNetCore.SignalR.Common/HubException.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/HubException.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/HubException.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/HubException.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/IInvocationBinder.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/IInvocationBinder.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/IInvocationBinder.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/IInvocationBinder.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/ISignalRBuilder.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/ISignalRBuilder.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/ISignalRBuilder.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/ISignalRBuilder.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Microsoft.AspNetCore.SignalR.Common.csproj diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Properties/AssemblyInfo.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Properties/AssemblyInfo.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Properties/AssemblyInfo.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Properties/AssemblyInfo.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/CancelInvocationMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/CancelInvocationMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/CancelInvocationMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/CancelInvocationMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/CloseMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/CloseMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/CloseMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/CloseMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/CompletionMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/CompletionMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/CompletionMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/CompletionMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeProtocol.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeProtocol.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeProtocol.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeProtocol.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeRequestMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeRequestMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeRequestMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeRequestMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeResponseMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeResponseMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeResponseMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HandshakeResponseMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubInvocationMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubInvocationMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubInvocationMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubInvocationMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubMethodInvocationMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubMethodInvocationMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubMethodInvocationMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubMethodInvocationMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolConstants.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolConstants.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolConstants.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolConstants.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/HubProtocolExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/IHubProtocol.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/IHubProtocol.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/IHubProtocol.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/IHubProtocol.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/InvocationBindingFailureMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/InvocationBindingFailureMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/InvocationBindingFailureMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/InvocationBindingFailureMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/PingMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/PingMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/PingMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/PingMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamBindingFailureMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamBindingFailureMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamBindingFailureMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamBindingFailureMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamCompleteMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamCompleteMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamCompleteMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamCompleteMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamDataMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamDataMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamDataMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamDataMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamItemMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamItemMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamItemMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamItemMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamPlaceholder.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamPlaceholder.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamPlaceholder.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/Protocol/StreamPlaceholder.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Common/baseline.netcore.json b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/baseline.netcore.json similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/baseline.netcore.json rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/baseline.netcore.json diff --git a/src/Microsoft.AspNetCore.SignalR.Common/breakingchanges.netcore.json b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/breakingchanges.netcore.json similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Common/breakingchanges.netcore.json rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Common/breakingchanges.netcore.json diff --git a/src/Microsoft.AspNetCore.SignalR.Core/ClientProxyExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/ClientProxyExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/ClientProxyExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/ClientProxyExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/DefaultHubLifetimeManager.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/DefaultHubLifetimeManager.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/DefaultHubLifetimeManager.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/DefaultHubLifetimeManager.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/DefaultUserIdProvider.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/DefaultUserIdProvider.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/DefaultUserIdProvider.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/DefaultUserIdProvider.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/DynamicHub.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/DynamicHub.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/DynamicHub.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/DynamicHub.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/DynamicHubClients.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/DynamicHubClients.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/DynamicHubClients.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/DynamicHubClients.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Hub.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Hub.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Hub.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Hub.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubCallerContext.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubCallerContext.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/HubCallerContext.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubCallerContext.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubClientsExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubClientsExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/HubClientsExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubClientsExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionHandler.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionHandler.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/HubConnectionHandler.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionHandler.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionStore.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionStore.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/HubConnectionStore.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionStore.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubLifetimeManager.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubLifetimeManager.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/HubLifetimeManager.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubLifetimeManager.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubMethodNameAttribute.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubMethodNameAttribute.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/HubMethodNameAttribute.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubMethodNameAttribute.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubOptions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubOptions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/HubOptions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubOptions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubOptions`T.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubOptions`T.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/HubOptions`T.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/HubOptions`T.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Hub`T.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Hub`T.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Hub`T.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Hub`T.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/IClientProxy.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IClientProxy.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/IClientProxy.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IClientProxy.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/IGroupManager.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IGroupManager.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/IGroupManager.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IGroupManager.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/IHubActivator.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubActivator.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/IHubActivator.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubActivator.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/IHubCallerClients.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubCallerClients.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/IHubCallerClients.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubCallerClients.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/IHubCallerClients`T.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubCallerClients`T.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/IHubCallerClients`T.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubCallerClients`T.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/IHubClients.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubClients.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/IHubClients.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubClients.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/IHubClients`T.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubClients`T.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/IHubClients`T.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubClients`T.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/IHubContext.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubContext.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/IHubContext.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubContext.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/IHubContext`T.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubContext`T.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/IHubContext`T.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubContext`T.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/IHubProtocolResolver.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubProtocolResolver.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/IHubProtocolResolver.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IHubProtocolResolver.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/ISignalRServerBuilder.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/ISignalRServerBuilder.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/ISignalRServerBuilder.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/ISignalRServerBuilder.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/IUserIdProvider.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IUserIdProvider.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/IUserIdProvider.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/IUserIdProvider.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/AsyncEnumeratorAdapters.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/AsyncEnumeratorAdapters.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/AsyncEnumeratorAdapters.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/AsyncEnumeratorAdapters.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubActivator.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubActivator.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubActivator.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubActivator.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubCallerContext.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubCallerContext.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubCallerContext.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubCallerContext.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.Log.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.Log.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.Log.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.Log.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubDispatcher.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubProtocolResolver.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubProtocolResolver.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubProtocolResolver.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/DefaultHubProtocolResolver.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/DynamicClientProxy.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/DynamicClientProxy.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/DynamicClientProxy.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/DynamicClientProxy.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/ErrorMessageHelper.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/ErrorMessageHelper.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/ErrorMessageHelper.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/ErrorMessageHelper.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/GroupManager.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/GroupManager.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/GroupManager.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/GroupManager.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubCallerClients.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubCallerClients.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/HubCallerClients.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubCallerClients.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubClients.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubClients.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/HubClients.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubClients.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubClients`T.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubClients`T.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/HubClients`T.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubClients`T.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubConnectionBinder.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubConnectionBinder.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/HubConnectionBinder.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubConnectionBinder.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubContext.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubContext.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/HubContext.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubContext.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubContext`T.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubContext`T.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/HubContext`T.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubContext`T.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubDispatcher.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubDispatcher.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/HubDispatcher.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubDispatcher.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubGroupList.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubGroupList.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/HubGroupList.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubGroupList.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubMethodDescriptor.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubMethodDescriptor.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/HubMethodDescriptor.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubMethodDescriptor.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubOptionsSetup.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubOptionsSetup.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/HubOptionsSetup.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubOptionsSetup.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubOptionsSetup`T.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubOptionsSetup`T.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/HubOptionsSetup`T.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubOptionsSetup`T.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubReflectionHelper.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubReflectionHelper.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/HubReflectionHelper.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/HubReflectionHelper.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/Proxies.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/Proxies.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/Proxies.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/Proxies.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRBuilder.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRBuilder.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRBuilder.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRBuilder.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRCoreMarkerService.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRCoreMarkerService.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRCoreMarkerService.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/SignalRCoreMarkerService.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/TaskCache.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/TaskCache.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/TaskCache.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/TaskCache.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/TypeBaseEnumerationExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/TypeBaseEnumerationExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/TypeBaseEnumerationExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/TypeBaseEnumerationExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/TypedClientBuilder.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/TypedClientBuilder.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/TypedClientBuilder.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/TypedClientBuilder.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Internal/TypedHubClients.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/TypedHubClients.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Internal/TypedHubClients.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Internal/TypedHubClients.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Microsoft.AspNetCore.SignalR.Core.csproj b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Microsoft.AspNetCore.SignalR.Core.csproj similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Microsoft.AspNetCore.SignalR.Core.csproj rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Microsoft.AspNetCore.SignalR.Core.csproj diff --git a/src/Microsoft.AspNetCore.SignalR.Core/Properties/AssemblyInfo.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Properties/AssemblyInfo.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/Properties/AssemblyInfo.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/Properties/AssemblyInfo.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/SerializedHubMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/SerializedHubMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/SerializedHubMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/SerializedHubMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/SerializedMessage.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/SerializedMessage.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/SerializedMessage.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/SerializedMessage.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/SignalRConnectionBuilderExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/SignalRConnectionBuilderExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/SignalRConnectionBuilderExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/SignalRConnectionBuilderExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/SignalRDependencyInjectionExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/SignalRDependencyInjectionExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/SignalRDependencyInjectionExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/SignalRDependencyInjectionExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/StreamTracker.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/StreamTracker.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/StreamTracker.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/StreamTracker.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Core/baseline.netcore.json b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/baseline.netcore.json similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Core/baseline.netcore.json rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Core/baseline.netcore.json diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.Json/JsonHubProtocolOptions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.Json/JsonHubProtocolOptions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Protocols.Json/JsonHubProtocolOptions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.Json/JsonHubProtocolOptions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.Json/JsonProtocolDependencyInjectionExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.Json/JsonProtocolDependencyInjectionExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Protocols.Json/JsonProtocolDependencyInjectionExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.Json/JsonProtocolDependencyInjectionExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Protocols.Json/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Microsoft.AspNetCore.SignalR.Protocols.Json.csproj diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Protocol/JsonHubProtocol.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Protocol/JsonHubProtocol.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Protocols.Json/Protocol/JsonHubProtocol.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Protocol/JsonHubProtocol.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.Json/baseline.netcore.json b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.Json/baseline.netcore.json similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Protocols.Json/baseline.netcore.json rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.Json/baseline.netcore.json diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/MessagePackHubProtocolOptions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/MessagePackHubProtocolOptions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/MessagePackHubProtocolOptions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/MessagePackHubProtocolOptions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/MessagePackProtocolDependencyInjectionExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/MessagePackProtocolDependencyInjectionExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/MessagePackProtocolDependencyInjectionExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/MessagePackProtocolDependencyInjectionExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Microsoft.AspNetCore.SignalR.Protocols.MessagePack.csproj diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Protocol/MessagePackHubProtocol.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Protocol/MessagePackHubProtocol.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Protocol/MessagePackHubProtocol.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/Protocol/MessagePackHubProtocol.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/baseline.netcore.json b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/baseline.netcore.json similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/baseline.netcore.json rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Protocols.MessagePack/baseline.netcore.json diff --git a/src/Microsoft.AspNetCore.SignalR.Specification.Tests/HubLifetimeManagerTestBase.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Specification.Tests/HubLifetimeManagerTestBase.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Specification.Tests/HubLifetimeManagerTestBase.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Specification.Tests/HubLifetimeManagerTestBase.cs diff --git a/src/Microsoft.AspNetCore.SignalR.Specification.Tests/Microsoft.AspNetCore.SignalR.Specification.Tests.csproj b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Specification.Tests/Microsoft.AspNetCore.SignalR.Specification.Tests.csproj similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Specification.Tests/Microsoft.AspNetCore.SignalR.Specification.Tests.csproj rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Specification.Tests/Microsoft.AspNetCore.SignalR.Specification.Tests.csproj diff --git a/src/Microsoft.AspNetCore.SignalR.Specification.Tests/ScaleoutHubLifetimeManagerTests.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.Specification.Tests/ScaleoutHubLifetimeManagerTests.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.Specification.Tests/ScaleoutHubLifetimeManagerTests.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.Specification.Tests/ScaleoutHubLifetimeManagerTests.cs diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/AckHandler.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/AckHandler.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/AckHandler.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/AckHandler.cs diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/GroupAction.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/GroupAction.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/GroupAction.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/GroupAction.cs diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/MessagePackUtil.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/MessagePackUtil.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/MessagePackUtil.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/MessagePackUtil.cs diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisChannels.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisChannels.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisChannels.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisChannels.cs diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisGroupCommand.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisGroupCommand.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisGroupCommand.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisGroupCommand.cs diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisInvocation.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisInvocation.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisInvocation.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisInvocation.cs diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisLog.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisLog.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisLog.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisLog.cs diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisProtocol.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisProtocol.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisProtocol.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisProtocol.cs diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisSubscriptionManager.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisSubscriptionManager.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisSubscriptionManager.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Internal/RedisSubscriptionManager.cs diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj b/src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/Microsoft.AspNetCore.SignalR.StackExchangeRedis.csproj diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisDependencyInjectionExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisDependencyInjectionExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisDependencyInjectionExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisDependencyInjectionExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisHubLifetimeManager.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisHubLifetimeManager.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisHubLifetimeManager.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisHubLifetimeManager.cs diff --git a/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisOptions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisOptions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisOptions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR.StackExchangeRedis/RedisOptions.cs diff --git a/src/Microsoft.AspNetCore.SignalR/GetHttpContextExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR/GetHttpContextExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR/GetHttpContextExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR/GetHttpContextExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR/HubRouteBuilder.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR/HubRouteBuilder.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR/HubRouteBuilder.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR/HubRouteBuilder.cs diff --git a/src/Microsoft.AspNetCore.SignalR/Microsoft.AspNetCore.SignalR.csproj b/src/SignalR/src/Microsoft.AspNetCore.SignalR/Microsoft.AspNetCore.SignalR.csproj similarity index 100% rename from src/Microsoft.AspNetCore.SignalR/Microsoft.AspNetCore.SignalR.csproj rename to src/SignalR/src/Microsoft.AspNetCore.SignalR/Microsoft.AspNetCore.SignalR.csproj diff --git a/src/Microsoft.AspNetCore.SignalR/SignalRAppBuilderExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR/SignalRAppBuilderExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR/SignalRAppBuilderExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR/SignalRAppBuilderExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR/SignalRDependencyInjectionExtensions.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR/SignalRDependencyInjectionExtensions.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR/SignalRDependencyInjectionExtensions.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR/SignalRDependencyInjectionExtensions.cs diff --git a/src/Microsoft.AspNetCore.SignalR/SignalRMarkerService.cs b/src/SignalR/src/Microsoft.AspNetCore.SignalR/SignalRMarkerService.cs similarity index 100% rename from src/Microsoft.AspNetCore.SignalR/SignalRMarkerService.cs rename to src/SignalR/src/Microsoft.AspNetCore.SignalR/SignalRMarkerService.cs diff --git a/src/Microsoft.AspNetCore.SignalR/baseline.netcore.json b/src/SignalR/src/Microsoft.AspNetCore.SignalR/baseline.netcore.json similarity index 100% rename from src/Microsoft.AspNetCore.SignalR/baseline.netcore.json rename to src/SignalR/src/Microsoft.AspNetCore.SignalR/baseline.netcore.json diff --git a/test/Directory.Build.props b/src/SignalR/test/Directory.Build.props similarity index 100% rename from test/Directory.Build.props rename to src/SignalR/test/Directory.Build.props diff --git a/test/Microsoft.AspNetCore.Http.Connections.Tests/ApplicationLifetime.cs b/src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/ApplicationLifetime.cs similarity index 100% rename from test/Microsoft.AspNetCore.Http.Connections.Tests/ApplicationLifetime.cs rename to src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/ApplicationLifetime.cs diff --git a/test/Microsoft.AspNetCore.Http.Connections.Tests/HttpConnectionDispatcherTests.cs b/src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/HttpConnectionDispatcherTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.Http.Connections.Tests/HttpConnectionDispatcherTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/HttpConnectionDispatcherTests.cs diff --git a/test/Microsoft.AspNetCore.Http.Connections.Tests/HttpConnectionManagerTests.cs b/src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/HttpConnectionManagerTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.Http.Connections.Tests/HttpConnectionManagerTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/HttpConnectionManagerTests.cs diff --git a/test/Microsoft.AspNetCore.Http.Connections.Tests/LongPollingTests.cs b/src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/LongPollingTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.Http.Connections.Tests/LongPollingTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/LongPollingTests.cs diff --git a/test/Microsoft.AspNetCore.Http.Connections.Tests/MapConnectionHandlerTests.cs b/src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/MapConnectionHandlerTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.Http.Connections.Tests/MapConnectionHandlerTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/MapConnectionHandlerTests.cs diff --git a/test/Microsoft.AspNetCore.Http.Connections.Tests/Microsoft.AspNetCore.Http.Connections.Tests.csproj b/src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/Microsoft.AspNetCore.Http.Connections.Tests.csproj similarity index 100% rename from test/Microsoft.AspNetCore.Http.Connections.Tests/Microsoft.AspNetCore.Http.Connections.Tests.csproj rename to src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/Microsoft.AspNetCore.Http.Connections.Tests.csproj diff --git a/test/Microsoft.AspNetCore.Http.Connections.Tests/NegotiateProtocolTests.cs b/src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/NegotiateProtocolTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.Http.Connections.Tests/NegotiateProtocolTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/NegotiateProtocolTests.cs diff --git a/test/Microsoft.AspNetCore.Http.Connections.Tests/ServerSentEventsMessageFormatterTests.cs b/src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/ServerSentEventsMessageFormatterTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.Http.Connections.Tests/ServerSentEventsMessageFormatterTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/ServerSentEventsMessageFormatterTests.cs diff --git a/test/Microsoft.AspNetCore.Http.Connections.Tests/ServerSentEventsTests.cs b/src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/ServerSentEventsTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.Http.Connections.Tests/ServerSentEventsTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/ServerSentEventsTests.cs diff --git a/test/Microsoft.AspNetCore.Http.Connections.Tests/TestWebSocketConnectionFeature.cs b/src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/TestWebSocketConnectionFeature.cs similarity index 100% rename from test/Microsoft.AspNetCore.Http.Connections.Tests/TestWebSocketConnectionFeature.cs rename to src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/TestWebSocketConnectionFeature.cs diff --git a/test/Microsoft.AspNetCore.Http.Connections.Tests/WebSocketsTests.cs b/src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/WebSocketsTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.Http.Connections.Tests/WebSocketsTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.Http.Connections.Tests/WebSocketsTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HeaderUserIdProvider.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HeaderUserIdProvider.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HeaderUserIdProvider.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HeaderUserIdProvider.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubConnectionTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubConnectionTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubConnectionTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubConnectionTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubProtocolVersionTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubProtocolVersionTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubProtocolVersionTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/HubProtocolVersionTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Hubs.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Hubs.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Hubs.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Hubs.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Microsoft.AspNetCore.SignalR.Client.FunctionalTests.csproj diff --git a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Startup.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Startup.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Startup.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/Startup.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/VersionJsonHubProtocol.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/VersionJsonHubProtocol.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/VersionJsonHubProtocol.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/VersionJsonHubProtocol.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/VersionStartup.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/VersionStartup.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/VersionStartup.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.FunctionalTests/VersionStartup.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionFactoryTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionFactoryTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionFactoryTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionFactoryTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.ConnectionLifecycle.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.ConnectionLifecycle.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.ConnectionLifecycle.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.ConnectionLifecycle.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Helpers.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Helpers.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Helpers.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Helpers.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Negotiate.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Negotiate.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Negotiate.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Negotiate.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Transport.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Transport.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Transport.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.Transport.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HttpConnectionTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderExtensionsTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderExtensionsTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderExtensionsTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderExtensionsTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionBuilderTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.ConnectionLifecycle.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.ConnectionLifecycle.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.ConnectionLifecycle.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.ConnectionLifecycle.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Extensions.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Extensions.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Extensions.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Extensions.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Helpers.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Helpers.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Helpers.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Helpers.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Protocol.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Protocol.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Protocol.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.Protocol.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/HubConnectionTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/LongPollingTransportTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/LongPollingTransportTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/LongPollingTransportTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/LongPollingTransportTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/Microsoft.AspNetCore.SignalR.Client.Tests.csproj b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/Microsoft.AspNetCore.SignalR.Client.Tests.csproj similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/Microsoft.AspNetCore.SignalR.Client.Tests.csproj rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/Microsoft.AspNetCore.SignalR.Client.Tests.csproj diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/ResponseUtils.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/ResponseUtils.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/ResponseUtils.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/ResponseUtils.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsParserTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsParserTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsParserTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsParserTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsTransportTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsTransportTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsTransportTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/ServerSentEventsTransportTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestConnection.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestConnection.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/TestConnection.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestConnection.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestHttpMessageHandler.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestHttpMessageHandler.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/TestHttpMessageHandler.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestHttpMessageHandler.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestTransport.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestTransport.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/TestTransport.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestTransport.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestTransportFactory.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestTransportFactory.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Client.Tests/TestTransportFactory.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Client.Tests/TestTransportFactory.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageFormatterTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageFormatterTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageFormatterTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageFormatterTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageParserTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageParserTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageParserTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/BinaryMessageParserTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageFormatterTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageFormatterTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageFormatterTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageFormatterTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageParserTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageParserTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageParserTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Formatters/TextMessageParserTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CompositeTestBinder.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CompositeTestBinder.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CompositeTestBinder.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CompositeTestBinder.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CustomObject.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CustomObject.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CustomObject.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/CustomObject.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/HandshakeProtocolTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/HandshakeProtocolTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/HandshakeProtocolTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/HandshakeProtocolTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/HubMessageHelpers.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/HubMessageHelpers.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/HubMessageHelpers.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/HubMessageHelpers.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MemoryBufferWriterTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MemoryBufferWriterTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MemoryBufferWriterTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MemoryBufferWriterTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MessagePackHubProtocolTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MessagePackHubProtocolTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MessagePackHubProtocolTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/MessagePackHubProtocolTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestBinder.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestBinder.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestBinder.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestBinder.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestHubMessageEqualityComparer.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestHubMessageEqualityComparer.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestHubMessageEqualityComparer.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/TestHubMessageEqualityComparer.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/Utf8BufferTextReaderTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/Utf8BufferTextReaderTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/Utf8BufferTextReaderTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/Utf8BufferTextReaderTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/Utf8BufferTextWriterTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/Utf8BufferTextWriterTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/Utf8BufferTextWriterTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/Utf8BufferTextWriterTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Microsoft.AspNetCore.SignalR.Common.Tests.csproj b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Microsoft.AspNetCore.SignalR.Common.Tests.csproj similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Common.Tests/Microsoft.AspNetCore.SignalR.Common.Tests.csproj rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Common.Tests/Microsoft.AspNetCore.SignalR.Common.Tests.csproj diff --git a/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Docker.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Docker.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Docker.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Docker.cs diff --git a/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/EchoHub.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/EchoHub.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/EchoHub.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/EchoHub.cs diff --git a/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests.csproj b/src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests.csproj similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests.csproj rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests.csproj diff --git a/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisDependencyInjectionExtensionsTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisDependencyInjectionExtensionsTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisDependencyInjectionExtensionsTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisDependencyInjectionExtensionsTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisEndToEnd.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisEndToEnd.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisEndToEnd.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisEndToEnd.cs diff --git a/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisHubLifetimeManagerTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisHubLifetimeManagerTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisHubLifetimeManagerTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisHubLifetimeManagerTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisProtocolTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisProtocolTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisProtocolTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisProtocolTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisServerFixture.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisServerFixture.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisServerFixture.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/RedisServerFixture.cs diff --git a/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/SkipIfDockerNotPresentAttribute.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/SkipIfDockerNotPresentAttribute.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/SkipIfDockerNotPresentAttribute.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/SkipIfDockerNotPresentAttribute.cs diff --git a/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Startup.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Startup.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Startup.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/Startup.cs diff --git a/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/TestConnectionMultiplexer.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/TestConnectionMultiplexer.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/TestConnectionMultiplexer.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.StackExchangeRedis.Tests/TestConnectionMultiplexer.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/CancellationTokenExtensions.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/CancellationTokenExtensions.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/CancellationTokenExtensions.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/CancellationTokenExtensions.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/ChannelExtensions.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/ChannelExtensions.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/ChannelExtensions.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/ChannelExtensions.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/DelegateConnectionFactory.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/DelegateConnectionFactory.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/DelegateConnectionFactory.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/DelegateConnectionFactory.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/DummyHubProtocol.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/DummyHubProtocol.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/DummyHubProtocol.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/DummyHubProtocol.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/ExceptionMessageExtensions.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/ExceptionMessageExtensions.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/ExceptionMessageExtensions.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/ExceptionMessageExtensions.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/FunctionalTestBase.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/FunctionalTestBase.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/FunctionalTestBase.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/FunctionalTestBase.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/HubConnectionBuilderTestExtensions.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/HubConnectionBuilderTestExtensions.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/HubConnectionBuilderTestExtensions.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/HubConnectionBuilderTestExtensions.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/HubConnectionContextUtils.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/HubConnectionContextUtils.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/HubConnectionContextUtils.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/HubConnectionContextUtils.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/HubProtocolHelpers.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/HubProtocolHelpers.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/HubProtocolHelpers.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/HubProtocolHelpers.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/InProcessTestServer.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/InProcessTestServer.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/InProcessTestServer.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/InProcessTestServer.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/LogRecord.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/LogRecord.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/LogRecord.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/LogRecord.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/LogSinkProvider.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/LogSinkProvider.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/LogSinkProvider.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/LogSinkProvider.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/Microsoft.AspNetCore.SignalR.Tests.Utils.csproj b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/Microsoft.AspNetCore.SignalR.Tests.Utils.csproj similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/Microsoft.AspNetCore.SignalR.Tests.Utils.csproj rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/Microsoft.AspNetCore.SignalR.Tests.Utils.csproj diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/PipeCompletionExtensions.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/PipeCompletionExtensions.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/PipeCompletionExtensions.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/PipeCompletionExtensions.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/PipeReaderExtensions.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/PipeReaderExtensions.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/PipeReaderExtensions.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/PipeReaderExtensions.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/ServerLogScope.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/ServerLogScope.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/ServerLogScope.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/ServerLogScope.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/SyncPoint.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/SyncPoint.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/SyncPoint.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/SyncPoint.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TaskExtensions.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TaskExtensions.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/TaskExtensions.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TaskExtensions.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestClient.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestClient.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestClient.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestClient.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestHelpers.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestHelpers.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestHelpers.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/TestHelpers.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/VerifiableLoggedTest.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/VerifiableLoggedTest.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/VerifiableLoggedTest.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/VerifiableLoggedTest.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/VerifyNoErrorsScope.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/VerifyNoErrorsScope.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/VerifyNoErrorsScope.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/VerifyNoErrorsScope.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/WebSocketsSupportedConditionAttribute.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/WebSocketsSupportedConditionAttribute.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/WebSocketsSupportedConditionAttribute.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/WebSocketsSupportedConditionAttribute.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests.Utils/WrappingLoggerFactory.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/WrappingLoggerFactory.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests.Utils/WrappingLoggerFactory.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests.Utils/WrappingLoggerFactory.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/AddSignalRTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/AddSignalRTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/AddSignalRTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/AddSignalRTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/AuthConnectionHandler.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/AuthConnectionHandler.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/AuthConnectionHandler.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/AuthConnectionHandler.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/CancellationDisposable.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/CancellationDisposable.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/CancellationDisposable.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/CancellationDisposable.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/ClientProxyTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/ClientProxyTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/ClientProxyTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/ClientProxyTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/DefaultHubActivatorTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/DefaultHubActivatorTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/DefaultHubActivatorTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/DefaultHubActivatorTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/DefaultHubLifetimeManagerTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/DefaultHubLifetimeManagerTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/DefaultHubLifetimeManagerTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/DefaultHubLifetimeManagerTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/DefaultTransportFactoryTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/DefaultTransportFactoryTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/DefaultTransportFactoryTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/DefaultTransportFactoryTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/EchoConnectionHandler.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/EchoConnectionHandler.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/EchoConnectionHandler.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/EchoConnectionHandler.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/EndToEndTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/EndToEndTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/EndToEndTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/EndToEndTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/HttpHeaderConnectionHandler.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/HttpHeaderConnectionHandler.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/HttpHeaderConnectionHandler.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/HttpHeaderConnectionHandler.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Hubs.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Hubs.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Hubs.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Hubs.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Utils.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Utils.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Utils.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTestUtils/Utils.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/HubConnectionHandlerTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/HubReflectionHelperTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/HubReflectionHelperTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/HubReflectionHelperTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/HubReflectionHelperTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/Internal/DefaultHubProtocolResolverTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/Internal/DefaultHubProtocolResolverTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/Internal/DefaultHubProtocolResolverTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/Internal/DefaultHubProtocolResolverTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/Internal/TypedClientBuilderTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/Internal/TypedClientBuilderTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/Internal/TypedClientBuilderTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/Internal/TypedClientBuilderTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/MapSignalRTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/MapSignalRTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/MapSignalRTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/MapSignalRTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/Microsoft.AspNetCore.SignalR.Tests.csproj diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/SerializedHubMessageTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/SerializedHubMessageTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/SerializedHubMessageTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/SerializedHubMessageTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/Startup.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/Startup.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/Startup.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/Startup.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/UncreatableHub.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/UncreatableHub.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/UncreatableHub.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/UncreatableHub.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/WebSocketsTransportTests.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/WebSocketsTransportTests.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/WebSocketsTransportTests.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/WebSocketsTransportTests.cs diff --git a/test/Microsoft.AspNetCore.SignalR.Tests/WriteThenCloseConnectionHandler.cs b/src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/WriteThenCloseConnectionHandler.cs similarity index 100% rename from test/Microsoft.AspNetCore.SignalR.Tests/WriteThenCloseConnectionHandler.cs rename to src/SignalR/test/Microsoft.AspNetCore.SignalR.Tests/WriteThenCloseConnectionHandler.cs diff --git a/test/xunit.runner.json b/src/SignalR/test/xunit.runner.json similarity index 100% rename from test/xunit.runner.json rename to src/SignalR/test/xunit.runner.json diff --git a/version.props b/src/SignalR/version.props similarity index 100% rename from version.props rename to src/SignalR/version.props