Merge branch 'master' of https://github.com/Azure/amqpnetlite into nanoframework-dev
This commit is contained in:
Коммит
3cf6a8dffe
|
@ -29,18 +29,27 @@
|
|||
<Reference Include="mscorlib, Version=1.10.5.4, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.CoreLibrary.1.10.5\lib\mscorlib.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<SpecificVersion>True</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="nanoFramework.Runtime.Events, Version=1.9.1.3, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.Runtime.Events.1.9.1\lib\nanoFramework.Runtime.Events.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<SpecificVersion>True</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="nanoFramework.System.Collections, Version=1.2.0.3, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.System.Collections.1.2.0\lib\nanoFramework.System.Collections.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<SpecificVersion>True</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="nanoFramework.System.Text, Version=1.1.1.3, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.System.Text.1.1.1\lib\nanoFramework.System.Text.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<SpecificVersion>True</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="System.Math, Version=1.4.1.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.System.Math.1.4.1-preview.5\lib\System.Math.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<SpecificVersion>True</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="System.Math, Version=1.4.1.3, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.System.Math.1.4.1\lib\System.Math.dll</HintPath>
|
||||
|
@ -49,6 +58,7 @@
|
|||
<Reference Include="System.Net, Version=1.7.0.3, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.System.Net.1.7.0\lib\System.Net.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<SpecificVersion>True</SpecificVersion>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
<package id="nanoFramework.System.Math" version="1.4.1" targetFramework="netnanoframework10" />
|
||||
<package id="nanoFramework.System.Net" version="1.7.0" targetFramework="netnanoframework10" />
|
||||
<package id="nanoFramework.System.Text" version="1.1.1" targetFramework="netnanoframework10" />
|
||||
</packages>
|
||||
</packages>
|
||||
|
|
|
@ -29,22 +29,32 @@
|
|||
<Reference Include="mscorlib, Version=1.10.5.4, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.CoreLibrary.1.10.5\lib\mscorlib.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<SpecificVersion>True</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="nanoFramework.Runtime.Events, Version=1.9.1.3, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.Runtime.Events.1.9.1\lib\nanoFramework.Runtime.Events.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<SpecificVersion>True</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="nanoFramework.System.Collections, Version=1.2.0.3, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.System.Collections.1.2.0\lib\nanoFramework.System.Collections.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<SpecificVersion>True</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="nanoFramework.System.Text, Version=1.1.1.3, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.System.Text.1.1.1\lib\nanoFramework.System.Text.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<SpecificVersion>True</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="System.Device.Gpio, Version=1.0.1.2, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.System.Device.Gpio.1.0.1\lib\System.Device.Gpio.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<SpecificVersion>True</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="System.Math, Version=1.4.1.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.System.Math.1.4.1-preview.5\lib\System.Math.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<SpecificVersion>True</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="System.Math, Version=1.4.1.3, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.System.Math.1.4.1\lib\System.Math.dll</HintPath>
|
||||
|
@ -53,6 +63,7 @@
|
|||
<Reference Include="System.Net, Version=1.7.0.3, Culture=neutral, PublicKeyToken=c07d481e9758c731">
|
||||
<HintPath>..\..\..\packages\nanoFramework.System.Net.1.7.0\lib\System.Net.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
<SpecificVersion>True</SpecificVersion>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -0,0 +1,740 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Amqp.Net", "test\Test.Amqp.Net\Test.Amqp.Net.csproj", "{06CAA70A-20A7-4334-AF03-D6228039C178}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{679989B2-8717-4ECC-9CAD-B104CFA91C38}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
src\amqp.snk = src\amqp.snk
|
||||
nuspec\AMQPNetLite.Core.nuspec = nuspec\AMQPNetLite.Core.nuspec
|
||||
nuspec\AMQPNetLite.NetMF.nuspec = nuspec\AMQPNetLite.NetMF.nuspec
|
||||
nuspec\AMQPNetLite.nuspec = nuspec\AMQPNetLite.nuspec
|
||||
nuspec\AMQPNetLite.Serialization.nuspec = nuspec\AMQPNetLite.Serialization.nuspec
|
||||
nuspec\AMQPNetLite.WebSockets.nuspec = nuspec\AMQPNetLite.WebSockets.nuspec
|
||||
nuspec\AMQPNetMicro.nuspec = nuspec\AMQPNetMicro.nuspec
|
||||
appveyor.yml = appveyor.yml
|
||||
build.cmd = build.cmd
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{8F701234-EC60-485C-BCDB-8EE233246832}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Interop", "Interop", "{612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Drain", "Examples\Interop\Interop.Drain\Interop.Drain.csproj", "{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Spout", "Examples\Interop\Interop.Spout\Interop.Spout.csproj", "{68470436-2F0D-4A76-B1E6-9C8517844C3E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Server", "Examples\Interop\Interop.Server\Interop.Server.csproj", "{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interop.Client", "Examples\Interop\Interop.Client\Interop.Client.csproj", "{C272B10E-36BE-4F36-A128-331F715514E6}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ServiceBus", "ServiceBus", "{4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceBus.Cbs", "Examples\ServiceBus\ServiceBus.Cbs\ServiceBus.Cbs.csproj", "{4681C268-36DB-4838-BD21-9EC9A8363269}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PeerToPeer", "PeerToPeer", "{7FF80B2D-4158-41D3-BC87-60C018028F53}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeerToPeer.Server", "Examples\PeerToPeer\PeerToPeer.Server\PeerToPeer.Server.csproj", "{24C152B0-3813-43C6-82DD-8BB601642F6C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeerToPeer.Client", "Examples\PeerToPeer\PeerToPeer.Client\PeerToPeer.Client.csproj", "{8FC90E46-024B-4089-9590-A7E8C2B092BE}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Device", "Device", "{BF554E12-7096-465F-B1D0-9ACFF00877F2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Device.Thermometer", "Examples\Device\Device.Thermometer\Device.Thermometer.csproj", "{43570F0D-DE6C-423E-A275-AC619A813B79}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceBus.EventHub", "Examples\ServiceBus\ServiceBus.EventHub\ServiceBus.EventHub.csproj", "{36F33391-4918-4C6D-9CAE-1ECD32262257}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PerfTest", "test\PerfTest\PerfTest.csproj", "{B23AC1B1-1551-41F3-8763-E68A53B172BB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Device.Controller2", "Examples\Device\Device.Controller2\Device.Controller2.csproj", "{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeerToPeer.Certificate", "Examples\PeerToPeer\PeerToPeer.Certificate\PeerToPeer.Certificate.csproj", "{E55CB1DD-2F8E-4052-A119-6F3FD9ED10BE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceBus.MessageSession", "Examples\ServiceBus\ServiceBus.MessageSession\ServiceBus.MessageSession.csproj", "{D1E69C74-4A33-4079-9665-8818A8479FFB}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Listener", "Listener", "{89F13102-4826-4406-844B-7B21C47885E7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Listener.ContainerHost", "Examples\Listener\Listener.ContainerHost\Listener.ContainerHost.csproj", "{E8D670D3-B1B4-45CA-9440-9630529599B2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Listener.IContainer", "Examples\Listener\Listener.IContainer\Listener.IContainer.csproj", "{4B7BFDB9-406A-4EBE-93C3-5D40D6A986F4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestAmqpBroker", "test\TestAmqpBroker\TestAmqpBroker.csproj", "{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeerToPeer.CustomType", "Examples\PeerToPeer\PeerToPeer.CustomType\PeerToPeer.CustomType.csproj", "{30536F8F-E4DA-46B3-B0D0-082632AD74B4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceBus.EventHub.NetMF", "Examples\ServiceBus\ServiceBus.EventHub.NetMF\ServiceBus.EventHub.NetMF.csproj", "{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeerToPeer.Receiver", "Examples\PeerToPeer\PeerToPeer.Receiver\PeerToPeer.Receiver.csproj", "{E5D42E35-B5C4-426D-B568-96926EBA588E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Amqp.NetCore", "test\Test.Amqp.NetCore\Test.Amqp.NetCore.csproj", "{6BCA313F-794F-4C54-9F96-C500290E147C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Device.SmallMemory", "Examples\Device\Device.SmallMemory\Device.SmallMemory.csproj", "{69E4A20C-EF50-49C6-8DAC-F76B9D565767}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docfx", "docfx", "{EB7EBF85-48AB-4EA0-9F00-825364BFA6FD}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
docs\docfx.json = docs\docfx.json
|
||||
docs\index.md = docs\index.md
|
||||
docs\toc.yml = docs\toc.yml
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "articles", "articles", "{5637969B-A822-425A-A831-F70AA2275777}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
docs\articles\azure_eventhubs.md = docs\articles\azure_eventhubs.md
|
||||
docs\articles\buffer_management.md = docs\articles\buffer_management.md
|
||||
docs\articles\building_application.md = docs\articles\building_application.md
|
||||
docs\articles\contributing.md = docs\articles\contributing.md
|
||||
docs\articles\device_to_iothub.md = docs\articles\device_to_iothub.md
|
||||
docs\articles\fault_tolerance.md = docs\articles\fault_tolerance.md
|
||||
docs\articles\hello_amqp.md = docs\articles\hello_amqp.md
|
||||
docs\articles\installation.md = docs\articles\installation.md
|
||||
docs\articles\listener.md = docs\articles\listener.md
|
||||
docs\articles\serialization.md = docs\articles\serialization.md
|
||||
docs\articles\service_to_iothub.md = docs\articles\service_to_iothub.md
|
||||
docs\articles\test_amqp_broker.md = docs\articles\test_amqp_broker.md
|
||||
docs\articles\toc.yml = docs\articles\toc.yml
|
||||
docs\articles\tracing.md = docs\articles\tracing.md
|
||||
docs\articles\versioning.md = docs\articles\versioning.md
|
||||
docs\articles\working_with_code.md = docs\articles\working_with_code.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceBus.Topic", "Examples\ServiceBus\ServiceBus.Topic\ServiceBus.Topic.csproj", "{D454DB5E-820F-4A92-B31E-A41A9D20B086}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Amqp.Net35", "test\Test.Amqp.Net35\Test.Amqp.Net35.csproj", "{7852029D-235C-40B7-8957-8E78414C3F97}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PeerToPeer.CustomTransport", "Examples\PeerToPeer\PeerToPeer.CustomTransport\PeerToPeer.CustomTransport.csproj", "{4573C570-520F-4F49-90B4-03D4532C2BA2}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{3A334EFA-47FA-4CE2-9306-FDFF7CF47157}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LongHaulTest", "test\LongHaulTest\LongHaulTest.csproj", "{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Amqp.Net40", "test\Test.Amqp.Net40\Test.Amqp.Net40.csproj", "{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceBus.WebSockets", "Examples\ServiceBus\ServiceBus.WebSockets\ServiceBus.WebSockets.csproj", "{F0A0D04C-6665-43C2-A3A3-870248A331B9}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Reconnect", "Reconnect", "{B61E3B51-78CB-4047-8078-0B987E5E9742}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReconnectSender", "Examples\Reconnect\ReconnectSender\ReconnectSender.csproj", "{EDD03052-3A73-4D9E-9B94-6844134BABFB}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Serialization", "Serialization", "{3C94DB48-3DDB-429C-8033-87F560607AA6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Serialization.Poco", "Examples\Serialization\Serialization.Poco\Serialization.Poco.csproj", "{629621F7-4D91-4F49-B373-FDFE6BB573D4}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "netmf", "netmf", "{E0C378B0-4AF7-4C1F-A068-81A23FF8894E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.Micro.NetMF", "netmf\Amqp.Micro.NetMF.csproj", "{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.NetMF42", "netmf\Amqp.NetMF42.csproj", "{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.NetMF43", "netmf\Amqp.NetMF43.csproj", "{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.NetMF44", "netmf\Amqp.NetMF44.csproj", "{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test.Amqp.NetMF", "netmf\Test.Amqp.NetMF.csproj", "{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.Net", "csproj\Amqp.Net.csproj", "{92153715-1D99-43B1-B291-470CF91A156D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.Net35", "csproj\Amqp.Net35.csproj", "{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.Net40", "csproj\Amqp.Net40.csproj", "{4A250B81-35E9-4D2F-8030-62909F6C8C63}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.NetCore", "csproj\Amqp.NetCore.csproj", "{35F64888-3446-444D-8E44-128378434AB3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amqp.Uwp", "csproj\Amqp.Uwp.csproj", "{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|ARM = Debug|ARM
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|ARM = Release|ARM
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{06CAA70A-20A7-4334-AF03-D6228039C178}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{06CAA70A-20A7-4334-AF03-D6228039C178}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{68470436-2F0D-4A76-B1E6-9C8517844C3E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C272B10E-36BE-4F36-A128-331F715514E6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C272B10E-36BE-4F36-A128-331F715514E6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{4681C268-36DB-4838-BD21-9EC9A8363269}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{4681C268-36DB-4838-BD21-9EC9A8363269}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{24C152B0-3813-43C6-82DD-8BB601642F6C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{8FC90E46-024B-4089-9590-A7E8C2B092BE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{43570F0D-DE6C-423E-A275-AC619A813B79}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{43570F0D-DE6C-423E-A275-AC619A813B79}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{36F33391-4918-4C6D-9CAE-1ECD32262257}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{36F33391-4918-4C6D-9CAE-1ECD32262257}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{36F33391-4918-4C6D-9CAE-1ECD32262257}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{36F33391-4918-4C6D-9CAE-1ECD32262257}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{36F33391-4918-4C6D-9CAE-1ECD32262257}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{36F33391-4918-4C6D-9CAE-1ECD32262257}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{36F33391-4918-4C6D-9CAE-1ECD32262257}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{36F33391-4918-4C6D-9CAE-1ECD32262257}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{36F33391-4918-4C6D-9CAE-1ECD32262257}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{36F33391-4918-4C6D-9CAE-1ECD32262257}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B23AC1B1-1551-41F3-8763-E68A53B172BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B23AC1B1-1551-41F3-8763-E68A53B172BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B23AC1B1-1551-41F3-8763-E68A53B172BB}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{B23AC1B1-1551-41F3-8763-E68A53B172BB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{B23AC1B1-1551-41F3-8763-E68A53B172BB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B23AC1B1-1551-41F3-8763-E68A53B172BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B23AC1B1-1551-41F3-8763-E68A53B172BB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B23AC1B1-1551-41F3-8763-E68A53B172BB}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{B23AC1B1-1551-41F3-8763-E68A53B172BB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{B23AC1B1-1551-41F3-8763-E68A53B172BB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Debug|x86.Build.0 = Debug|x86
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Release|ARM.Build.0 = Release|ARM
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Release|x86.ActiveCfg = Release|x86
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Release|x86.Build.0 = Release|x86
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C}.Release|x86.Deploy.0 = Release|x86
|
||||
{E55CB1DD-2F8E-4052-A119-6F3FD9ED10BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E55CB1DD-2F8E-4052-A119-6F3FD9ED10BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E55CB1DD-2F8E-4052-A119-6F3FD9ED10BE}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{E55CB1DD-2F8E-4052-A119-6F3FD9ED10BE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E55CB1DD-2F8E-4052-A119-6F3FD9ED10BE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E55CB1DD-2F8E-4052-A119-6F3FD9ED10BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E55CB1DD-2F8E-4052-A119-6F3FD9ED10BE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E55CB1DD-2F8E-4052-A119-6F3FD9ED10BE}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{E55CB1DD-2F8E-4052-A119-6F3FD9ED10BE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E55CB1DD-2F8E-4052-A119-6F3FD9ED10BE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D1E69C74-4A33-4079-9665-8818A8479FFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D1E69C74-4A33-4079-9665-8818A8479FFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D1E69C74-4A33-4079-9665-8818A8479FFB}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{D1E69C74-4A33-4079-9665-8818A8479FFB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D1E69C74-4A33-4079-9665-8818A8479FFB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D1E69C74-4A33-4079-9665-8818A8479FFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D1E69C74-4A33-4079-9665-8818A8479FFB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D1E69C74-4A33-4079-9665-8818A8479FFB}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{D1E69C74-4A33-4079-9665-8818A8479FFB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D1E69C74-4A33-4079-9665-8818A8479FFB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E8D670D3-B1B4-45CA-9440-9630529599B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E8D670D3-B1B4-45CA-9440-9630529599B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E8D670D3-B1B4-45CA-9440-9630529599B2}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{E8D670D3-B1B4-45CA-9440-9630529599B2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E8D670D3-B1B4-45CA-9440-9630529599B2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E8D670D3-B1B4-45CA-9440-9630529599B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E8D670D3-B1B4-45CA-9440-9630529599B2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E8D670D3-B1B4-45CA-9440-9630529599B2}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{E8D670D3-B1B4-45CA-9440-9630529599B2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E8D670D3-B1B4-45CA-9440-9630529599B2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4B7BFDB9-406A-4EBE-93C3-5D40D6A986F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4B7BFDB9-406A-4EBE-93C3-5D40D6A986F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4B7BFDB9-406A-4EBE-93C3-5D40D6A986F4}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{4B7BFDB9-406A-4EBE-93C3-5D40D6A986F4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{4B7BFDB9-406A-4EBE-93C3-5D40D6A986F4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4B7BFDB9-406A-4EBE-93C3-5D40D6A986F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4B7BFDB9-406A-4EBE-93C3-5D40D6A986F4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4B7BFDB9-406A-4EBE-93C3-5D40D6A986F4}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{4B7BFDB9-406A-4EBE-93C3-5D40D6A986F4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{4B7BFDB9-406A-4EBE-93C3-5D40D6A986F4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{30536F8F-E4DA-46B3-B0D0-082632AD74B4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{30536F8F-E4DA-46B3-B0D0-082632AD74B4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{30536F8F-E4DA-46B3-B0D0-082632AD74B4}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{30536F8F-E4DA-46B3-B0D0-082632AD74B4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{30536F8F-E4DA-46B3-B0D0-082632AD74B4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{30536F8F-E4DA-46B3-B0D0-082632AD74B4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{30536F8F-E4DA-46B3-B0D0-082632AD74B4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{30536F8F-E4DA-46B3-B0D0-082632AD74B4}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{30536F8F-E4DA-46B3-B0D0-082632AD74B4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{30536F8F-E4DA-46B3-B0D0-082632AD74B4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E5D42E35-B5C4-426D-B568-96926EBA588E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E5D42E35-B5C4-426D-B568-96926EBA588E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E5D42E35-B5C4-426D-B568-96926EBA588E}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{E5D42E35-B5C4-426D-B568-96926EBA588E}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E5D42E35-B5C4-426D-B568-96926EBA588E}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E5D42E35-B5C4-426D-B568-96926EBA588E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E5D42E35-B5C4-426D-B568-96926EBA588E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E5D42E35-B5C4-426D-B568-96926EBA588E}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{E5D42E35-B5C4-426D-B568-96926EBA588E}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E5D42E35-B5C4-426D-B568-96926EBA588E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Debug|x64.Build.0 = Debug|x64
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Debug|x64.Deploy.0 = Debug|x64
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Debug|x86.Build.0 = Debug|x86
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Debug|x86.Deploy.0 = Debug|x86
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Release|ARM.Build.0 = Release|ARM
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Release|x64.ActiveCfg = Release|x64
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Release|x64.Build.0 = Release|x64
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Release|x64.Deploy.0 = Release|x64
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Release|x86.ActiveCfg = Release|x86
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Release|x86.Build.0 = Release|x86
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C}.Release|x86.Deploy.0 = Release|x86
|
||||
{69E4A20C-EF50-49C6-8DAC-F76B9D565767}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{69E4A20C-EF50-49C6-8DAC-F76B9D565767}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{69E4A20C-EF50-49C6-8DAC-F76B9D565767}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{69E4A20C-EF50-49C6-8DAC-F76B9D565767}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{69E4A20C-EF50-49C6-8DAC-F76B9D565767}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{69E4A20C-EF50-49C6-8DAC-F76B9D565767}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{69E4A20C-EF50-49C6-8DAC-F76B9D565767}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{69E4A20C-EF50-49C6-8DAC-F76B9D565767}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{69E4A20C-EF50-49C6-8DAC-F76B9D565767}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{69E4A20C-EF50-49C6-8DAC-F76B9D565767}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{69E4A20C-EF50-49C6-8DAC-F76B9D565767}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{69E4A20C-EF50-49C6-8DAC-F76B9D565767}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D454DB5E-820F-4A92-B31E-A41A9D20B086}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D454DB5E-820F-4A92-B31E-A41A9D20B086}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D454DB5E-820F-4A92-B31E-A41A9D20B086}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{D454DB5E-820F-4A92-B31E-A41A9D20B086}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D454DB5E-820F-4A92-B31E-A41A9D20B086}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D454DB5E-820F-4A92-B31E-A41A9D20B086}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D454DB5E-820F-4A92-B31E-A41A9D20B086}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D454DB5E-820F-4A92-B31E-A41A9D20B086}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{D454DB5E-820F-4A92-B31E-A41A9D20B086}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D454DB5E-820F-4A92-B31E-A41A9D20B086}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7852029D-235C-40B7-8957-8E78414C3F97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7852029D-235C-40B7-8957-8E78414C3F97}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7852029D-235C-40B7-8957-8E78414C3F97}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{7852029D-235C-40B7-8957-8E78414C3F97}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7852029D-235C-40B7-8957-8E78414C3F97}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7852029D-235C-40B7-8957-8E78414C3F97}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7852029D-235C-40B7-8957-8E78414C3F97}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7852029D-235C-40B7-8957-8E78414C3F97}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{7852029D-235C-40B7-8957-8E78414C3F97}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7852029D-235C-40B7-8957-8E78414C3F97}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Release|x64.Build.0 = Release|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0}.Release|x86.Build.0 = Release|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9}.Release|x86.Build.0 = Release|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Release|x64.Build.0 = Release|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB}.Release|x86.Build.0 = Release|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Release|x64.Build.0 = Release|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8}.Release|x86.Build.0 = Release|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|x64.Build.0 = Release|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19}.Release|x86.Build.0 = Release|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Release|x64.Build.0 = Release|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC}.Release|x86.Build.0 = Release|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|ARM.Deploy.0 = Debug|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|x64.Deploy.0 = Debug|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Debug|x86.Deploy.0 = Debug|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|ARM.Deploy.0 = Release|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|x64.Build.0 = Release|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|x64.Deploy.0 = Release|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|x86.Build.0 = Release|Any CPU
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426}.Release|x86.Deploy.0 = Release|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{92153715-1D99-43B1-B291-470CF91A156D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|x64.Build.0 = Release|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4FB9C0D9-C3A8-4FB5-86CD-927E5EBC6885}.Release|x86.Build.0 = Release|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Release|x64.Build.0 = Release|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{4A250B81-35E9-4D2F-8030-62909F6C8C63}.Release|x86.Build.0 = Release|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Release|x64.Build.0 = Release|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{35F64888-3446-444D-8E44-128378434AB3}.Release|x86.Build.0 = Release|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Release|x64.Build.0 = Release|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{75DC3484-F6C8-4373-A8C4-9D1A8C9FC3B0}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{06CAA70A-20A7-4334-AF03-D6228039C178} = {3A334EFA-47FA-4CE2-9306-FDFF7CF47157}
|
||||
{612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05} = {8F701234-EC60-485C-BCDB-8EE233246832}
|
||||
{D6201667-DFEC-4BEF-8F4F-BE5EE5F07FE7} = {612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}
|
||||
{68470436-2F0D-4A76-B1E6-9C8517844C3E} = {612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}
|
||||
{09975981-F2D3-43AE-B70D-F4DEE7B0B0D2} = {612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}
|
||||
{C272B10E-36BE-4F36-A128-331F715514E6} = {612E8E0A-6CB6-45C9-9A05-CFC7F26A5C05}
|
||||
{4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56} = {8F701234-EC60-485C-BCDB-8EE233246832}
|
||||
{4681C268-36DB-4838-BD21-9EC9A8363269} = {4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56}
|
||||
{7FF80B2D-4158-41D3-BC87-60C018028F53} = {8F701234-EC60-485C-BCDB-8EE233246832}
|
||||
{24C152B0-3813-43C6-82DD-8BB601642F6C} = {7FF80B2D-4158-41D3-BC87-60C018028F53}
|
||||
{8FC90E46-024B-4089-9590-A7E8C2B092BE} = {7FF80B2D-4158-41D3-BC87-60C018028F53}
|
||||
{BF554E12-7096-465F-B1D0-9ACFF00877F2} = {8F701234-EC60-485C-BCDB-8EE233246832}
|
||||
{43570F0D-DE6C-423E-A275-AC619A813B79} = {BF554E12-7096-465F-B1D0-9ACFF00877F2}
|
||||
{36F33391-4918-4C6D-9CAE-1ECD32262257} = {4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56}
|
||||
{B23AC1B1-1551-41F3-8763-E68A53B172BB} = {3A334EFA-47FA-4CE2-9306-FDFF7CF47157}
|
||||
{D6E83FC7-0D39-48AB-8DFA-FE89011CDD3C} = {BF554E12-7096-465F-B1D0-9ACFF00877F2}
|
||||
{E55CB1DD-2F8E-4052-A119-6F3FD9ED10BE} = {7FF80B2D-4158-41D3-BC87-60C018028F53}
|
||||
{D1E69C74-4A33-4079-9665-8818A8479FFB} = {4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56}
|
||||
{89F13102-4826-4406-844B-7B21C47885E7} = {8F701234-EC60-485C-BCDB-8EE233246832}
|
||||
{E8D670D3-B1B4-45CA-9440-9630529599B2} = {89F13102-4826-4406-844B-7B21C47885E7}
|
||||
{4B7BFDB9-406A-4EBE-93C3-5D40D6A986F4} = {89F13102-4826-4406-844B-7B21C47885E7}
|
||||
{78A9C0DF-1999-4D97-AE22-50ADC44F9A7B} = {3A334EFA-47FA-4CE2-9306-FDFF7CF47157}
|
||||
{30536F8F-E4DA-46B3-B0D0-082632AD74B4} = {7FF80B2D-4158-41D3-BC87-60C018028F53}
|
||||
{F37DE470-865E-4F80-BC9C-FAC7BC11D3CF} = {4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56}
|
||||
{E5D42E35-B5C4-426D-B568-96926EBA588E} = {7FF80B2D-4158-41D3-BC87-60C018028F53}
|
||||
{6BCA313F-794F-4C54-9F96-C500290E147C} = {3A334EFA-47FA-4CE2-9306-FDFF7CF47157}
|
||||
{69E4A20C-EF50-49C6-8DAC-F76B9D565767} = {BF554E12-7096-465F-B1D0-9ACFF00877F2}
|
||||
{5637969B-A822-425A-A831-F70AA2275777} = {EB7EBF85-48AB-4EA0-9F00-825364BFA6FD}
|
||||
{D454DB5E-820F-4A92-B31E-A41A9D20B086} = {4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56}
|
||||
{7852029D-235C-40B7-8957-8E78414C3F97} = {3A334EFA-47FA-4CE2-9306-FDFF7CF47157}
|
||||
{4573C570-520F-4F49-90B4-03D4532C2BA2} = {7FF80B2D-4158-41D3-BC87-60C018028F53}
|
||||
{F052E9A9-15BD-4DB4-8539-8961B7BA7DC0} = {3A334EFA-47FA-4CE2-9306-FDFF7CF47157}
|
||||
{CD62609E-EA4E-48F4-B1FB-DF9BB98A132C} = {3A334EFA-47FA-4CE2-9306-FDFF7CF47157}
|
||||
{F0A0D04C-6665-43C2-A3A3-870248A331B9} = {4A93A5B6-B935-4F86-B3DE-95B0F6EBEA56}
|
||||
{B61E3B51-78CB-4047-8078-0B987E5E9742} = {8F701234-EC60-485C-BCDB-8EE233246832}
|
||||
{EDD03052-3A73-4D9E-9B94-6844134BABFB} = {B61E3B51-78CB-4047-8078-0B987E5E9742}
|
||||
{3C94DB48-3DDB-429C-8033-87F560607AA6} = {8F701234-EC60-485C-BCDB-8EE233246832}
|
||||
{629621F7-4D91-4F49-B373-FDFE6BB573D4} = {3C94DB48-3DDB-429C-8033-87F560607AA6}
|
||||
{C9111380-CFA2-4A3E-B0DF-87A1C1888F98} = {E0C378B0-4AF7-4C1F-A068-81A23FF8894E}
|
||||
{C80D0C64-C34A-4DF4-9E26-E1D2F4FFEFC8} = {E0C378B0-4AF7-4C1F-A068-81A23FF8894E}
|
||||
{5D8F78FC-0719-495F-9AD0-1EDD7EC9AA19} = {E0C378B0-4AF7-4C1F-A068-81A23FF8894E}
|
||||
{97A6D8B7-2F39-45AC-91D7-A59FABF38CEC} = {E0C378B0-4AF7-4C1F-A068-81A23FF8894E}
|
||||
{2C4CBC7A-16BD-4F27-86BA-3CF38BE0F426} = {3A334EFA-47FA-4CE2-9306-FDFF7CF47157}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
1192
amqp.sln
1192
amqp.sln
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
17
appveyor.yml
17
appveyor.yml
|
@ -4,11 +4,14 @@ branches:
|
|||
- master
|
||||
skip_tags: true
|
||||
|
||||
init:
|
||||
- git config --global core.autocrlf true
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||
FRAMEWORKS_TO_BUILD: REST_OF_FRAMEWORKS
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||
FRAMEWORKS_TO_BUILD: NANOFRAMEWORK
|
||||
|
||||
before_build:
|
||||
|
@ -73,9 +76,9 @@ before_build:
|
|||
$webClient.DownloadFile("http://vsixgallery.com/feed/author/nanoframework", $vsixFeedXml)
|
||||
[xml]$feedDetails = Get-Content $vsixFeedXml
|
||||
|
||||
# assuming this is building on VS2017 only
|
||||
$extensionUrl = $feedDetails.feed.entry[0].content.src
|
||||
$vsixPath = Join-Path $($env:USERPROFILE) "nanoFramework.Tools.VS2017.Extension.zip"
|
||||
# assuming this is building on VS2019 only
|
||||
$extensionUrl = $feedDetails.feed.entry[1].content.src
|
||||
$vsixPath = Join-Path $($env:USERPROFILE) "nanoFramework.Tools.VS2019.Extension.zip"
|
||||
|
||||
# download VS extension
|
||||
Write-Debug "Download VSIX file from $extensionUrl to $vsixPath"
|
||||
|
@ -89,7 +92,7 @@ before_build:
|
|||
|
||||
# copy build files to msbuild location
|
||||
Write-Debug "Copy build files to msbuild location"
|
||||
$msbuildPath = "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild"
|
||||
$msbuildPath = "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild"
|
||||
Copy-Item -Path "$($env:USERPROFILE)\nf-extension\`$MSBuild\nanoFramework" -Destination $msbuildPath -Recurse
|
||||
|
||||
'OK' | Write-Host -ForegroundColor Green
|
||||
|
@ -115,9 +118,9 @@ build_script:
|
|||
{
|
||||
Write-Output "Invoking build.cmd script ..."
|
||||
|
||||
& c:\projects\amqpnetlite\build.cmd | Write-Output
|
||||
& c:\projects\amqpnetlite\build.cmd --solution "amqp-vs2015.sln amqp-dotnet.sln amqp-netmf.sln" | Write-Output
|
||||
|
||||
& c:\projects\amqpnetlite\build.cmd release | Write-Output
|
||||
& c:\projects\amqpnetlite\build.cmd release --solution "amqp-vs2015.sln amqp-dotnet.sln amqp-netmf.sln" | Write-Output
|
||||
|
||||
}
|
||||
Else
|
||||
|
|
43
build.cmd
43
build.cmd
|
@ -6,7 +6,7 @@ ECHO.
|
|||
|
||||
SET return-code=0
|
||||
|
||||
SET build-sln=amqp.sln amqp-dotnet.sln amqp-netmf.sln
|
||||
SET build-sln=amqp.sln
|
||||
SET build-target=build
|
||||
SET build-config=Debug
|
||||
SET build-platform=Any CPU
|
||||
|
@ -54,7 +54,7 @@ GOTO :args-error
|
|||
|
||||
:args-solution
|
||||
SHIFT
|
||||
SET build-sln=%1
|
||||
SET build-sln=%~1
|
||||
GOTO args-loop
|
||||
:args-config
|
||||
SHIFT
|
||||
|
@ -166,7 +166,7 @@ IF "%MSTestPath%" == "" (
|
|||
|
||||
ECHO.
|
||||
ECHO Running NET tests...
|
||||
"%MSTestPath%" /testcontainer:.\bin\%build-config%\Test.Amqp.Net\Test.Amqp.Net.dll
|
||||
"%MSTestPath%" /testcontainer:.\bin\%build-config%\Test.Amqp.Net\Test.Amqp.Net.dll /nologo
|
||||
IF ERRORLEVEL 1 (
|
||||
SET return-code=1
|
||||
ECHO Test failed!
|
||||
|
@ -177,7 +177,7 @@ IF ERRORLEVEL 1 (
|
|||
|
||||
ECHO.
|
||||
ECHO Running NET40 tests...
|
||||
"%MSTestPath%" /testcontainer:.\bin\%build-config%\Test.Amqp.Net40\Test.Amqp.Net40.dll
|
||||
"%MSTestPath%" /testcontainer:.\bin\%build-config%\Test.Amqp.Net40\Test.Amqp.Net40.dll /nologo
|
||||
IF ERRORLEVEL 1 (
|
||||
SET return-code=1
|
||||
ECHO Test failed!
|
||||
|
@ -187,7 +187,7 @@ IF ERRORLEVEL 1 (
|
|||
|
||||
ECHO.
|
||||
ECHO Running NET35 tests...
|
||||
"%MSTestPath%" /testcontainer:.\bin\%build-config%\Test.Amqp.Net35\Test.Amqp.Net35.dll
|
||||
"%MSTestPath%" /testcontainer:.\bin\%build-config%\Test.Amqp.Net35\Test.Amqp.Net35.dll /nologo
|
||||
IF ERRORLEVEL 1 (
|
||||
SET return-code=1
|
||||
ECHO Test failed!
|
||||
|
@ -195,14 +195,16 @@ IF ERRORLEVEL 1 (
|
|||
GOTO :exit
|
||||
)
|
||||
|
||||
IF "%build-sln:amqp-dotnet.sln=%" == "%build-sln%" GOTO :done-test
|
||||
IF NOT "%build-sln:amqp.sln=%" == "%build-sln%" GOTO :run-dotnet-test
|
||||
IF NOT "%build-sln:amqp-dotnet.sln=%" == "%build-sln%" GOTO :run-dotnet-test
|
||||
GOTO :done-test
|
||||
|
||||
:run-dotnet-test
|
||||
ECHO Running DOTNET (.Net Core 2.0) tests...
|
||||
ECHO Running DOTNET (netcoreapp 2.1) tests...
|
||||
"%dotnetPath%" test -c %build-config% --no-build test\Test.Amqp\Test.Amqp.csproj -- no-broker
|
||||
IF ERRORLEVEL 1 (
|
||||
SET return-code=1
|
||||
ECHO .Net Core 2. 0 Test failed!
|
||||
ECHO dotnet Test failed!
|
||||
GOTO :exit
|
||||
)
|
||||
|
||||
|
@ -225,13 +227,25 @@ IF /I "%build-config%" NEQ "Release" (
|
|||
|
||||
IF NOT EXIST ".\Build\Packages" MKDIR ".\Build\Packages"
|
||||
ECHO Building NuGet package with version %build-version%
|
||||
IF NOT "%build-sln:amqp.sln=%" == "%build-sln%" (
|
||||
"%NuGetPath%" pack .\nuspec\AMQPNetLite.nuspec -Version %build-version% -BasePath .\ -OutputDirectory ".\Build\Packages"
|
||||
IF NOT "%build-sln:amqp.sln=%" == "%build-sln%" GOTO :package-main
|
||||
IF NOT "%build-sln:amqp-vs2015.sln=%" == "%build-sln%" GOTO :package-main
|
||||
IF NOT "%build-sln:amqp-dotnet.sln=%" == "%build-sln%" GOTO :package-dotnet
|
||||
GOTO :package-netmf
|
||||
:package-main
|
||||
"%NuGetPath%" pack .\nuspec\AMQPNetLite.nuspec -Version %build-version% -BasePath .\ -OutputDirectory ".\Build\Packages"
|
||||
IF ERRORLEVEL 1 (
|
||||
SET return-code=1
|
||||
GOTO :exit
|
||||
)
|
||||
:package-dotnet
|
||||
FOR %%G IN (AMQPNetLite.Core AMQPNetLite.Serialization AMQPNetLite.WebSockets) DO (
|
||||
"%NuGetPath%" pack .\nuspec\%%G.nuspec -Version %build-version% -BasePath .\ -OutputDirectory ".\Build\Packages" -Symbols -SymbolPackageFormat snupkg
|
||||
IF ERRORLEVEL 1 (
|
||||
SET return-code=1
|
||||
GOTO :exit
|
||||
)
|
||||
)
|
||||
:package-netmf
|
||||
IF NOT "%build-sln:amqp-netmf.sln=%" == "%build-sln%" (
|
||||
FOR %%G IN (AMQPNetLite.NetMF AMQPNetMicro) DO (
|
||||
"%NuGetPath%" pack .\nuspec\%%G.nuspec -Version %build-version% -BasePath .\ -OutputDirectory ".\Build\Packages"
|
||||
|
@ -241,15 +255,6 @@ IF NOT "%build-sln:amqp-netmf.sln=%" == "%build-sln%" (
|
|||
)
|
||||
)
|
||||
)
|
||||
IF NOT "%build-sln:amqp-dotnet.sln=%" == "%build-sln%" (
|
||||
FOR %%G IN (AMQPNetLite.Core AMQPNetLite.Serialization AMQPNetLite.WebSockets) DO (
|
||||
"%NuGetPath%" pack .\nuspec\%%G.nuspec -Version %build-version% -BasePath .\ -OutputDirectory ".\Build\Packages" -Symbols -SymbolPackageFormat snupkg
|
||||
IF ERRORLEVEL 1 (
|
||||
SET return-code=1
|
||||
GOTO :exit
|
||||
)
|
||||
)
|
||||
)
|
||||
IF NOT "%build-sln:amqp-nanoFramework.sln=%" == "%build-sln%" (
|
||||
FOR %%G IN (AMQPNetLite.nanoFramework AMQPNetMicro.nanoFramework) DO (
|
||||
"%NuGetPath%" pack .\nuspec\%%G.nuspec -Version %build-version% -BasePath .\ -OutputDirectory ".\Build\Packages"
|
||||
|
|
|
@ -125,6 +125,9 @@
|
|||
<Compile Include="..\src\Listener\ListenerLink.cs">
|
||||
<Link>Listener\ListenerLink.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\src\MessageDelivery.cs">
|
||||
<Link>MessageDelivery.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\src\Net\IConnectionFactory.cs" />
|
||||
<Compile Include="..\src\Net\TcpKeepAliveSettings.cs" />
|
||||
<Compile Include="..\src\Net\TransportProvider.cs" />
|
||||
|
|
|
@ -63,6 +63,9 @@
|
|||
<Link>Handler\IDelivery.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\src\IAmqpObject.cs" />
|
||||
<Compile Include="..\src\MessageDelivery.cs">
|
||||
<Link>MessageDelivery.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\src\Net35\TcpTransport.cs">
|
||||
<Link>Internal\TcpTransport.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -133,6 +133,9 @@
|
|||
<Compile Include="..\src\Listener\X509Identity.cs">
|
||||
<Link>Listener\X509Identity.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\src\MessageDelivery.cs">
|
||||
<Link>MessageDelivery.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\src\Net\IConnectionFactory.cs" />
|
||||
<Compile Include="..\src\Net\Map.Net.cs">
|
||||
<Link>Types\Map.Net.cs</Link>
|
||||
|
|
|
@ -186,6 +186,9 @@
|
|||
<Link>Internal\LinkedList.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\src\Message.cs" />
|
||||
<Compile Include="..\src\MessageDelivery.cs">
|
||||
<Link>MessageDelivery.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\src\Net\AmqpSettings.cs" />
|
||||
<Compile Include="..\src\Net\AsyncPump.cs">
|
||||
<Link>Internal\AsyncPump.cs</Link>
|
||||
|
|
|
@ -185,6 +185,9 @@
|
|||
<Link>Internal\LinkedList.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\src\Message.cs" />
|
||||
<Compile Include="..\src\MessageDelivery.cs">
|
||||
<Link>MessageDelivery.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\src\Net\AmqpSettings.cs" />
|
||||
<Compile Include="..\src\Net\AsyncPump.cs">
|
||||
<Link>Internal\AsyncPump.cs</Link>
|
||||
|
|
|
@ -74,6 +74,10 @@ undesired behavior, e.g. UI freeze if it is called from a UI thread. In these ca
|
|||
should use the `ConnectionFactory` class to perform asynchronous non-blocking creation of
|
||||
a connection.
|
||||
|
||||
On platforms where `ConnectionFactory` is supported, the default factory (`Connection.Factory`) is
|
||||
used for all connections created by the constructors. Therefore, any change made to the settings of
|
||||
the default factory is applied to connections created afterwards.
|
||||
|
||||
### ConnectionFactory
|
||||
|
||||
`ConnectionFactory` provides asynchronous connection creation, and it also gives more control
|
||||
|
@ -224,21 +228,12 @@ recovery by recreating the object, and sometimes maybe its container object.
|
|||
|
||||
## Threading
|
||||
|
||||
Send and receive methods on links are thread safe.
|
||||
Usually the library completes an async operation or invokes a callback when a network event
|
||||
occurs. These events are generated when a network package is received. So the execution happens
|
||||
on the I/O thread where the connection pump is running. Blocking the thread means no more incoming
|
||||
frames can be processed and it is very likely to cause deadlock, application hang or timeout errors.
|
||||
To avoid such issues, application should not mix sync and async APIs. DO not perform blocking calls
|
||||
from the async callback.
|
||||
Below are examples for potential issues.
|
||||
```
|
||||
SenderLink sender = new SenderLink(session, "sender", "q1");
|
||||
await sender.SendAsync(new Message("m1"));
|
||||
sender.Send(new Message("m2"));
|
||||
```
|
||||
The Send call will timeout because the returned acknowledgement cannot be processed when the I/O
|
||||
thread is blocked.
|
||||
Send and receive methods on links are thread safe.
|
||||
|
||||
The library does not create any threads for sending or receiving messages. Instead the async API relies on an asynchronous connection "pump",
|
||||
meaning a continous loop that asynchronously processes I/O. It is critical for proper operation that the application does not block this pump.
|
||||
|
||||
There are two ways in which an application can accidentally block the pump. The first is by performing a blocking operation in a callback:
|
||||
|
||||
```
|
||||
SenderLink sender = new SenderLink(session, "sender", "q1");
|
||||
|
@ -247,8 +242,37 @@ sender.Send(
|
|||
(m, o, s) => Thread.Sleep(120000),
|
||||
sender);
|
||||
```
|
||||
Thread.Sleep is a hypothetical example of having blocking calls in the MessageCallback.
|
||||
|
||||
|
||||
The second occurs when an async operation is completed and its continuation runs *synchronously*:
|
||||
|
||||
```
|
||||
SenderLink sender = new SenderLink(session, "sender", "q1");
|
||||
await sender.SendAsync( new Message("test"));
|
||||
|
||||
Thead.Sleep(120000);
|
||||
```
|
||||
|
||||
The above code will block the pump if the continuation of SendAsync happens to be run synchronously (which it frequently will be).
|
||||
The problem is the same as with the first example, the async pump does not get a chance to release the currently executing thread back to the
|
||||
thread pool and therefore has no chance to await further I/O. This means that no messages can be processed and will typically cause deadlock,
|
||||
application hang or timeout errors.
|
||||
|
||||
Specifically it is important to understand that blocking operations to be avoided include the sync API of this library:
|
||||
```
|
||||
SenderLink sender = new SenderLink(session, "sender", "q1");
|
||||
await sender.SendAsync(new Message("m1"));
|
||||
sender.Send(new Message("m2"));
|
||||
```
|
||||
Here, the Send call will timeout because the returned acknowledgement cannot be processed when the I/O
|
||||
processing is blocked.
|
||||
|
||||
The solution for callbacks is naturally to schedule blocking work asynchronously instead of blocking the calling thread. The solution for continuations
|
||||
depends on the application, which must either ensure that continuations of async operations never occur on threads that do blocking work, or the async operations can be wrapped by the application using a `TaskCompletionSource` with `TaskCreationOptions.RunContinuationsAsynchronously` specified.
|
||||
|
||||
For more details see the following issues:
|
||||
https://github.com/Azure/amqpnetlite/issues/237
|
||||
https://github.com/Azure/amqpnetlite/issues/490
|
||||
|
||||
## Advanced topics
|
||||
* [Listener](listener.md)
|
||||
* [Serialization](serialization.md)
|
||||
|
|
|
@ -5,10 +5,14 @@ ContainerHost is the easiest way to start an AMQP listener. Multiple endpoints c
|
|||
|
||||
The application is required to register at least one of the following processors to process AMQP events. Multiple message/request processors can be registered as long as their addresses are different. At most one link processor can be registered.
|
||||
|
||||
When the container host receives an attach performative from the remote peer,
|
||||
(1) if a message/request processor is found at the registered address, the host creates a link endpoint for that address and all received messages are routed to that processor.
|
||||
(2) otherwise, if a link processor is registered, the attach request is routed to the processor.
|
||||
(3) otherwise, the attach is rejected with "amqp:not-found" error.
|
||||
When the container host receives an attach performative from the remote peer,
|
||||
(1) if an address resolver is set, the host first calls the resolver to translate the address from the incoming attach request.
|
||||
The resolver allows the application to implement various logic for mapping a peer specified address to a listener address, which
|
||||
is used to register a processor. Common scenarios are message processor to route messages to different destinations and message
|
||||
source to serve messages from multiple nodes.
|
||||
(2) if a message/request processor is found at the registered address, the host creates a link endpoint for that address and all received messages are routed to that processor.
|
||||
(3) otherwise, if a link processor is registered, the attach request is routed to the processor.
|
||||
(4) otherwise, the attach is rejected with "amqp:not-found" error.
|
||||
|
||||
Protocol behavior can be configured through the Listeners properties of the container host.
|
||||
|
||||
|
|
|
@ -15,7 +15,9 @@ At least one Uri should be specified. Multiple are allowed (typically one for "a
|
|||
|
||||
If "amqps" Uri is present, the "cert" option must exist to specify a server certificate for the Tls listener.
|
||||
|
||||
If "queues" option is present, the broker is preconfigured with a list of queues. If it does not exist, the broker implicitly creates a queue upon an attach request and deletes it when the associated connection is closed. This allows running the tests easily without creating or draining the queue. Note that this is different from AMQP dynamic nodes. You can still create dynamic nodes through the protocol.
|
||||
If "queues" option is present, the broker is preconfigured with a list of queues. If it does not exist, the broker implicitly creates a queue upon the first attach request
|
||||
and deletes it when the last connection is closed. This allows running the tests easily without creating or draining the queue. Note that this is different from AMQP dynamic nodes.
|
||||
You can still create dynamic nodes through the protocol.
|
||||
|
||||
When "trace" option is specified, the traces will be printed to the console window.
|
||||
|
||||
|
|
|
@ -69,6 +69,9 @@
|
|||
<Compile Include="..\src\Framing\Data.cs">
|
||||
<Link>Framing\Data.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\src\MessageDelivery.cs">
|
||||
<Link>MessageDelivery.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="NETMF\TimeoutException.cs" />
|
||||
<Compile Include="NETMF\List.cs" />
|
||||
<Compile Include="NETMF\Map.cs" />
|
||||
|
|
|
@ -162,6 +162,9 @@
|
|||
<Compile Include="..\src\Link.cs" />
|
||||
<Compile Include="..\src\LinkedList.cs" />
|
||||
<Compile Include="..\src\Message.cs" />
|
||||
<Compile Include="..\src\MessageDelivery.cs">
|
||||
<Link>MessageDelivery.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="NetMF\Fx.cs" />
|
||||
<Compile Include="NetMF\List.cs" />
|
||||
<Compile Include="NetMF\Map.cs" />
|
||||
|
|
|
@ -162,6 +162,9 @@
|
|||
<Compile Include="..\src\Link.cs" />
|
||||
<Compile Include="..\src\LinkedList.cs" />
|
||||
<Compile Include="..\src\Message.cs" />
|
||||
<Compile Include="..\src\MessageDelivery.cs">
|
||||
<Link>MessageDelivery.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\src\Properties\AssemblyInfo.cs">
|
||||
<Link>Properties\AssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -44,7 +44,8 @@ namespace Amqp
|
|||
/// <summary>
|
||||
/// Initializes a new instance of the Address class from a string.
|
||||
/// </summary>
|
||||
/// <param name="address">The string representation of the address.</param>
|
||||
/// <param name="address">The string representation of the address. User and password in
|
||||
/// the string, if any, MUST be URL encoded.</param>
|
||||
public Address(string address)
|
||||
{
|
||||
this.Port = -1;
|
||||
|
@ -57,8 +58,8 @@ namespace Amqp
|
|||
/// </summary>
|
||||
/// <param name="host">The domain of the address.</param>
|
||||
/// <param name="port">The port number of the address.</param>
|
||||
/// <param name="user">User name for SASL PLAIN profile.</param>
|
||||
/// <param name="password">Password for SASL PLAIN profile.</param>
|
||||
/// <param name="user">User name for SASL PLAIN profile without URL encoding.</param>
|
||||
/// <param name="password">Password for SASL PLAIN profile without URL encoding.</param>
|
||||
/// <param name="path">The path of the address.</param>
|
||||
/// <param name="scheme">Protocol scheme, which can be either "amqp" or "amqps".</param>
|
||||
public Address(string host, int port, string user = null, string password = null, string path = "/", string scheme = Amqps)
|
||||
|
|
|
@ -107,11 +107,11 @@ namespace Amqp
|
|||
|
||||
internal const uint DefaultMaxFrameSize = 256 * 1024;
|
||||
internal const ushort DefaultMaxSessions = 256;
|
||||
internal const int DefaultMaxLinksPerSession = 64;
|
||||
internal const int DefaultMaxLinksPerSession = 1024;
|
||||
internal static int HeartBeatCloseTimeout = 20 * 1000;
|
||||
const uint MaxIdleTimeout = 30 * 60 * 1000;
|
||||
readonly Address address;
|
||||
readonly OnOpened onOpened;
|
||||
readonly object lockObject;
|
||||
IHandler handler;
|
||||
Session[] localSessions;
|
||||
Session[] remoteSessions;
|
||||
|
@ -120,9 +120,7 @@ namespace Amqp
|
|||
uint maxFrameSize;
|
||||
uint remoteMaxFrameSize;
|
||||
ITransport writer;
|
||||
Pump reader;
|
||||
HeartBeat heartBeat;
|
||||
private readonly object lockObject = new object();
|
||||
|
||||
Connection(Address address, ushort channelMax, uint maxFrameSize)
|
||||
{
|
||||
|
@ -132,6 +130,7 @@ namespace Amqp
|
|||
this.remoteMaxFrameSize = uint.MaxValue;
|
||||
this.localSessions = new Session[1];
|
||||
this.remoteSessions = new Session[1];
|
||||
this.lockObject = new object();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -142,7 +141,7 @@ namespace Amqp
|
|||
/// The connection initialization includes establishing the underlying transport,
|
||||
/// which typically has blocking network I/O. Depending on the current synchronization
|
||||
/// context, it may cause deadlock or UI freeze. Please use the ConnectionFactory.CreateAsync
|
||||
/// method instead.
|
||||
/// method instead if it is available for the platform.
|
||||
/// </remarks>
|
||||
public Connection(Address address)
|
||||
: this(address, null)
|
||||
|
@ -154,6 +153,12 @@ namespace Amqp
|
|||
/// </summary>
|
||||
/// <param name="address">The address.</param>
|
||||
/// <param name="handler">The protocol handler.</param>
|
||||
/// <remarks>
|
||||
/// The connection initialization includes establishing the underlying transport,
|
||||
/// which typically has blocking network I/O. Depending on the current synchronization
|
||||
/// context, it may cause deadlock or UI freeze. Please use the ConnectionFactory.CreateAsync
|
||||
/// method instead if it is available for the platform.
|
||||
/// </remarks>
|
||||
public Connection(Address address, IHandler handler)
|
||||
: this(address, DefaultMaxSessions, DefaultMaxFrameSize)
|
||||
{
|
||||
|
@ -174,7 +179,7 @@ namespace Amqp
|
|||
/// The connection initialization includes establishing the underlying transport,
|
||||
/// which typically has blocking network I/O. Depending on the current synchronization
|
||||
/// context, it may cause deadlock or UI freeze. Please use the ConnectionFactory.CreateAsync
|
||||
/// method instead.
|
||||
/// method instead if it is available for the platform.
|
||||
/// </remarks>
|
||||
public Connection(Address address, SaslProfile saslProfile, Open open, OnOpened onOpened)
|
||||
: this(address, DefaultMaxSessions, DefaultMaxFrameSize)
|
||||
|
@ -197,16 +202,33 @@ namespace Amqp
|
|||
}
|
||||
|
||||
#if NETFX || NETFX40 || DOTNET || NETFX_CORE || WINDOWS_STORE || WINDOWS_PHONE
|
||||
static ushort GetChannelMax(AmqpSettings amqpSettings, Open open)
|
||||
{
|
||||
return open != null ? open.ChannelMax : (ushort)(amqpSettings.MaxSessionsPerConnection - 1);
|
||||
}
|
||||
|
||||
static uint GetMaxFrameSize(AmqpSettings amqpSettings, Open open)
|
||||
{
|
||||
return open != null ? open.MaxFrameSize : (uint)amqpSettings.MaxFrameSize;
|
||||
}
|
||||
|
||||
internal Connection(IBufferManager bufferManager, AmqpSettings amqpSettings, Address address,
|
||||
IAsyncTransport transport, Open open, OnOpened onOpened, IHandler handler)
|
||||
: this(address, (ushort)(amqpSettings.MaxSessionsPerConnection - 1), (uint)amqpSettings.MaxFrameSize)
|
||||
: this(address, DefaultMaxSessions, DefaultMaxFrameSize)
|
||||
{
|
||||
this.onOpened = onOpened;
|
||||
this.handler = handler;
|
||||
this.Init(bufferManager, amqpSettings, transport, open);
|
||||
}
|
||||
|
||||
internal void Init(IBufferManager bufferManager, AmqpSettings amqpSettings, IAsyncTransport transport, Open open)
|
||||
{
|
||||
transport.SetConnection(this);
|
||||
|
||||
this.handler = handler;
|
||||
this.BufferManager = bufferManager;
|
||||
this.channelMax = GetChannelMax(amqpSettings, open);
|
||||
this.maxFrameSize = GetMaxFrameSize(amqpSettings, open);
|
||||
this.MaxLinksPerSession = amqpSettings.MaxLinksPerSession;
|
||||
this.onOpened = onOpened;
|
||||
this.writer = new TransportWriter(transport, this.OnIoException);
|
||||
|
||||
// after getting the transport, move state to open pipe before starting the pump
|
||||
|
@ -218,13 +240,13 @@ namespace Amqp
|
|||
HostName = amqpSettings.HostName ?? this.address.Host,
|
||||
ChannelMax = this.channelMax,
|
||||
MaxFrameSize = this.maxFrameSize,
|
||||
IdleTimeOut = (uint)amqpSettings.IdleTimeout
|
||||
IdleTimeOut = (uint)amqpSettings.IdleTimeout / 2
|
||||
};
|
||||
}
|
||||
|
||||
if (open.IdleTimeOut > 0)
|
||||
{
|
||||
this.heartBeat = new HeartBeat(this, open.IdleTimeOut);
|
||||
this.heartBeat = new HeartBeat(this, open.IdleTimeOut * 2);
|
||||
}
|
||||
|
||||
this.SendHeader();
|
||||
|
@ -232,12 +254,19 @@ namespace Amqp
|
|||
this.state = ConnectionState.OpenPipe;
|
||||
}
|
||||
|
||||
static ConnectionFactory connectionFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a factory with default settings.
|
||||
/// Gets a factory with default settings. Any changes to the settings are
|
||||
/// applied to the connections created from this factory instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// On platforms where <seealso cref="ConnectionFactory"/> is supported, this
|
||||
/// is also used for connections initialized by the constructors.
|
||||
/// </remarks>
|
||||
public static ConnectionFactory Factory
|
||||
{
|
||||
get { return new ConnectionFactory(); }
|
||||
get { return connectionFactory ?? (connectionFactory = new ConnectionFactory()); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -270,8 +299,14 @@ namespace Amqp
|
|||
{
|
||||
return new WrappedByteBuffer(buffer, offset, length);
|
||||
}
|
||||
|
||||
void Connect(SaslProfile saslProfile, Open open)
|
||||
{
|
||||
Factory.ConnectAsync(this.address, saslProfile, open, this).ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
}
|
||||
#else
|
||||
internal int MaxLinksPerSession = DefaultMaxLinksPerSession;
|
||||
Pump reader;
|
||||
|
||||
ByteBuffer AllocateBuffer(int size)
|
||||
{
|
||||
|
@ -282,8 +317,71 @@ namespace Amqp
|
|||
{
|
||||
return new ByteBuffer(buffer.Buffer, offset, length, length);
|
||||
}
|
||||
|
||||
void Connect(SaslProfile saslProfile, Open open)
|
||||
{
|
||||
if (open != null)
|
||||
{
|
||||
this.maxFrameSize = open.MaxFrameSize;
|
||||
this.channelMax = open.ChannelMax;
|
||||
}
|
||||
else
|
||||
{
|
||||
open = new Open()
|
||||
{
|
||||
ContainerId = MakeAmqpContainerId(),
|
||||
HostName = this.address.Host,
|
||||
MaxFrameSize = this.maxFrameSize,
|
||||
ChannelMax = this.channelMax
|
||||
};
|
||||
}
|
||||
|
||||
if (open.IdleTimeOut > 0)
|
||||
{
|
||||
this.heartBeat = new HeartBeat(this, open.IdleTimeOut * 2);
|
||||
}
|
||||
|
||||
ITransport transport;
|
||||
{
|
||||
TcpTransport tcpTransport = new TcpTransport();
|
||||
tcpTransport.Connect(this, this.address, DisableServerCertValidation);
|
||||
transport = tcpTransport;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (saslProfile != null)
|
||||
{
|
||||
transport = saslProfile.Open(this.address.Host, transport);
|
||||
}
|
||||
else if (this.address.User != null)
|
||||
{
|
||||
transport = new SaslPlainProfile(this.address.User, this.address.Password).Open(this.address.Host, transport);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
transport.Close();
|
||||
throw;
|
||||
}
|
||||
|
||||
this.writer = new Writer(transport);
|
||||
|
||||
// after getting the transport, move state to open pipe before starting the pump
|
||||
this.SendHeader();
|
||||
this.SendOpen(open);
|
||||
this.state = ConnectionState.OpenPipe;
|
||||
|
||||
this.reader = new Pump(this, transport);
|
||||
this.reader.Start();
|
||||
}
|
||||
#endif
|
||||
|
||||
internal static string MakeAmqpContainerId()
|
||||
{
|
||||
return "AMQPNetLite-" + Guid.NewGuid().ToString().Substring(0, 8);
|
||||
}
|
||||
|
||||
internal ushort AddSession(Session session)
|
||||
{
|
||||
this.ThrowIfClosed("AddSession");
|
||||
|
@ -413,73 +511,6 @@ namespace Amqp
|
|||
}
|
||||
}
|
||||
|
||||
void Connect(SaslProfile saslProfile, Open open)
|
||||
{
|
||||
if (open != null)
|
||||
{
|
||||
this.maxFrameSize = open.MaxFrameSize;
|
||||
this.channelMax = open.ChannelMax;
|
||||
}
|
||||
else
|
||||
{
|
||||
open = new Open()
|
||||
{
|
||||
ContainerId = Guid.NewGuid().ToString(),
|
||||
HostName = this.address.Host,
|
||||
MaxFrameSize = this.maxFrameSize,
|
||||
ChannelMax = this.channelMax
|
||||
};
|
||||
}
|
||||
|
||||
if (open.IdleTimeOut > 0)
|
||||
{
|
||||
this.heartBeat = new HeartBeat(this, open.IdleTimeOut);
|
||||
}
|
||||
|
||||
ITransport transport;
|
||||
#if NETFX
|
||||
if (WebSocketTransport.MatchScheme(address.Scheme))
|
||||
{
|
||||
WebSocketTransport wsTransport = new WebSocketTransport();
|
||||
wsTransport.ConnectAsync(address, null).ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
transport = wsTransport;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
TcpTransport tcpTransport = new TcpTransport();
|
||||
tcpTransport.Connect(this, this.address, DisableServerCertValidation);
|
||||
transport = tcpTransport;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (saslProfile != null)
|
||||
{
|
||||
transport = saslProfile.Open(this.address.Host, transport);
|
||||
}
|
||||
else if (this.address.User != null)
|
||||
{
|
||||
transport = new SaslPlainProfile(this.address.User, this.address.Password).Open(this.address.Host, transport);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
transport.Close();
|
||||
throw;
|
||||
}
|
||||
|
||||
this.writer = new Writer(transport);
|
||||
|
||||
// after getting the transport, move state to open pipe before starting the pump
|
||||
this.SendHeader();
|
||||
this.SendOpen(open);
|
||||
this.state = ConnectionState.OpenPipe;
|
||||
|
||||
this.reader = new Pump(this, transport);
|
||||
this.reader.Start();
|
||||
}
|
||||
|
||||
void ThrowIfClosed(string operation)
|
||||
{
|
||||
if (this.state >= ConnectionState.CloseSent)
|
||||
|
@ -768,7 +799,7 @@ namespace Amqp
|
|||
return shouldContinue;
|
||||
}
|
||||
|
||||
void OnException(Exception exception)
|
||||
internal void OnException(Exception exception)
|
||||
{
|
||||
Trace.WriteLine(TraceLevel.Error, "Exception occurred: {0}", exception.ToString());
|
||||
AmqpException amqpException = exception as AmqpException;
|
||||
|
@ -848,7 +879,7 @@ namespace Amqp
|
|||
|
||||
public void Start(uint remote)
|
||||
{
|
||||
this.remote = remote / 2;
|
||||
this.remote = remote;
|
||||
this.lastSend = DateTime.UtcNow;
|
||||
this.lastReceive = DateTime.UtcNow;
|
||||
this.SetTimer();
|
||||
|
@ -1032,6 +1063,11 @@ namespace Amqp
|
|||
ProtocolHeader header = Reader.ReadHeader(this.transport);
|
||||
this.connection.OnHeader(header);
|
||||
}
|
||||
catch (AmqpException amqpException)
|
||||
{
|
||||
this.connection.OnException(amqpException);
|
||||
return;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
this.connection.OnIoException(exception);
|
||||
|
@ -1046,6 +1082,10 @@ namespace Amqp
|
|||
ByteBuffer buffer = Reader.ReadFrameBuffer(this.transport, sizeBuffer, this.connection.maxFrameSize);
|
||||
this.connection.OnFrame(buffer);
|
||||
}
|
||||
catch (AmqpException amqpException)
|
||||
{
|
||||
this.connection.OnException(amqpException);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
this.connection.OnIoException(exception);
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace Amqp
|
|||
using Amqp.Types;
|
||||
using Amqp.Handler;
|
||||
|
||||
class Delivery : IDelivery, INode
|
||||
sealed class Delivery : IDelivery, INode
|
||||
{
|
||||
Message message;
|
||||
|
||||
|
@ -56,7 +56,16 @@ namespace Amqp
|
|||
public Message Message
|
||||
{
|
||||
get { return this.message; }
|
||||
set { this.message = value; value.Delivery = this; }
|
||||
set
|
||||
{
|
||||
if (value.Delivery != null)
|
||||
{
|
||||
value.Delivery.message = null;
|
||||
}
|
||||
|
||||
this.message = value;
|
||||
this.message.Delivery = this;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReleaseAll(Delivery delivery, Error error)
|
||||
|
@ -95,5 +104,11 @@ namespace Amqp
|
|||
this.State = state;
|
||||
this.Link.OnDeliveryStateChanged(this);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.Buffer.ReleaseReference();
|
||||
this.message = null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -45,7 +45,7 @@ namespace Amqp.Framing
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if handle field was defined (index=0).
|
||||
/// Indicates if handle field was defined.
|
||||
/// </summary>
|
||||
public bool HasHandle
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ namespace Amqp.Framing
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the next-incoming-id field (index=1).
|
||||
/// Gets or sets the next-incoming-id field (index=0).
|
||||
/// </summary>
|
||||
public uint NextIncomingId
|
||||
{
|
||||
|
|
|
@ -82,6 +82,7 @@ namespace Amqp.Framing
|
|||
/// <summary>
|
||||
/// Gets or sets the idle-time-out field (index=4).
|
||||
/// </summary>
|
||||
/// <remarks>To avoid spurious timeouts, the value SHOULD be half the actual timeout threshold.</remarks>
|
||||
public uint IdleTimeOut
|
||||
{
|
||||
get { return this.GetField(4, this.idleTimeOut, 0u); }
|
||||
|
|
|
@ -89,6 +89,28 @@ namespace Amqp.Handler
|
|||
/// Handler MUST call System.Net.Security.SslStream.AuthenticateAsClient(string) or one of its overloads.
|
||||
/// </summary>
|
||||
SslAuthenticate,
|
||||
#if NETFX || NETFX40 || DOTNET
|
||||
/// <summary>
|
||||
/// A System.Net.Sockets.Socket (<see cref="Event.Context"/>) is accepted.
|
||||
/// </summary>
|
||||
SocketAccept,
|
||||
/// <summary>
|
||||
/// A System.Net.Security.SslStream (<see cref="Event.Context"/>) is accepted.
|
||||
/// </summary>
|
||||
SslStreamAccept,
|
||||
/// <summary>
|
||||
/// A System.Net.HttpListenerContext (<see cref="Event.Context"/>) is accepted in the WebSockets listener.
|
||||
/// </summary>
|
||||
HttpAccept,
|
||||
/// <summary>
|
||||
/// A System.Net.WebSockets.WebSocketContext (<see cref="Event.Context"/>) is accepted.
|
||||
/// </summary>
|
||||
WebSocketAccept,
|
||||
/// <summary>
|
||||
/// A <see cref="Amqp.Listener.ListenerConnection"/> is accepted.
|
||||
/// </summary>
|
||||
ConnectionAccept,
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -133,6 +133,8 @@ namespace Amqp.Listener
|
|||
/// <summary>
|
||||
/// Gets or sets a factory that creates a <see cref="IHandler"/> for an accepted connection.
|
||||
/// </summary>
|
||||
/// <remarks>The delegate is called once for each accepted transport. It allows for creating
|
||||
/// a handler per connection if needed (<see cref="Amqp.Connection.Handler"/>).</remarks>
|
||||
public Func<ConnectionListener, IHandler> HandlerFactory
|
||||
{
|
||||
get;
|
||||
|
@ -237,17 +239,16 @@ namespace Amqp.Listener
|
|||
throw new ArgumentNullException("certificate");
|
||||
}
|
||||
|
||||
async Task HandleTransportAsync(IAsyncTransport transport)
|
||||
async Task HandleTransportAsync(IAsyncTransport transport, IHandler handler, object context)
|
||||
{
|
||||
IPrincipal principal = null;
|
||||
if (this.saslSettings != null)
|
||||
{
|
||||
ListenerSaslProfile profile = new ListenerSaslProfile(this);
|
||||
transport = await profile.NegotiateAsync(transport);
|
||||
transport = await profile.NegotiateAsync(transport).ConfigureAwait(false);
|
||||
principal = profile.GetPrincipal();
|
||||
}
|
||||
|
||||
IHandler handler = this.HandlerFactory?.Invoke(this);
|
||||
var connection = new ListenerConnection(this, this.address, handler, transport);
|
||||
if (principal == null)
|
||||
{
|
||||
|
@ -277,10 +278,15 @@ namespace Amqp.Listener
|
|||
|
||||
if (shouldClose)
|
||||
{
|
||||
await connection.CloseAsync();
|
||||
await connection.CloseAsync().ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (handler != null && handler.CanHandle(EventId.ConnectionAccept))
|
||||
{
|
||||
handler.Handle(Event.Create(EventId.ConnectionAccept, connection, context: context));
|
||||
}
|
||||
|
||||
AsyncPump pump = new AsyncPump(this.BufferManager, transport);
|
||||
pump.Start(connection);
|
||||
}
|
||||
|
@ -494,6 +500,11 @@ namespace Amqp.Listener
|
|||
|
||||
protected override ITransport UpgradeTransport(ITransport transport)
|
||||
{
|
||||
if (this.innerProfile != null)
|
||||
{
|
||||
return this.innerProfile.UpgradeTransportInternal(transport);
|
||||
}
|
||||
|
||||
return transport;
|
||||
}
|
||||
|
||||
|
@ -545,7 +556,7 @@ namespace Amqp.Listener
|
|||
|
||||
class TcpTransportListener : TransportListener
|
||||
{
|
||||
Socket[] listenSockets;
|
||||
readonly Socket[] listenSockets;
|
||||
|
||||
public TcpTransportListener(ConnectionListener listener, string host, int port)
|
||||
{
|
||||
|
@ -618,9 +629,15 @@ namespace Amqp.Listener
|
|||
this.Listener.tcpSettings.Configure(socket);
|
||||
}
|
||||
|
||||
IAsyncTransport transport = await this.CreateTransportAsync(socket);
|
||||
IHandler handler = this.Listener.HandlerFactory?.Invoke(this.Listener);
|
||||
if (handler != null && handler.CanHandle(EventId.SocketAccept))
|
||||
{
|
||||
handler.Handle(Event.Create(EventId.SocketAccept, null, context: socket));
|
||||
}
|
||||
|
||||
await this.Listener.HandleTransportAsync(transport);
|
||||
IAsyncTransport transport = await this.CreateTransportAsync(socket, handler).ConfigureAwait(false);
|
||||
|
||||
await this.Listener.HandleTransportAsync(transport, handler, socket).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
|
@ -629,7 +646,7 @@ namespace Amqp.Listener
|
|||
}
|
||||
}
|
||||
|
||||
protected virtual Task<IAsyncTransport> CreateTransportAsync(Socket socket)
|
||||
protected virtual Task<IAsyncTransport> CreateTransportAsync(Socket socket, IHandler handler)
|
||||
{
|
||||
var tcs = new TaskCompletionSource<IAsyncTransport>();
|
||||
tcs.SetResult(new ListenerTcpTransport(socket, this.Listener.BufferManager));
|
||||
|
@ -646,7 +663,7 @@ namespace Amqp.Listener
|
|||
try
|
||||
{
|
||||
args.AcceptSocket = null;
|
||||
Socket acceptSocket = await socket.AcceptAsync(args, SocketFlags.None);
|
||||
Socket acceptSocket = await socket.AcceptAsync(args, SocketFlags.None).ConfigureAwait(false);
|
||||
if (acceptSocket != null)
|
||||
{
|
||||
var task = this.HandleSocketAsync(acceptSocket);
|
||||
|
@ -677,13 +694,13 @@ namespace Amqp.Listener
|
|||
this.certificate = certificate;
|
||||
}
|
||||
|
||||
protected override async Task<IAsyncTransport> CreateTransportAsync(Socket socket)
|
||||
protected override async Task<IAsyncTransport> CreateTransportAsync(Socket socket, IHandler handler)
|
||||
{
|
||||
SslStream sslStream;
|
||||
if (this.Listener.sslSettings == null)
|
||||
{
|
||||
sslStream = new SslStream(new NetworkStream(socket));
|
||||
await sslStream.AuthenticateAsServerAsync(this.certificate);
|
||||
await sslStream.AuthenticateAsServerAsync(this.certificate).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -691,7 +708,12 @@ namespace Amqp.Listener
|
|||
this.Listener.sslSettings.RemoteCertificateValidationCallback);
|
||||
|
||||
await sslStream.AuthenticateAsServerAsync(this.certificate, this.Listener.sslSettings.ClientCertificateRequired,
|
||||
this.Listener.sslSettings.Protocols, this.Listener.sslSettings.CheckCertificateRevocation);
|
||||
this.Listener.sslSettings.Protocols, this.Listener.sslSettings.CheckCertificateRevocation).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (handler != null && handler.CanHandle(EventId.SslStreamAccept))
|
||||
{
|
||||
handler.Handle(Event.Create(EventId.SslStreamAccept, null, context: sslStream));
|
||||
}
|
||||
|
||||
return new ListenerTcpTransport(sslStream, this.Listener.BufferManager);
|
||||
|
@ -725,7 +747,8 @@ namespace Amqp.Listener
|
|||
try
|
||||
{
|
||||
var transport = await this.provider.CreateAsync(this.Listener.address);
|
||||
await this.Listener.HandleTransportAsync(transport);
|
||||
IHandler handler = this.Listener.HandlerFactory?.Invoke(this.Listener);
|
||||
await this.Listener.HandleTransportAsync(transport, handler, null).ConfigureAwait(false);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
|
@ -769,12 +792,11 @@ namespace Amqp.Listener
|
|||
#if NETFX
|
||||
class WebSocketTransportListener : TransportListener
|
||||
{
|
||||
readonly ConnectionListener listener;
|
||||
HttpListener httpListener;
|
||||
|
||||
public WebSocketTransportListener(ConnectionListener listener, string scheme, string host, int port, string path)
|
||||
{
|
||||
this.listener = listener;
|
||||
this.Listener = listener;
|
||||
|
||||
// if certificate is set, it must be bound to host:port by netsh http command
|
||||
string address = string.Format("{0}://{1}:{2}{3}", scheme, host, port, path);
|
||||
|
@ -795,11 +817,11 @@ namespace Amqp.Listener
|
|||
this.httpListener.Close();
|
||||
}
|
||||
|
||||
async Task HandleListenerContextAsync(HttpListenerContext context)
|
||||
async Task HandleListenerContextAsync(HttpListenerContext context, IHandler handler)
|
||||
{
|
||||
try
|
||||
{
|
||||
int status = await this.CreateTransportAsync(context);
|
||||
int status = await this.CreateTransportAsync(context, handler).ConfigureAwait(false);
|
||||
if (status != 0)
|
||||
{
|
||||
Trace.WriteLine(TraceLevel.Error, "Failed to create ws transport ", status);
|
||||
|
@ -816,23 +838,23 @@ namespace Amqp.Listener
|
|||
}
|
||||
}
|
||||
|
||||
async Task<int> CreateTransportAsync(HttpListenerContext context)
|
||||
async Task<int> CreateTransportAsync(HttpListenerContext context, IHandler handler)
|
||||
{
|
||||
X509Certificate2 clientCertificate = null;
|
||||
|
||||
if (this.listener.sslSettings != null && this.listener.sslSettings.ClientCertificateRequired)
|
||||
if (this.Listener.sslSettings != null && this.Listener.sslSettings.ClientCertificateRequired)
|
||||
{
|
||||
clientCertificate = await context.Request.GetClientCertificateAsync(); ;
|
||||
clientCertificate = await context.Request.GetClientCertificateAsync().ConfigureAwait(false);
|
||||
if (clientCertificate == null)
|
||||
{
|
||||
return 40300;
|
||||
}
|
||||
|
||||
if (this.listener.sslSettings.RemoteCertificateValidationCallback != null)
|
||||
if (this.Listener.sslSettings.RemoteCertificateValidationCallback != null)
|
||||
{
|
||||
SslPolicyErrors sslError = SslPolicyErrors.None;
|
||||
X509Chain chain = new X509Chain();
|
||||
chain.ChainPolicy.RevocationMode = this.listener.sslSettings.CheckCertificateRevocation ?
|
||||
chain.ChainPolicy.RevocationMode = this.Listener.sslSettings.CheckCertificateRevocation ?
|
||||
X509RevocationMode.Online : X509RevocationMode.NoCheck;
|
||||
chain.Build(clientCertificate);
|
||||
if (chain.ChainStatus.Length > 0)
|
||||
|
@ -840,7 +862,7 @@ namespace Amqp.Listener
|
|||
sslError = SslPolicyErrors.RemoteCertificateChainErrors;
|
||||
}
|
||||
|
||||
bool success = this.listener.sslSettings.RemoteCertificateValidationCallback(
|
||||
bool success = this.Listener.sslSettings.RemoteCertificateValidationCallback(
|
||||
this, clientCertificate, chain, sslError);
|
||||
if (!success)
|
||||
{
|
||||
|
@ -877,9 +899,14 @@ namespace Amqp.Listener
|
|||
return 40003;
|
||||
}
|
||||
|
||||
var wsContext = await context.AcceptWebSocketAsync(subProtocol);
|
||||
var wsContext = await context.AcceptWebSocketAsync(subProtocol).ConfigureAwait(false);
|
||||
if (handler != null && handler.CanHandle(EventId.WebSocketAccept))
|
||||
{
|
||||
handler.Handle(Event.Create(EventId.WebSocketAccept, null, context: wsContext));
|
||||
}
|
||||
|
||||
var wsTransport = new ListenerWebSocketTransport(wsContext.WebSocket, principal);
|
||||
await this.listener.HandleTransportAsync(wsTransport);
|
||||
await this.Listener.HandleTransportAsync(wsTransport, handler, wsContext.WebSocket).ConfigureAwait(false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -890,9 +917,15 @@ namespace Amqp.Listener
|
|||
{
|
||||
try
|
||||
{
|
||||
HttpListenerContext context = await this.httpListener.GetContextAsync();
|
||||
HttpListenerContext context = await this.httpListener.GetContextAsync().ConfigureAwait(false);
|
||||
|
||||
var task = this.HandleListenerContextAsync(context);
|
||||
IHandler handler = this.Listener.HandlerFactory?.Invoke(this.Listener);
|
||||
if (handler != null && handler.CanHandle(EventId.HttpAccept))
|
||||
{
|
||||
handler.Handle(Event.Create(EventId.HttpAccept, null, context: context));
|
||||
}
|
||||
|
||||
var task = this.HandleListenerContextAsync(context, handler);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
|
|
|
@ -62,7 +62,9 @@ namespace Amqp.Listener
|
|||
/// * After the link attach is handled, wrap it in a Target/SourceLinkEndpoint
|
||||
/// that works with the previously implemented message processor or source.
|
||||
///
|
||||
/// Upon receiving an attach performative, the registered message level
|
||||
/// Upon receiving an attach performative, the host uses the address to look up
|
||||
/// the registered processors. If an address resolver is set, it is called first
|
||||
/// and the result overwrites the address in attach. The registered message level
|
||||
/// processors (IMessageProcessor, IMessageSource, IRequestProcessor) are
|
||||
/// checked first. If a processor matches the address on the received attach
|
||||
/// performative, a link is automatically created and the send/receive requests
|
||||
|
@ -139,7 +141,7 @@ namespace Amqp.Listener
|
|||
/// </summary>
|
||||
public ContainerHost(IList<Address> addressList)
|
||||
{
|
||||
this.containerId = string.Join("-", this.GetType().Name, Guid.NewGuid().ToString("N"));
|
||||
this.containerId = Connection.MakeAmqpContainerId();
|
||||
this.customTransports = new Dictionary<string, TransportProvider>(StringComparer.OrdinalIgnoreCase);
|
||||
this.linkCollection = new LinkCollection(this.containerId);
|
||||
this.onLinkClosed = this.OnLinkClosed;
|
||||
|
@ -183,6 +185,21 @@ namespace Amqp.Listener
|
|||
get { return this.listeners; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an address resolver for all processors.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The resolver returns a non-null string which was registered earlier for a
|
||||
/// processor that can handle the incoming attach request. If a null string is
|
||||
/// returned, the host continues to search for registered processors that matches
|
||||
/// the address exactly in the attach.
|
||||
/// </remarks>
|
||||
public Func<ContainerHost, Attach, string> AddressResolver
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens the container host object.
|
||||
/// </summary>
|
||||
|
@ -323,9 +340,12 @@ namespace Amqp.Listener
|
|||
|
||||
static void ThrowIfExists<T>(string address, Dictionary<string, T> processors)
|
||||
{
|
||||
if (processors.ContainsKey(address))
|
||||
lock (processors)
|
||||
{
|
||||
throw new AmqpException(ErrorCode.NotAllowed, typeof(T).Name + " processor has been registered at address " + address);
|
||||
if (processors.ContainsKey(address))
|
||||
{
|
||||
throw new AmqpException(ErrorCode.NotAllowed, typeof(T).Name + " processor has been registered at address " + address);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,36 +412,44 @@ namespace Amqp.Listener
|
|||
throw new AmqpException(ErrorCode.Stolen, string.Format("Link '{0}' has been attached already.", attach.LinkName));
|
||||
}
|
||||
|
||||
string address = attach.Role ? ((Source)attach.Source).Address : ((Target)attach.Target).Address;
|
||||
if (string.IsNullOrWhiteSpace(address))
|
||||
string address = null;
|
||||
if (this.AddressResolver != null)
|
||||
{
|
||||
throw new AmqpException(ErrorCode.InvalidField, "The address field cannot be empty");
|
||||
address = this.AddressResolver(this, attach);
|
||||
}
|
||||
|
||||
if (listenerLink.Role)
|
||||
if (address == null)
|
||||
{
|
||||
MessageProcessor messageProcessor;
|
||||
if (TryGetProcessor(this.messageProcessors, address, out messageProcessor))
|
||||
{
|
||||
messageProcessor.AddLink(listenerLink, address);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageSource messageSource;
|
||||
if (TryGetProcessor(this.messageSources, address, out messageSource))
|
||||
{
|
||||
messageSource.AddLink(listenerLink, address);
|
||||
return true;
|
||||
}
|
||||
address = attach.Role ? ((Source)attach.Source).Address : ((Target)attach.Target).Address;
|
||||
}
|
||||
|
||||
RequestProcessor requestProcessor;
|
||||
if (TryGetProcessor(this.requestProcessors, address, out requestProcessor))
|
||||
if (address != null)
|
||||
{
|
||||
requestProcessor.AddLink(listenerLink, address, attach);
|
||||
return true;
|
||||
if (listenerLink.Role)
|
||||
{
|
||||
MessageProcessor messageProcessor;
|
||||
if (TryGetProcessor(this.messageProcessors, address, out messageProcessor))
|
||||
{
|
||||
messageProcessor.AddLink(listenerLink, address);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageSource messageSource;
|
||||
if (TryGetProcessor(this.messageSources, address, out messageSource))
|
||||
{
|
||||
messageSource.AddLink(listenerLink, address);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
RequestProcessor requestProcessor;
|
||||
if (TryGetProcessor(this.requestProcessors, address, out requestProcessor))
|
||||
{
|
||||
requestProcessor.AddLink(listenerLink, address, attach);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.linkProcessor != null)
|
||||
|
@ -430,6 +458,11 @@ namespace Amqp.Listener
|
|||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(address))
|
||||
{
|
||||
throw new AmqpException(ErrorCode.InvalidField, "The address field cannot be empty.");
|
||||
}
|
||||
|
||||
throw new AmqpException(ErrorCode.NotFound, "No processor was found at " + address);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,9 @@ namespace Amqp.Listener
|
|||
/// </summary>
|
||||
/// <param name="flowContext">Context of the received flow performative.</param>
|
||||
/// <remarks>
|
||||
/// A sending endpoint should send messages per the requested message count.
|
||||
/// A sending endpoint should send messages per the requested message count. If not enough
|
||||
/// messages are available, it should also check <see cref="ListenerLink.IsDraining"/> and
|
||||
/// call <see cref="ListenerLink.CompleteDrain"/>.
|
||||
/// A receiving endpoint may receive a flow if the sender wants to exchange flow
|
||||
/// state or send custom properties.
|
||||
/// </remarks>
|
||||
|
|
|
@ -17,11 +17,10 @@
|
|||
|
||||
namespace Amqp.Listener
|
||||
{
|
||||
using System;
|
||||
using System.Security.Principal;
|
||||
using System.Threading;
|
||||
using Amqp.Framing;
|
||||
using Amqp.Handler;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Principal;
|
||||
|
||||
/// <summary>
|
||||
/// An AMQP connection used by the listener.
|
||||
|
@ -30,6 +29,7 @@ namespace Amqp.Listener
|
|||
{
|
||||
readonly static OnOpened onOpened = OnOpen;
|
||||
readonly ConnectionListener listener;
|
||||
Dictionary<string, object> properties;
|
||||
|
||||
internal ListenerConnection(ConnectionListener listener, Address address, IHandler handler, IAsyncTransport transport)
|
||||
: base(listener.BufferManager, listener.AMQP, address, transport, null, onOpened, handler)
|
||||
|
@ -47,6 +47,14 @@ namespace Amqp.Listener
|
|||
internal set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Custom properties attached to the connection. This is not thread safe.
|
||||
/// </summary>
|
||||
public IDictionary<string, object> Properties
|
||||
{
|
||||
get { return this.properties ?? (this.properties = new Dictionary<string, object>()); }
|
||||
}
|
||||
|
||||
internal ConnectionListener Listener
|
||||
{
|
||||
get { return this.listener; }
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace Amqp.Listener
|
|||
object state;
|
||||
SequenceNumber deliveryCount;
|
||||
uint credit;
|
||||
bool drain;
|
||||
|
||||
// caller can initialize the link for an endpoint, a sender or a receiver
|
||||
// based on its needs.
|
||||
|
@ -85,6 +86,14 @@ namespace Amqp.Listener
|
|||
get { return this.state; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the link is in drain mode (applicable when the link is in sender role).
|
||||
/// </summary>
|
||||
public bool IsDraining
|
||||
{
|
||||
get { return this.drain; }
|
||||
}
|
||||
|
||||
internal uint Credit
|
||||
{
|
||||
get { return this.credit; }
|
||||
|
@ -112,6 +121,10 @@ namespace Amqp.Listener
|
|||
/// <param name="onCredit">The callback to be invoked when delivery limit changes (by received flow performatives).</param>
|
||||
/// <param name="onDispose">The callback to be invoked when disposition is received.</param>
|
||||
/// <param name="state">The user state attached to the link.</param>
|
||||
/// <remarks>
|
||||
/// In the <see cref="onCredit"/> callback, if the application does not have enough messages to satisfy the credits, it should check the
|
||||
/// <see cref="IsDraining"/> property. If the value is true, it should discard remaining credits and call <see cref="CompleteDrain"/>.
|
||||
/// </remarks>
|
||||
public void InitializeSender(Action<int, Fields, object> onCredit, Action<Message, DeliveryState, bool, object> onDispose, object state)
|
||||
{
|
||||
ThrowIfNotNull(this.linkEndpoint, "endpoint");
|
||||
|
@ -241,6 +254,27 @@ namespace Amqp.Listener
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Completes the drain mode. The library will comsume all availble link credits and send a flow to the remote peer.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The application should reset any credits that it may keep before calling this function. After this, the application
|
||||
/// should not send any messages, when they are available, until it receives another onCredit callback with credits.
|
||||
/// </remarks>
|
||||
public void CompleteDrain()
|
||||
{
|
||||
lock (this.ThisLock)
|
||||
{
|
||||
if (this.drain)
|
||||
{
|
||||
this.deliveryCount += (int)this.credit;
|
||||
this.credit = 0;
|
||||
this.drain = false;
|
||||
this.SendFlow(this.deliveryCount, this.credit, this.drain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void SafeAddClosed(ClosedCallback callback)
|
||||
{
|
||||
this.Closed += callback;
|
||||
|
@ -359,6 +393,7 @@ namespace Amqp.Listener
|
|||
{
|
||||
if (!this.role)
|
||||
{
|
||||
this.drain = flow.Drain;
|
||||
var theirLimit = (SequenceNumber)(flow.DeliveryCount + flow.LinkCredit);
|
||||
var myLimit = this.deliveryCount + (SequenceNumber)this.credit;
|
||||
delta = theirLimit - myLimit;
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace Amqp.Listener
|
|||
{
|
||||
while (!this.link.IsDetaching)
|
||||
{
|
||||
ReceiveContext receiveContext = await this.messageSource.GetMessageAsync(this.link);
|
||||
ReceiveContext receiveContext = await this.messageSource.GetMessageAsync(this.link).ConfigureAwait(false);
|
||||
if (receiveContext != null)
|
||||
{
|
||||
try
|
||||
|
@ -104,6 +104,16 @@ namespace Amqp.Listener
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (this.link.IsDraining)
|
||||
{
|
||||
lock (this.syncRoot)
|
||||
{
|
||||
this.receiving = false;
|
||||
}
|
||||
|
||||
this.link.CompleteDrain();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -193,18 +193,26 @@ namespace Amqp
|
|||
return message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the information of the message delivery. It can be used to acknowledge the message
|
||||
/// later even if the message has been disposed or discarded.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="MessageDelivery"/> object, or null if delivery has not happened yet.</returns>
|
||||
public MessageDelivery GetDelivery()
|
||||
{
|
||||
return this.Delivery == null ? MessageDelivery.None : new MessageDelivery(this.Delivery);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the current message to release resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
#if NETFX || NETFX40 || DOTNET
|
||||
if (this.Delivery != null &&
|
||||
this.Delivery.Buffer != null)
|
||||
if (this.Delivery != null)
|
||||
{
|
||||
this.Delivery.Buffer.ReleaseReference();
|
||||
this.Delivery.Dispose();
|
||||
this.Delivery = null;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
internal ByteBuffer Encode(int reservedBytes)
|
||||
|
@ -280,7 +288,10 @@ namespace Amqp
|
|||
return 64;
|
||||
}
|
||||
|
||||
int GetEstimatedMessageSize()
|
||||
/// <summary>
|
||||
/// Gets estimated message size in bytes.
|
||||
/// </summary>
|
||||
public int GetEstimatedMessageSize()
|
||||
{
|
||||
int size = 0;
|
||||
if (this.Header != null) size += 64;
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
// ------------------------------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR
|
||||
// CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
|
||||
// NON-INFRINGEMENT.
|
||||
//
|
||||
// See the Apache Version 2.0 License for specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
namespace Amqp
|
||||
{
|
||||
using Amqp.Framing;
|
||||
|
||||
/// <summary>
|
||||
/// Contains the state associated with a message delivery.
|
||||
/// </summary>
|
||||
public struct MessageDelivery
|
||||
{
|
||||
readonly Delivery delivery;
|
||||
|
||||
internal MessageDelivery(Delivery delivery)
|
||||
{
|
||||
this.delivery = delivery;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returs an empty value for a message that is not delivered yet.
|
||||
/// </summary>
|
||||
public static MessageDelivery None
|
||||
{
|
||||
get { return default(MessageDelivery); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the delivery tag.
|
||||
/// </summary>
|
||||
public byte[] Tag
|
||||
{
|
||||
get { return this.delivery.Tag; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the delivery state.
|
||||
/// </summary>
|
||||
public DeliveryState State
|
||||
{
|
||||
get { return this.delivery.State; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Link over which the message was transferred, or null if the message is not transferred yet.
|
||||
/// </summary>
|
||||
public Link Link
|
||||
{
|
||||
get { return this.delivery.Link; }
|
||||
}
|
||||
|
||||
internal Delivery Delivery
|
||||
{
|
||||
get { return this.delivery; }
|
||||
}
|
||||
};
|
||||
}
|
|
@ -68,7 +68,8 @@ namespace Amqp
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the open.idle-time-out field.
|
||||
/// Gets or sets the connection idle timeout. Half the value is set
|
||||
/// as the value of open.idle-time-out field.
|
||||
/// </summary>
|
||||
public int IdleTimeout
|
||||
{
|
||||
|
|
|
@ -91,6 +91,10 @@ namespace Amqp
|
|||
{
|
||||
await this.PumpAsync(connection.MaxFrameSize, connection.OnHeader, connection.OnFrame).ConfigureAwait(false);
|
||||
}
|
||||
catch (AmqpException amqpException)
|
||||
{
|
||||
connection.OnException(amqpException);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
connection.OnIoException(exception);
|
||||
|
|
|
@ -110,15 +110,37 @@ namespace Amqp
|
|||
/// Creates a new connection with a custom open frame and a callback to handle remote open frame.
|
||||
/// </summary>
|
||||
/// <param name="address">The address of remote endpoint to connect to.</param>
|
||||
/// <param name="open">If specified, it is sent to open the connection, otherwise an open frame created from the AMQP settings property is sent.</param>
|
||||
/// <param name="open">If specified, it is sent to open the connection, otherwise an open frame created from the AMQP settings is sent.</param>
|
||||
/// <param name="onOpened">If specified, it is invoked when an open frame is received from the remote peer.</param>
|
||||
/// <returns>A task for the connection creation operation. On success, the result is an AMQP <see cref="Connection"/></returns>
|
||||
/// <remarks>The Open object, when provided, is used as is, and not augmented by the AMQP settings.</remarks>
|
||||
public Task<Connection> CreateAsync(Address address, Open open = null, OnOpened onOpened = null)
|
||||
{
|
||||
return this.CreateAsync(address, open, onOpened, null);
|
||||
}
|
||||
|
||||
async Task<Connection> CreateAsync(Address address, Open open, OnOpened onOpened, IHandler handler)
|
||||
internal async Task ConnectAsync(Address address, SaslProfile saslProfile, Open open, Connection connection)
|
||||
{
|
||||
if (saslProfile == null)
|
||||
{
|
||||
if (address.User != null)
|
||||
{
|
||||
saslProfile = new SaslPlainProfile(address.User, address.Password);
|
||||
}
|
||||
else if (this.saslSettings != null && this.saslSettings.Profile != null)
|
||||
{
|
||||
saslProfile = this.saslSettings.Profile;
|
||||
}
|
||||
}
|
||||
|
||||
IAsyncTransport transport = await this.CreateTransportAsync(address, saslProfile, connection.Handler).ConfigureAwait(false);
|
||||
connection.Init(this.BufferManager, this.AMQP, transport, open);
|
||||
|
||||
AsyncPump pump = new AsyncPump(this.BufferManager, transport);
|
||||
pump.Start(connection);
|
||||
}
|
||||
|
||||
async Task<IAsyncTransport> CreateTransportAsync(Address address, SaslProfile saslProfile, IHandler handler)
|
||||
{
|
||||
IAsyncTransport transport;
|
||||
TransportProvider provider;
|
||||
|
@ -145,27 +167,38 @@ namespace Amqp
|
|||
throw new NotSupportedException(address.Scheme);
|
||||
}
|
||||
|
||||
try
|
||||
if (saslProfile != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
transport = await saslProfile.OpenAsync(address.Host, this.BufferManager, transport, null).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
transport.Close();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return transport;
|
||||
}
|
||||
|
||||
async Task<Connection> CreateAsync(Address address, Open open, OnOpened onOpened, IHandler handler)
|
||||
{
|
||||
SaslProfile saslProfile = null;
|
||||
if (address.User != null)
|
||||
{
|
||||
if (address.User != null)
|
||||
{
|
||||
SaslPlainProfile profile = new SaslPlainProfile(address.User, address.Password);
|
||||
transport = await profile.OpenAsync(address.Host, this.BufferManager, transport, null).ConfigureAwait(false);
|
||||
}
|
||||
else if (this.saslSettings != null && this.saslSettings.Profile != null)
|
||||
{
|
||||
transport = await this.saslSettings.Profile.OpenAsync(address.Host, this.BufferManager, transport, null).ConfigureAwait(false);
|
||||
}
|
||||
saslProfile = new SaslPlainProfile(address.User, address.Password);
|
||||
}
|
||||
catch
|
||||
else if (this.saslSettings != null && this.saslSettings.Profile != null)
|
||||
{
|
||||
transport.Close();
|
||||
throw;
|
||||
saslProfile = this.saslSettings.Profile;
|
||||
}
|
||||
|
||||
IAsyncTransport transport = await this.CreateTransportAsync(address, saslProfile, handler).ConfigureAwait(false);
|
||||
Connection connection = new Connection(this.BufferManager, this.AMQP, address, transport, open, onOpened, handler);
|
||||
|
||||
AsyncPump pump = new AsyncPump(this.BufferManager, transport);
|
||||
Connection connection = new Connection(this.BufferManager, this.AMQP, address, transport, open, onOpened, handler);
|
||||
pump.Start(connection);
|
||||
|
||||
return connection;
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace Amqp
|
|||
this.amqpSettings = new AmqpSettings()
|
||||
{
|
||||
MaxFrameSize = (int)Connection.DefaultMaxFrameSize,
|
||||
ContainerId = "AMQPNetLite-" + Guid.NewGuid().ToString("N").Substring(0, 8),
|
||||
ContainerId = Connection.MakeAmqpContainerId(),
|
||||
IdleTimeout = int.MaxValue,
|
||||
MaxSessionsPerConnection = Connection.DefaultMaxSessions,
|
||||
MaxLinksPerSession = Connection.DefaultMaxLinksPerSession
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace Amqp
|
|||
{
|
||||
async Task<IConnection> IConnectionFactory.CreateAsync(Address address)
|
||||
{
|
||||
return await this.CreateAsync(address, null, null);
|
||||
return await this.CreateAsync(address, null, null).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,10 @@ namespace Amqp
|
|||
// but it seems that the value is passed to the PAL implementation
|
||||
// so it should work if the runtime supports it.
|
||||
// 3 = TcpKeepAliveTime, 17 = TcpKeepAliveInterval
|
||||
socket.SetSocketOption(SocketOptionLevel.Tcp, (SocketOptionName)3, (int)settings.KeepAliveTime);
|
||||
socket.SetSocketOption(SocketOptionLevel.Tcp, (SocketOptionName)17, (int)settings.KeepAliveInterval);
|
||||
int timeInSeconds = (int)Math.Ceiling(settings.KeepAliveTime / 1000.0);
|
||||
int intervalInSeconds = (int)Math.Ceiling(settings.KeepAliveInterval / 1000.0);
|
||||
socket.SetSocketOption(SocketOptionLevel.Tcp, (SocketOptionName)3, timeInSeconds);
|
||||
socket.SetSocketOption(SocketOptionLevel.Tcp, (SocketOptionName)17, intervalInSeconds);
|
||||
#else
|
||||
// This is only supported on Windows
|
||||
|
||||
|
|
|
@ -152,14 +152,14 @@ namespace Amqp
|
|||
}
|
||||
|
||||
#if !NETFX40
|
||||
Task task = await Task.WhenAny(tcs.Task, Task.Delay(timeout));
|
||||
Task task = await Task.WhenAny(tcs.Task, Task.Delay(timeout)).ConfigureAwait(false);
|
||||
if (task != tcs.Task)
|
||||
{
|
||||
tcs.TrySetException(new TimeoutException(Fx.Format(SRAmqp.AmqpTimeout,
|
||||
"close", timeout, this.GetType().Name)));
|
||||
}
|
||||
#endif
|
||||
await tcs.Task;
|
||||
await tcs.Task.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
public class TcpKeepAliveSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// How often a keep-alive transmission is sent to an idle connection.
|
||||
/// Gets or sets a value in milliseconds that defines how often a keep-alive transmission is sent to an idle connection.
|
||||
/// </summary>
|
||||
public uint KeepAliveTime
|
||||
{
|
||||
|
@ -15,7 +15,8 @@
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// How often a keep-alive transmission is sent when no response is received from previous keep-alive transmissions.
|
||||
/// Gets or sets a value in milliseconds that defines how often a keep-alive transmission
|
||||
/// is sent when no response is received from previous keep-alive transmissions.
|
||||
/// </summary>
|
||||
public uint KeepAliveInterval
|
||||
{
|
||||
|
|
|
@ -119,7 +119,7 @@ namespace Amqp
|
|||
IAsyncTransport transport;
|
||||
if (address.UseSsl)
|
||||
{
|
||||
RemoteCertificateValidationCallback remoteCertificateValidationCallback = null;
|
||||
RemoteCertificateValidationCallback remoteCertificateValidationCallback = Connection.DisableServerCertValidation ? noneCertValidator : null;
|
||||
LocalCertificateSelectionCallback localCertificateSelectionCallback = null;
|
||||
var ssl = factory.SslInternal;
|
||||
if (ssl != null)
|
||||
|
|
|
@ -25,5 +25,5 @@ using System.Reflection;
|
|||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("2.1.0")]
|
||||
[assembly: AssemblyFileVersion("2.4.3")]
|
||||
[assembly: AssemblyInformationalVersion("2.4.3")]
|
||||
[assembly: AssemblyFileVersion("2.4.4")]
|
||||
[assembly: AssemblyInformationalVersion("2.4.4")]
|
||||
|
|
|
@ -240,9 +240,18 @@ namespace Amqp
|
|||
/// </summary>
|
||||
/// <param name="message">The message to accept.</param>
|
||||
public void Accept(Message message)
|
||||
{
|
||||
this.Accept(message.GetDelivery());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Accepts a message. It sends an accepted outcome to the peer.
|
||||
/// </summary>
|
||||
/// <param name="messageDelivery">Delivery information of a message to accept.</param>
|
||||
public void Accept(MessageDelivery messageDelivery)
|
||||
{
|
||||
this.ThrowIfDetaching("Accept");
|
||||
this.DisposeMessage(message, new Accepted(), null);
|
||||
this.UpdateDelivery(messageDelivery, new Accepted(), null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -251,8 +260,17 @@ namespace Amqp
|
|||
/// <param name="message">The message to release.</param>
|
||||
public void Release(Message message)
|
||||
{
|
||||
this.ThrowIfDetaching("Release");
|
||||
this.DisposeMessage(message, new Released(), null);
|
||||
this.Release(message.GetDelivery());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases a message. It sends a released outcome to the peer.
|
||||
/// </summary>
|
||||
/// <param name="messageDelivery">Delivery information of a message to release.</param>
|
||||
public void Release(MessageDelivery messageDelivery)
|
||||
{
|
||||
this.ThrowIfDetaching("Accept");
|
||||
this.UpdateDelivery(messageDelivery, new Released(), null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -261,9 +279,19 @@ namespace Amqp
|
|||
/// <param name="message">The message to reject.</param>
|
||||
/// <param name="error">The error, if any, for the rejection.</param>
|
||||
public void Reject(Message message, Error error = null)
|
||||
{
|
||||
this.Reject(message.GetDelivery(), error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rejects a message. It sends a rejected outcome to the peer.
|
||||
/// </summary>
|
||||
/// <param name="messageDelivery">Delivery information of a message to reject.</param>
|
||||
/// <param name="error">The error, if any, for the rejection.</param>
|
||||
public void Reject(MessageDelivery messageDelivery, Error error = null)
|
||||
{
|
||||
this.ThrowIfDetaching("Reject");
|
||||
this.DisposeMessage(message, new Rejected() { Error = error }, null);
|
||||
this.UpdateDelivery(messageDelivery, new Rejected() { Error = error }, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -274,15 +302,27 @@ namespace Amqp
|
|||
/// <param name="undeliverableHere">Indicates if the message should not be redelivered to this endpoint.</param>
|
||||
/// <param name="messageAnnotations">Annotations to be combined with the current message annotations.</param>
|
||||
public void Modify(Message message, bool deliveryFailed, bool undeliverableHere = false, Fields messageAnnotations = null)
|
||||
{
|
||||
this.Modify(message.GetDelivery(), deliveryFailed, undeliverableHere, messageAnnotations);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modifies a message. It sends a modified outcome to the peer.
|
||||
/// </summary>
|
||||
/// <param name="messageDelivery">Delivery information of a message to reject.</param>
|
||||
/// <param name="deliveryFailed">If set, the message's delivery-count is incremented.</param>
|
||||
/// <param name="undeliverableHere">Indicates if the message should not be redelivered to this endpoint.</param>
|
||||
/// <param name="messageAnnotations">Annotations to be combined with the current message annotations.</param>
|
||||
public void Modify(MessageDelivery messageDelivery, bool deliveryFailed, bool undeliverableHere = false, Fields messageAnnotations = null)
|
||||
{
|
||||
this.ThrowIfDetaching("Modify");
|
||||
this.DisposeMessage(message, new Modified()
|
||||
{
|
||||
DeliveryFailed = deliveryFailed,
|
||||
UndeliverableHere = undeliverableHere,
|
||||
MessageAnnotations = messageAnnotations
|
||||
},
|
||||
null);
|
||||
this.UpdateDelivery(messageDelivery, new Modified()
|
||||
{
|
||||
DeliveryFailed = deliveryFailed,
|
||||
UndeliverableHere = undeliverableHere,
|
||||
MessageAnnotations = messageAnnotations
|
||||
},
|
||||
null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -297,7 +337,22 @@ namespace Amqp
|
|||
/// <paramref name="deliveryState"/>.</remarks>
|
||||
public void Complete(Message message, DeliveryState deliveryState)
|
||||
{
|
||||
this.DisposeMessage(message, null, deliveryState);
|
||||
this.Complete(message.GetDelivery(), deliveryState);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Completes a received message. It settles the delivery and sends
|
||||
/// a disposition with the delivery state to the remote peer.
|
||||
/// </summary>
|
||||
/// <param name="messageDelivery">Delivery information of a message to reject.</param>
|
||||
/// <param name="deliveryState">An <see cref="Outcome"/> or a TransactionalState.</param>
|
||||
/// <remarks>This method is not transaction aware. It should be used to bypass
|
||||
/// transaction context look up when transactions are not used at all, or
|
||||
/// to manage AMQP transactions directly by providing a TransactionalState to
|
||||
/// <paramref name="deliveryState"/>.</remarks>
|
||||
public void Complete(MessageDelivery messageDelivery, DeliveryState deliveryState)
|
||||
{
|
||||
this.UpdateDelivery(messageDelivery, null, deliveryState);
|
||||
}
|
||||
|
||||
internal override void OnFlow(Flow flow)
|
||||
|
@ -476,9 +531,14 @@ namespace Amqp
|
|||
}
|
||||
|
||||
// deliveryState overwrites outcome
|
||||
void DisposeMessage(Message message, Outcome outcome, DeliveryState deliveryState)
|
||||
void UpdateDelivery(MessageDelivery messageDelivery, Outcome outcome, DeliveryState deliveryState)
|
||||
{
|
||||
Delivery delivery = message.Delivery;
|
||||
Delivery delivery = messageDelivery.Delivery;
|
||||
if (delivery == null)
|
||||
{
|
||||
throw new InvalidOperationException("Message was not delivered yet.");
|
||||
}
|
||||
|
||||
if (delivery == null || delivery.Link != this)
|
||||
{
|
||||
throw new InvalidOperationException("Message was not received by this link.");
|
||||
|
|
|
@ -93,15 +93,37 @@ namespace Amqp
|
|||
/// Creates a new connection with a custom open frame and a callback to handle remote open frame.
|
||||
/// </summary>
|
||||
/// <param name="address">The address of remote endpoint to connect to.</param>
|
||||
/// <param name="open">If specified, it is sent to open the connection, otherwise an open frame created from the AMQP settings property is sent.</param>
|
||||
/// <param name="open">If specified, it is sent to open the connection, otherwise an open frame created from the AMQP settings is sent.</param>
|
||||
/// <param name="onOpened">If specified, it is invoked when an open frame is received from the remote peer.</param>
|
||||
/// <returns>A task for the connection creation operation. On success, the result is an AMQP <see cref="Connection"/></returns>
|
||||
/// <remarks>The Open object, when provided, is used as is, and not augmented by the AMQP settings.</remarks>
|
||||
public Task<Connection> CreateAsync(Address address, Open open, OnOpened onOpened)
|
||||
{
|
||||
return this.CreateAsync(address, open, onOpened, null);
|
||||
}
|
||||
|
||||
async Task<Connection> CreateAsync(Address address, Open open, OnOpened onOpened, IHandler handler)
|
||||
internal async Task ConnectAsync(Address address, SaslProfile saslProfile, Open open, Connection connection)
|
||||
{
|
||||
if (saslProfile == null)
|
||||
{
|
||||
if (address.User != null)
|
||||
{
|
||||
saslProfile = new SaslPlainProfile(address.User, address.Password);
|
||||
}
|
||||
else if (this.saslSettings != null && this.saslSettings.Profile != null)
|
||||
{
|
||||
saslProfile = this.saslSettings.Profile;
|
||||
}
|
||||
}
|
||||
|
||||
IAsyncTransport transport = await this.CreateTransportAsync(address, saslProfile, connection.Handler).ConfigureAwait(false);
|
||||
connection.Init(null, this.AMQP, transport, open);
|
||||
|
||||
AsyncPump pump = new AsyncPump(null, transport);
|
||||
pump.Start(connection);
|
||||
}
|
||||
|
||||
async Task<IAsyncTransport> CreateTransportAsync(Address address, SaslProfile saslProfile, IHandler handler)
|
||||
{
|
||||
IAsyncTransport transport;
|
||||
#if !WINDOWS_PHONE
|
||||
|
@ -125,18 +147,38 @@ namespace Amqp
|
|||
throw new NotSupportedException(address.Scheme);
|
||||
}
|
||||
|
||||
if (saslProfile != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
transport = await saslProfile.OpenAsync(address.Host, null, transport, null).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
transport.Close();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return transport;
|
||||
}
|
||||
|
||||
async Task<Connection> CreateAsync(Address address, Open open, OnOpened onOpened, IHandler handler)
|
||||
{
|
||||
SaslProfile saslProfile = null;
|
||||
if (address.User != null)
|
||||
{
|
||||
SaslPlainProfile profile = new SaslPlainProfile(address.User, address.Password);
|
||||
transport = await profile.OpenAsync(address.Host, null, transport, null).ConfigureAwait(false);
|
||||
saslProfile = new SaslPlainProfile(address.User, address.Password);
|
||||
}
|
||||
else if (this.saslSettings != null && this.saslSettings.Profile != null)
|
||||
{
|
||||
transport = await this.saslSettings.Profile.OpenAsync(address.Host, null, transport, null).ConfigureAwait(false);
|
||||
saslProfile = this.saslSettings.Profile;
|
||||
}
|
||||
|
||||
AsyncPump pump = new AsyncPump(null, transport);
|
||||
IAsyncTransport transport = await this.CreateTransportAsync(address, saslProfile, handler).ConfigureAwait(false);
|
||||
Connection connection = new Connection(null, this.AMQP, address, transport, open, onOpened, handler);
|
||||
|
||||
AsyncPump pump = new AsyncPump(null, transport);
|
||||
pump.Start(connection);
|
||||
|
||||
return connection;
|
||||
|
|
|
@ -73,6 +73,7 @@ namespace Test.Amqp
|
|||
|
||||
public void TestCleanup()
|
||||
{
|
||||
this.host.AddressResolver = null;
|
||||
if (this.linkProcessor != null)
|
||||
{
|
||||
this.host.UnregisterLinkProcessor(this.linkProcessor);
|
||||
|
@ -93,6 +94,66 @@ namespace Test.Amqp
|
|||
this.ClassCleanup();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ContainerHostAddressResolverTest()
|
||||
{
|
||||
string name = "router";
|
||||
var processor = new TestMessageProcessor();
|
||||
this.host.AddressResolver = (h, a) => name;
|
||||
this.host.RegisterMessageProcessor(name, processor);
|
||||
|
||||
int count = 10;
|
||||
var connection = new Connection(Address);
|
||||
var session = new Session(connection);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var sender = new SenderLink(session, "send-link", "node" + i);
|
||||
var message = new Message("msg" + i);
|
||||
message.Properties = new Properties() { To = "node" + i };
|
||||
sender.Send(message, null, null);
|
||||
sender.Close();
|
||||
}
|
||||
|
||||
session.Close();
|
||||
connection.Close();
|
||||
|
||||
Assert.AreEqual(count, processor.Messages.Count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var message = processor.Messages[i];
|
||||
Assert.AreEqual("node" + (i % 10), message.Properties.To);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ContainerHostDynamicProcessorTest()
|
||||
{
|
||||
string name = "ContainerHostDynamicProcessorTest";
|
||||
var processor = new TestMessageProcessor();
|
||||
this.host.AddressResolver = (h, a) =>
|
||||
{
|
||||
h.RegisterMessageProcessor(name, processor);
|
||||
return name;
|
||||
};
|
||||
|
||||
int count = 10;
|
||||
var connection = new Connection(Address);
|
||||
var session = new Session(connection);
|
||||
var sender = new SenderLink(session, "send-link", name);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var message = new Message("msg" + i);
|
||||
message.Properties = new Properties() { GroupId = name };
|
||||
sender.Send(message, Timeout);
|
||||
}
|
||||
|
||||
sender.Close();
|
||||
session.Close();
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ContainerHostMessageProcessorTest()
|
||||
{
|
||||
|
@ -177,6 +238,70 @@ namespace Test.Amqp
|
|||
Assert.AreEqual(rejected, source.DeadLetterCount, string.Join(",", source.DeadletterMessage.Select(m => m.Properties.MessageId)));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ContainerHostMessageSourceDrainTest()
|
||||
{
|
||||
string name = "ContainerHostMessageSourceDrainTest";
|
||||
int count = 10;
|
||||
Queue<Message> messages = new Queue<Message>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
messages.Enqueue(new Message("test") { Properties = new Properties() { MessageId = name + i } });
|
||||
}
|
||||
|
||||
var source = new TestMessageSource(messages);
|
||||
this.host.RegisterMessageSource(name, source);
|
||||
|
||||
var connection = new Connection(Address);
|
||||
var session = new Session(connection);
|
||||
var receiver = new ReceiverLink(session, "receiver0", name);
|
||||
receiver.SetCredit(count + 4, CreditMode.Drain);
|
||||
for (int i = 1; i <= count; i++)
|
||||
{
|
||||
var message = receiver.Receive();
|
||||
Assert.IsTrue(message != null);
|
||||
receiver.Accept(message);
|
||||
}
|
||||
{
|
||||
messages.Enqueue(new Message("test") { Properties = new Properties() { MessageId = name + count } });
|
||||
var message = receiver.Receive(TimeSpan.FromMilliseconds(500));
|
||||
Assert.IsTrue(message == null);
|
||||
}
|
||||
|
||||
receiver.Close();
|
||||
session.Close();
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ContainerHostAnyMessageSourceTest()
|
||||
{
|
||||
string name = "*";
|
||||
int count = 10;
|
||||
Queue<Message> messages = new Queue<Message>();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
messages.Enqueue(new Message("test") { Properties = new Properties() { MessageId = name + i } });
|
||||
}
|
||||
|
||||
this.host.AddressResolver = (h, a) => name;
|
||||
var source = new TestMessageSource(messages);
|
||||
this.host.RegisterMessageSource(name, source);
|
||||
|
||||
var connection = new Connection(Address);
|
||||
var session = new Session(connection);
|
||||
var receiver = new ReceiverLink(session, "receiver0", null);
|
||||
for (int i = 1; i <= count; i++)
|
||||
{
|
||||
Message message = receiver.Receive();
|
||||
receiver.Accept(message);
|
||||
}
|
||||
|
||||
receiver.Close();
|
||||
session.Close();
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ContainerHostRequestProcessorTest()
|
||||
{
|
||||
|
@ -887,6 +1012,25 @@ namespace Test.Amqp
|
|||
connection.Close();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ContainerHostListenerCustomSaslMechanismTest()
|
||||
{
|
||||
string name = "ContainerHostListenerCustomSaslMechanismTest";
|
||||
var serverSaslProfile = new CustomSaslProfile(name);
|
||||
this.host.Listeners[0].SASL.EnableMechanism(name, serverSaslProfile);
|
||||
this.host.RegisterMessageProcessor(name, new TestMessageProcessor());
|
||||
|
||||
var factory = new ConnectionFactory();
|
||||
factory.SASL.Profile = new CustomSaslProfile(name);
|
||||
var connection = factory.CreateAsync(new Address(Address.Host, Address.Port, null, null, "/", Address.Scheme)).Result;
|
||||
var session = new Session(connection);
|
||||
var sender = new SenderLink(session, name, name);
|
||||
sender.Send(new Message("msg1"), Timeout);
|
||||
connection.Close();
|
||||
|
||||
Assert.IsTrue(serverSaslProfile.Transport != null);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ContainerHostSaslPlainNegativeTest()
|
||||
{
|
||||
|
@ -1395,9 +1539,11 @@ namespace Test.Amqp
|
|||
{
|
||||
}
|
||||
|
||||
public ITransport Transport { get; private set;}
|
||||
|
||||
protected override ITransport UpgradeTransport(ITransport transport)
|
||||
{
|
||||
return transport;
|
||||
return this.Transport = transport;
|
||||
}
|
||||
|
||||
protected override DescribedList GetStartCommand(string hostname)
|
||||
|
@ -1411,6 +1557,11 @@ namespace Test.Amqp
|
|||
|
||||
protected override DescribedList OnCommand(DescribedList command)
|
||||
{
|
||||
if (command.Descriptor.Code == 0x0000000000000041 /* SaslInit.Code */)
|
||||
{
|
||||
return new SaslOutcome() { Code = SaslCode.Ok };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,6 +149,110 @@ namespace Test.Amqp
|
|||
connection.Close();
|
||||
}
|
||||
|
||||
#if NETFX || NETFX35 || NETFX_CORE || DOTNET
|
||||
[TestMethod]
|
||||
#endif
|
||||
public void TestMethod_MessageDeliveryAccept()
|
||||
{
|
||||
string testName = "MessageDeliveryAccept";
|
||||
Connection connection = new Connection(testTarget.Address);
|
||||
Session session = new Session(connection);
|
||||
SenderLink sender = new SenderLink(session, "sender-" + testName, testTarget.Path);
|
||||
Message message = new Message("msg accept");
|
||||
sender.Send(message, null, null);
|
||||
|
||||
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, testTarget.Path);
|
||||
message = receiver.Receive();
|
||||
MessageDelivery messageDelivery = message.GetDelivery();
|
||||
message.Dispose();
|
||||
receiver.Accept(messageDelivery);
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
#if NETFX || NETFX35 || NETFX_CORE || DOTNET
|
||||
[TestMethod]
|
||||
#endif
|
||||
public void TestMethod_MessageDeliveryRelease()
|
||||
{
|
||||
string testName = "MessageDeliveryRelease";
|
||||
Connection connection = new Connection(testTarget.Address);
|
||||
Session session = new Session(connection);
|
||||
SenderLink sender = new SenderLink(session, "sender-" + testName, testTarget.Path);
|
||||
Message message = new Message("msg release");
|
||||
sender.Send(message, null, null);
|
||||
|
||||
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, testTarget.Path);
|
||||
message = receiver.Receive();
|
||||
MessageDelivery messageDelivery = message.GetDelivery();
|
||||
message.Dispose();
|
||||
receiver.Release(messageDelivery);
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
#if NETFX || NETFX35 || NETFX_CORE || DOTNET
|
||||
[TestMethod]
|
||||
#endif
|
||||
public void TestMethod_MessageDeliveryReject()
|
||||
{
|
||||
string testName = "MessageDeliveryReject";
|
||||
Connection connection = new Connection(testTarget.Address);
|
||||
Session session = new Session(connection);
|
||||
SenderLink sender = new SenderLink(session, "sender-" + testName, testTarget.Path);
|
||||
Message message = new Message("msg reject");
|
||||
sender.Send(message, null, null);
|
||||
|
||||
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, testTarget.Path);
|
||||
message = receiver.Receive();
|
||||
MessageDelivery messageDelivery = message.GetDelivery();
|
||||
message.Dispose();
|
||||
receiver.Reject(messageDelivery);
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
#if NETFX || NETFX35 || NETFX_CORE || DOTNET
|
||||
[TestMethod]
|
||||
#endif
|
||||
public void TestMethod_MessageDeliveryModify()
|
||||
{
|
||||
string testName = "MessageDeliveryModify";
|
||||
Connection connection = new Connection(testTarget.Address);
|
||||
Session session = new Session(connection);
|
||||
SenderLink sender = new SenderLink(session, "sender-" + testName, testTarget.Path);
|
||||
Message message = new Message("msg modify");
|
||||
sender.Send(message, null, null);
|
||||
|
||||
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, testTarget.Path);
|
||||
message = receiver.Receive();
|
||||
MessageDelivery messageDelivery = message.GetDelivery();
|
||||
message.Dispose();
|
||||
receiver.Modify(messageDelivery, true);
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
#if NETFX || NETFX35 || NETFX_CORE || DOTNET
|
||||
[TestMethod]
|
||||
#endif
|
||||
public void TestMethod_MessageDeliveryResend()
|
||||
{
|
||||
string testName = "MessageDeliveryResend";
|
||||
Connection connection = new Connection(testTarget.Address);
|
||||
Session session = new Session(connection);
|
||||
SenderLink sender = new SenderLink(session, "sender-" + testName, testTarget.Path);
|
||||
Message message = new Message("msg resend");
|
||||
sender.Send(message, null, null);
|
||||
|
||||
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, testTarget.Path);
|
||||
message = receiver.Receive();
|
||||
MessageDelivery messageDelivery = message.GetDelivery();
|
||||
|
||||
message.Properties = new Properties() { GroupId = "abcdefg" };
|
||||
sender.Send(message, null, null);
|
||||
message.Dispose();
|
||||
|
||||
receiver.Accept(messageDelivery);
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
#if NETFX || NETFX35 || NETFX_CORE || DOTNET
|
||||
[TestMethod]
|
||||
#endif
|
||||
|
@ -623,6 +727,68 @@ namespace Test.Amqp
|
|||
connection.Close();
|
||||
}
|
||||
|
||||
#if NETFX || NETFX35 || NETFX_CORE || DOTNET
|
||||
[TestMethod]
|
||||
#endif
|
||||
public void TestMethod_ReceiveDrain()
|
||||
{
|
||||
string testName = "ReceiveDrain";
|
||||
Connection connection = new Connection(testTarget.Address);
|
||||
Session session = new Session(connection);
|
||||
|
||||
SenderLink sender = new SenderLink(session, "sender-" + testName, testTarget.Path);
|
||||
Message msg = new Message() { Properties = new Properties() { MessageId = "12345" } };
|
||||
sender.Send(msg);
|
||||
|
||||
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, testTarget.Path);
|
||||
receiver.SetCredit(2, CreditMode.Drain);
|
||||
msg = receiver.Receive();
|
||||
Assert.IsTrue(msg != null);
|
||||
|
||||
msg = new Message() { Properties = new Properties() { MessageId = "67890" } };
|
||||
sender.Send(msg);
|
||||
|
||||
msg = receiver.Receive(TimeSpan.FromTicks(600 * TimeSpan.TicksPerMillisecond));
|
||||
Assert.IsTrue(msg == null);
|
||||
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
#if NETFX || NETFX35 || NETFX_CORE || DOTNET
|
||||
[TestMethod]
|
||||
#endif
|
||||
public void TestMethod_ReceiveReceiveSend()
|
||||
{
|
||||
string testName = "ReceiveReceiveSend";
|
||||
Connection connection = new Connection(testTarget.Address);
|
||||
|
||||
Session session = new Session(connection);
|
||||
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, testTarget.Path);
|
||||
Message msg = receiver.Receive(TimeSpan.FromTicks(500 * TimeSpan.TicksPerMillisecond));
|
||||
Assert.IsTrue(msg == null);
|
||||
|
||||
receiver.Close();
|
||||
session.Close();
|
||||
|
||||
session = new Session(connection);
|
||||
receiver = new ReceiverLink(session, "receiver-" + testName, testTarget.Path);
|
||||
msg = receiver.Receive(TimeSpan.FromTicks(500 * TimeSpan.TicksPerMillisecond));
|
||||
Assert.IsTrue(msg == null);
|
||||
|
||||
Connection connection2 = new Connection(testTarget.Address);
|
||||
Session session2 = new Session(connection2);
|
||||
SenderLink sender = new SenderLink(session2, "sender-" + testName, testTarget.Path);
|
||||
msg = new Message() { Properties = new Properties() { MessageId = "12345" } };
|
||||
sender.Send(msg);
|
||||
|
||||
msg = receiver.Receive(TimeSpan.FromTicks(6000 * TimeSpan.TicksPerMillisecond));
|
||||
Assert.IsTrue(msg != null);
|
||||
receiver.Accept(msg);
|
||||
|
||||
connection2.Close();
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
#if NETFX || NETFX35 || NETFX_CORE || DOTNET
|
||||
[TestMethod]
|
||||
#endif
|
||||
|
@ -915,6 +1081,7 @@ namespace Test.Amqp
|
|||
}
|
||||
});
|
||||
|
||||
Connection.DisableServerCertValidation = true;
|
||||
Address sslAddress = new Address("amqps://guest:guest@localhost:5671");
|
||||
Connection connection = new Connection(sslAddress, handler);
|
||||
Session session = new Session(connection);
|
||||
|
|
|
@ -100,6 +100,101 @@ namespace Test.Amqp
|
|||
}).Unwrap().GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ConnectionMaxFrameSizeNegativeTest()
|
||||
{
|
||||
Stream networkStream = null;
|
||||
this.testListener.RegisterTarget(TestPoint.Flow, (stream, channel, fields) =>
|
||||
{
|
||||
networkStream = stream;
|
||||
TestListener.FRM(stream, 0x13UL, 0, channel, 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, false, false,
|
||||
new Fields() { { new Symbol("big-string"), new string('a', 1024) } }); // flow
|
||||
return TestOutcome.Stop;
|
||||
});
|
||||
|
||||
string testName = "ConnectionMaxFrameSizeNegativeTest";
|
||||
|
||||
Trace.WriteLine(TraceLevel.Information, "sync test");
|
||||
{
|
||||
Open open = new Open() { ContainerId = testName, HostName = "localhost", MaxFrameSize = 512 };
|
||||
Connection connection = new Connection(this.address, null, open, null);
|
||||
Session session = new Session(connection);
|
||||
ReceiverLink receiver = new ReceiverLink(session, "receiver-" + testName, "any");
|
||||
try
|
||||
{
|
||||
receiver.Receive();
|
||||
}
|
||||
catch (AmqpException) { }
|
||||
Assert.IsTrue(connection.Error != null);
|
||||
Assert.AreEqual((Symbol)ErrorCode.InvalidField, connection.Error.Condition);
|
||||
Assert.AreEqual(ConnectionState.End, connection.ConnectionState);
|
||||
try
|
||||
{
|
||||
Thread.Sleep(300);
|
||||
networkStream.WriteByte(0);
|
||||
Assert.IsTrue(false, "transport connection not closed");
|
||||
}
|
||||
catch (IOException) { }
|
||||
catch (ObjectDisposedException) { }
|
||||
}
|
||||
|
||||
Trace.WriteLine(TraceLevel.Information, "async test");
|
||||
networkStream = null;
|
||||
Task.Factory.StartNew(async () =>
|
||||
{
|
||||
ConnectionFactory factory = new ConnectionFactory();
|
||||
factory.AMQP.MaxFrameSize = 512;
|
||||
IConnection connection = await factory.CreateAsync(this.address);
|
||||
ISession session = connection.CreateSession();
|
||||
IReceiverLink receiver = session.CreateReceiver("receiver-" + testName, "any");
|
||||
try
|
||||
{
|
||||
await receiver.ReceiveAsync();
|
||||
}
|
||||
catch (AmqpException) { }
|
||||
Assert.IsTrue(connection.Error != null);
|
||||
Assert.AreEqual((Symbol)ErrorCode.InvalidField, connection.Error.Condition);
|
||||
try
|
||||
{
|
||||
networkStream.WriteByte(0);
|
||||
Assert.IsTrue(false, "transport connection not closed");
|
||||
}
|
||||
catch (IOException) { }
|
||||
catch (ObjectDisposedException) { }
|
||||
await connection.CloseAsync();
|
||||
}).Unwrap().GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void ConnectionWithUserOpenTest()
|
||||
{
|
||||
string testName = "ConnectionWithUserOpenTest";
|
||||
List receivedOpen = null;
|
||||
this.testListener.RegisterTarget(TestPoint.Open, (stream, channel, fields) =>
|
||||
{
|
||||
receivedOpen = fields;
|
||||
return TestOutcome.Continue;
|
||||
});
|
||||
|
||||
Task.Factory.StartNew(async () =>
|
||||
{
|
||||
ConnectionFactory factory = new ConnectionFactory();
|
||||
factory.AMQP.MaxFrameSize = 2048;
|
||||
factory.AMQP.MaxSessionsPerConnection = 10;
|
||||
|
||||
Open open = new Open() { ContainerId = testName, HostName = "localhost", MaxFrameSize = 4096, ChannelMax = 128 };
|
||||
Connection connection = await factory.CreateAsync(this.address, open, null);
|
||||
Session session = new Session(connection);
|
||||
SenderLink sender = new SenderLink(session, "sender-" + testName, "any");
|
||||
await sender.SendAsync(new Message("test") { Properties = new Properties() { MessageId = testName } });
|
||||
await connection.CloseAsync();
|
||||
|
||||
Assert.IsTrue(receivedOpen != null);
|
||||
Assert.AreEqual(open.MaxFrameSize, receivedOpen[2]);
|
||||
Assert.AreEqual(open.ChannelMax, receivedOpen[3]);
|
||||
}).Unwrap().GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RemoteSessionChannelTest()
|
||||
{
|
||||
|
@ -209,14 +304,16 @@ namespace Test.Amqp
|
|||
|
||||
Trace.WriteLine(TraceLevel.Information, "sync test");
|
||||
{
|
||||
Open open = new Open() { ContainerId = testName, HostName = "localhost", IdleTimeOut = 1000 };
|
||||
Open open = new Open() { ContainerId = testName, HostName = "localhost", IdleTimeOut = 500 };
|
||||
Connection connection = new Connection(this.address, null, open, null);
|
||||
Session session = new Session(connection);
|
||||
SenderLink sender = new SenderLink(session, "sender-" + testName, "any");
|
||||
sender.Send(new Message("test") { Properties = new Properties() { MessageId = testName } });
|
||||
Thread.Sleep(1200);
|
||||
var h = connection.GetType().GetField("heartBeat", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
Assert.IsTrue(h != null, "heart beat is not initialized");
|
||||
Thread.Sleep(600);
|
||||
Assert.IsTrue(!connection.IsClosed, "connection should not be closed");
|
||||
Thread.Sleep(600);
|
||||
Assert.IsTrue(connection.IsClosed, "connection not closed");
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace Listener.IContainer
|
|||
{
|
||||
foreach (string q in queues)
|
||||
{
|
||||
this.queues.Add(q, new TestQueue(this));
|
||||
this.queues.Add(q, new TestQueue(this, q));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -111,7 +111,7 @@ namespace Listener.IContainer
|
|||
{
|
||||
lock (this.queues)
|
||||
{
|
||||
this.queues.Add(queue, new TestQueue(this));
|
||||
this.queues.Add(queue, new TestQueue(this, queue));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,9 +220,8 @@ namespace Listener.IContainer
|
|||
{
|
||||
if (dynamic || (this.implicitQueue && !link.Name.StartsWith("$explicit:")))
|
||||
{
|
||||
queue = new TestQueue(this);
|
||||
queue = new TestQueue(this, address, !dynamic);
|
||||
this.queues.Add(address, queue);
|
||||
connection.Closed += (o, e) => this.RemoveQueue(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -361,6 +360,9 @@ namespace Listener.IContainer
|
|||
sealed class TestQueue
|
||||
{
|
||||
readonly TestAmqpBroker broker;
|
||||
readonly string address;
|
||||
readonly bool isImplicit;
|
||||
readonly HashSet<Connection> connections;
|
||||
readonly LinkedList<BrokerMessage> messages;
|
||||
readonly LinkedList<Consumer> waiters;
|
||||
readonly Dictionary<int, Publisher> publishers;
|
||||
|
@ -368,23 +370,27 @@ namespace Listener.IContainer
|
|||
readonly object syncRoot;
|
||||
int currentId;
|
||||
|
||||
public TestQueue(TestAmqpBroker broker)
|
||||
public TestQueue(TestAmqpBroker broker, string address, bool isImplicit = false)
|
||||
{
|
||||
this.broker = broker;
|
||||
this.address = address;
|
||||
this.isImplicit = isImplicit;
|
||||
this.connections = isImplicit ? new HashSet<Connection>() : null;
|
||||
this.messages = new LinkedList<BrokerMessage>();
|
||||
this.waiters = new LinkedList<Consumer>();
|
||||
this.publishers = new Dictionary<int, Publisher>();
|
||||
this.consumers = new Dictionary<int, Consumer>();
|
||||
this.syncRoot = this.waiters;
|
||||
this.syncRoot = new object();
|
||||
}
|
||||
|
||||
public void CreatePublisher(ListenerLink link)
|
||||
{
|
||||
int id = Interlocked.Increment(ref this.currentId);
|
||||
Publisher publisher = new Publisher(this, link, id);
|
||||
lock (this.publishers)
|
||||
lock (this.syncRoot)
|
||||
{
|
||||
this.publishers.Add(id, publisher);
|
||||
this.OnClientConnected(link);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -392,9 +398,34 @@ namespace Listener.IContainer
|
|||
{
|
||||
int id = Interlocked.Increment(ref this.currentId);
|
||||
Consumer consumer = new Consumer(this, link, id);
|
||||
lock (this.consumers)
|
||||
lock (this.syncRoot)
|
||||
{
|
||||
this.consumers.Add(id, consumer);
|
||||
this.OnClientConnected(link);
|
||||
}
|
||||
}
|
||||
|
||||
void OnClientConnected(Link link)
|
||||
{
|
||||
if (this.isImplicit && !this.connections.Contains(link.Session.Connection))
|
||||
{
|
||||
this.connections.Add(link.Session.Connection);
|
||||
link.Session.Connection.Closed += OnConnectionClosed;
|
||||
}
|
||||
}
|
||||
|
||||
void OnConnectionClosed(IAmqpObject sender, Error error)
|
||||
{
|
||||
if (this.isImplicit)
|
||||
{
|
||||
lock (this.syncRoot)
|
||||
{
|
||||
this.connections.Remove((Connection)sender);
|
||||
if (this.connections.Count == 0)
|
||||
{
|
||||
this.broker.RemoveQueue(this.address);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -455,7 +486,7 @@ namespace Listener.IContainer
|
|||
}
|
||||
}
|
||||
|
||||
void Dequeue(Consumer consumer, int credit)
|
||||
void Dequeue(Consumer consumer, int credit, bool drain)
|
||||
{
|
||||
List<BrokerMessage> messageList = new List<BrokerMessage>();
|
||||
lock (this.syncRoot)
|
||||
|
@ -492,7 +523,11 @@ namespace Listener.IContainer
|
|||
}
|
||||
}
|
||||
|
||||
if (consumer.Credit > 0)
|
||||
if (drain)
|
||||
{
|
||||
consumer.Credit = 0;
|
||||
}
|
||||
else if (consumer.Credit > 0)
|
||||
{
|
||||
this.waiters.AddLast(consumer);
|
||||
}
|
||||
|
@ -538,11 +573,20 @@ namespace Listener.IContainer
|
|||
}
|
||||
}
|
||||
|
||||
void OnPublisherClosed(int id, Publisher publisher)
|
||||
{
|
||||
lock (this.syncRoot)
|
||||
{
|
||||
this.publishers.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
void OnConsumerClosed(int id, Consumer consumer)
|
||||
{
|
||||
lock (this.syncRoot)
|
||||
{
|
||||
this.consumers.Remove(id);
|
||||
this.waiters.Remove(consumer);
|
||||
var node = this.messages.First;
|
||||
while (node != null)
|
||||
{
|
||||
|
@ -576,10 +620,7 @@ namespace Listener.IContainer
|
|||
|
||||
void OnLinkClosed(IAmqpObject sender, Error error)
|
||||
{
|
||||
lock (this.queue.publishers)
|
||||
{
|
||||
this.queue.publishers.Remove(this.id);
|
||||
}
|
||||
this.queue.OnPublisherClosed(this.id, this);
|
||||
}
|
||||
|
||||
static void OnMessage(ListenerLink link, Message message, DeliveryState deliveryState, object state)
|
||||
|
@ -631,7 +672,6 @@ namespace Listener.IContainer
|
|||
readonly TestQueue queue;
|
||||
readonly ListenerLink link;
|
||||
readonly int id;
|
||||
int tag;
|
||||
|
||||
public Consumer(TestQueue queue, ListenerLink link, int id)
|
||||
{
|
||||
|
@ -652,11 +692,6 @@ namespace Listener.IContainer
|
|||
this.link.SendMessage(message, message.Buffer);
|
||||
}
|
||||
|
||||
ArraySegment<byte> GetNextTag()
|
||||
{
|
||||
return new ArraySegment<byte>(BitConverter.GetBytes(Interlocked.Increment(ref this.tag)));
|
||||
}
|
||||
|
||||
void OnLinkClosed(IAmqpObject sender, Error error)
|
||||
{
|
||||
this.Credit = 0;
|
||||
|
@ -666,7 +701,12 @@ namespace Listener.IContainer
|
|||
static void OnCredit(int credit, Fields properties, object state)
|
||||
{
|
||||
var thisPtr = (Consumer)state;
|
||||
thisPtr.queue.Dequeue(thisPtr, credit);
|
||||
thisPtr.queue.Dequeue(thisPtr, credit, thisPtr.link.IsDraining);
|
||||
if (thisPtr.link.IsDraining)
|
||||
{
|
||||
thisPtr.Credit = 0;
|
||||
thisPtr.link.CompleteDrain();
|
||||
}
|
||||
}
|
||||
|
||||
static void OnDispose(Message message, DeliveryState deliveryState, bool settled, object state)
|
||||
|
|
|
@ -150,6 +150,54 @@ namespace Test.Amqp
|
|||
|
||||
await connection.CloseAsync();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task ReceiverSenderAsync()
|
||||
{
|
||||
string testName = "ReceiverSenderAsync";
|
||||
|
||||
ConnectionFactory connectionFactory = new ConnectionFactory();
|
||||
|
||||
// Creating first ReceiverLink
|
||||
Connection firstReceiverConnection = await connectionFactory.CreateAsync(this.testTarget.Address);
|
||||
Session firstReceiverSession = new Session(firstReceiverConnection);
|
||||
ReceiverLink firstReceiverLink = new ReceiverLink(firstReceiverSession, "receiver-link", testName);
|
||||
|
||||
// Does not work when creating SenderLink after first ReceiverLink
|
||||
var senderConnection = await connectionFactory.CreateAsync(this.testTarget.Address);
|
||||
var senderSession = new Session(senderConnection);
|
||||
var senderLink = new SenderLink(senderSession, "sender-link", testName);
|
||||
|
||||
// Send and receive message
|
||||
await senderLink.SendAsync(new Message(testName));
|
||||
Message firstMessageReceived = await firstReceiverLink.ReceiveAsync(TimeSpan.FromMilliseconds(1000));
|
||||
|
||||
// Close first reveiver link
|
||||
await firstReceiverLink.CloseAsync();
|
||||
await firstReceiverSession.CloseAsync();
|
||||
await firstReceiverConnection.CloseAsync();
|
||||
|
||||
// Creating second ReceiverLink
|
||||
Connection secondReceiverConnection = await connectionFactory.CreateAsync(this.testTarget.Address);
|
||||
Session secondReceiverSession = new Session(secondReceiverConnection);
|
||||
ReceiverLink secondReceiverLink = new ReceiverLink(secondReceiverSession, "receiver-link", testName);
|
||||
|
||||
// Send and receive message
|
||||
await senderLink.SendAsync(new Message(testName));
|
||||
Message message = await secondReceiverLink.ReceiveAsync(TimeSpan.FromMilliseconds(1000));
|
||||
Assert.IsTrue(message != null, "No message received");
|
||||
secondReceiverLink.Accept(message);
|
||||
|
||||
// Close second reveiver link
|
||||
await secondReceiverLink.CloseAsync();
|
||||
await secondReceiverSession.CloseAsync();
|
||||
await secondReceiverConnection.CloseAsync();
|
||||
|
||||
// Close sender link
|
||||
await senderLink.CloseAsync();
|
||||
await senderSession.CloseAsync();
|
||||
await senderConnection.CloseAsync();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NETFX40
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
<AppxBundle>Never</AppxBundle>
|
||||
<AllowCrossPlatformRetargeting>False</AllowCrossPlatformRetargeting>
|
||||
<IntermediateOutputPath>..\..\obj\$(Configuration)\$(MSBuildProjectName)\</IntermediateOutputPath>
|
||||
<PackageCertificateThumbprint>04523CFB02DAE8D40D906A2B7AB4D171D46EB550</PackageCertificateThumbprint>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
|
Двоичные данные
test/Test.Amqp.NetCore/Test.Amqp.NetCore_TemporaryKey.pfx
Двоичные данные
test/Test.Amqp.NetCore/Test.Amqp.NetCore_TemporaryKey.pfx
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче