Remove Cpp Client from this repo (#9050)

This commit is contained in:
BrennanConroy 2019-04-10 09:51:33 -07:00 committed by GitHub
parent 592859a8a7
commit 7c76144865
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
166 changed files with 0 additions and 27110 deletions

View File

@ -303,15 +303,10 @@ jobs:
displayName: Install SQL Server 2016 Express LocalDB
- powershell: "& ./src/Servers/IIS/tools/UpdateIISExpressCertificate.ps1; & ./src/Servers/IIS/tools/update_schema.ps1"
displayName: Setup IISExpress test certificates and schema
- powershell: "& ./.azure/pipelines/tools/SetupTestEnvironment.ps1 Setup signalrclienttests.exe"
displayName: Start AppVerifier
afterBuild:
- powershell: "& ./build.ps1 -CI -NoBuild -Test /p:RunFlakyTests=true"
displayName: Run Flaky Tests
continueOnError: true
- powershell: "& ./.azure/pipelines/tools/SetupTestEnvironment.ps1 Shutdown signalrclienttests.exe"
displayName: Stop AppVerifier
condition: always()
artifacts:
- name: Windows_Test_Logs
path: artifacts/logs/

View File

@ -14,11 +14,4 @@ jobs:
agentOs: Windows
jobName: SignalRDailyTests
jobDisplayName: "SignalR Daily Tests"
beforeBuild:
- powershell: "& ./.azure/pipelines/tools/SetupTestEnvironment.ps1 Setup signalrclienttests.exe"
displayName: Start AppVerifier
afterBuild:
- powershell: "& ./.azure/pipelines/tools/SetupTestEnvironment.ps1 Shutdown signalrclienttests.exe"
displayName: Stop AppVerifier
condition: always()

View File

@ -54,8 +54,6 @@
$(RepositoryRoot)src\Tools\dotnet-watch\test\TestProjects\**\*.csproj;
$(RepositoryRoot)src\Razor\Razor.Design\test\testassets\**\*.*proj;
$(RepositoryRoot)src\submodules\**\*.*proj;
$(RepositoryRoot)src\SignalR\clients\cpp\samples\**\*.*proj;
$(RepositoryRoot)src\SignalR\clients\cpp\test\signalrclient-testhost\**\*.*proj;
$(RepositoryRoot)src\Installers\**\*.*proj;
$(RepositoryRoot)src\SignalR\clients\ts\**\node_modules\**\*.*proj;
$(RepositoryRoot)src\Components\Blazor\Templates\src\content\**\*.*proj;

View File

@ -1,3 +0,0 @@
[submodule "clients/cpp/test/gtest/googletest"]
path = clients/cpp/test/gtest/googletest
url = https://github.com/google/googletest

View File

@ -1,3 +0,0 @@
packages/
Debug/
Release/

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildThisFileDirectory)Version.props" />
<PropertyGroup>
<SolutionDir Condition="$(SolutionDir) == '' Or '$(SolutionDir)' == '*Undefined*'">$(MSBuildThisFileDirectory)..\</SolutionDir>
<Configuration Condition="'$(Configuration)'==''">Debug</Configuration>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<PlatformToolset Condition=" '$(PlatformToolset)' == '' And '$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset>
<PlatformToolset Condition=" '$(PlatformToolset)' == '' And '$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
<PlatformToolset Condition=" '$(PlatformToolset)' == ''">v140</PlatformToolset>
<SubSystem Condition="'$(SubSystem)' != 'UWP'">Desktop</SubSystem>
<OutDir Condition="'$(OutDir)' == ''">$(SolutionDir)bin\$(SubSystem)\$(Platform)\$(Configuration)\</OutDir>
<SignalrClientTargetName>signalrclient</SignalrClientTargetName>
<DefaultLanguage>en-US</DefaultLanguage>
</PropertyGroup>
</Project>

View File

@ -1,82 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="ExecAsync" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
<ParameterGroup>
<Executable ParameterType="System.String" Required="true" />
<Arguments ParameterType="System.String" Required="false" />
</ParameterGroup>
<Task>
<Using Namespace="System.IO" />
<Using Namespace="System.Diagnostics" />
<Code Type="Fragment" Language="cs">
<![CDATA[
Log.LogMessage("Executable {0}...", Executable);
var name = System.IO.Path.GetFileNameWithoutExtension(Executable);
Log.LogMessage("Starting {0}...", name);
var processStartInfo = new ProcessStartInfo(Executable, Arguments) { UseShellExecute = true };
Process.Start(processStartInfo);
Log.LogMessage("Finished starting process {0}.", name);
]]>
</Code>
</Task>
</UsingTask>
<UsingTask TaskName="Sleep" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
<ParameterGroup>
<TimeoutMs ParameterType="System.Int32" Required="true" />
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<![CDATA[System.Threading.Thread.Sleep(TimeoutMs);]]>
</Code>
</Task>
</UsingTask>
<UsingTask TaskName="ZipDir" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
<ParameterGroup>
<InputDir ParameterType="System.String" Required="true" />
<OutputFileName ParameterType="System.String" Required="true" />
<IncludeBaseDir ParameterType="System.Boolean" Required="false" />
</ParameterGroup>
<Task>
<Reference Include="System.IO.Compression.FileSystem" />
<Using Namespace="System.IO.Compression" />
<Code Type="Fragment" Language="cs">
<![CDATA[ ZipFile.CreateFromDirectory(InputDir, OutputFileName, CompressionLevel.Optimal, IncludeBaseDir); ]]>
</Code>
</Task>
</UsingTask>
<UsingTask TaskName="RegexReplaceInFile" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
<ParameterGroup>
<InputFilename ParameterType="System.String" Required="true" />
<OutputFilename ParameterType="System.String" Required="true" />
<Pattern ParameterType="System.String" Required="true" />
<Replacement ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Using Namespace="System.IO" />
<Using Namespace="System.Linq" />
<Using Namespace="System.Text.RegularExpressions" />
<Code Type="Fragment" Language="cs">
<![CDATA[
string contents;
using (var input = new StreamReader(InputFilename))
{
contents = input.ReadToEnd();
}
contents = new Regex(Pattern, RegexOptions.Compiled | RegexOptions.Multiline)
.Replace(contents, Replacement);
using (var output = new StreamWriter(OutputFilename))
{
output.Write(contents);
}
]]>
</Code>
</Task>
</UsingTask>
</Project>

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
</Project>

View File

@ -1,91 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildThisFileDirectory)\Common.Build.Settings" />
<PropertyGroup>
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe>
<RestorePackages>true</RestorePackages>
<CharacterSet>Unicode</CharacterSet>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<UseDebugLibraries>true</UseDebugLibraries>
<WholeProgramOptimization>false</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(SubSystem)' == 'UWP'">
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<AppContainerApplication>true</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
<GenerateProjectSpecificOutputFolder>False</GenerateProjectSpecificOutputFolder>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<TreatWarningAsError Condition="'$(TreatWarningsAsErrors)' != ''">true</TreatWarningAsError>
<SDLCheck>true</SDLCheck>
<StringPooling>true</StringPooling>
<CompileAsWinRT Condition="'$(SubSystem)' == 'UWP'">true</CompileAsWinRT>
</ClCompile>
<Link>
<SubSystem Condition="'$(SubSystem)' != 'UWP'">Windows</SubSystem>
<SubSystem Condition="'$(SubSystem)' == 'UWP'">Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile>
<StripPrivateSymbols>$(OutDir)$(TargetName).pub.pdb</StripPrivateSymbols>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<Profile>true</Profile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<Optimization>Disabled</Optimization>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>_WIN64;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>_WIN64;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
</Project>

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- When changing version remember to update version in $src\signalrclient\constants.h -->
<SignalRClientCppVersionMajor>1</SignalRClientCppVersionMajor>
<SignalRClientCppVersionMinor>0</SignalRClientCppVersionMinor>
<SignalRClientCppVersionPatch>0</SignalRClientCppVersionPatch>
<SignalRClientCppVersionSuffix>-alpha0</SignalRClientCppVersionSuffix>
<!-- $(build_number) generated by Team City -->
<SignalRClientCppVersionSuffix Condition="'$(build_number)' != '' And '$(build_branch)' != 'release'">$(SignalRClientCppVersionSuffix)-$(build_number)</SignalRClientCppVersionSuffix>
<SignalRClientCppVersionString>$(SignalRClientCppVersionMajor).$(SignalRClientCppVersionMinor).$(SignalRClientCppVersionPatch)$(SignalRClientCppVersionSuffix)</SignalRClientCppVersionString>
</PropertyGroup>
</Project>

View File

@ -1,148 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildThisFileDirectory)\Common.tasks" />
<Import Project="$(MSBuildThisFileDirectory)\Common.Build.Settings" />
<ItemGroup>
<Projects Include="$(SolutionDir)src\signalrclientdll\Build\VS\signalrclientdll.vcxproj" />
</ItemGroup>
<ItemGroup>
<TestProjects Include="$(SolutionDir)src\signalrclient\Build\VS\signalrclient.vcxproj" />
<TestProjects Include="$(SolutionDir)test\signalrclienttests\Build\VS\signalrclienttests.vcxproj" />
<TestProjects Include="$(SolutionDir)test\signalrclient-e2e-tests\Build\VS\signalrclient-e2e-tests.vcxproj" />
</ItemGroup>
<ItemGroup>
<!-- TestHost is an ASP.NET app, will replace with a ASP.NET Core app -->
<!-- <ManagedProjects Include="$(SolutionDir)test\signalrclient-testhost\signalrclient-testhost.csproj" /> -->
<!--
<ManagedProjects Include="$(SolutionDir)\samples\SignalRServer\SignalRServer.csproj" />
-->
</ItemGroup>
<ItemGroup>
<!--
<SampleProjects Include="$(SolutionDir)\samples\PersistentConnectionSample\PersistentConnectionSample.vcxproj" />
<SampleProjects Include="$(SolutionDir)\samples\HubConnectionSample\HubConnectionSample.vcxproj" />
-->
</ItemGroup>
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<Target Name="Build">
<MSBuild Targets="RestorePackages" Projects="@(Projects)" />
<MSBuild Targets="RestorePackages" Projects="@(SampleProjects)" />
<MSBuild Targets="RestorePackages" Projects="@(ManagedProjects)" />
<MSBuild Targets="$(BuildTargets)"
Projects="@(Projects)"
Properties="Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset);SubSystem=$(SubSystem)" />
<MSBuild Targets="$(BuildTargets)"
Projects="@(TestProjects)"
Properties="Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset)" Condition="'$(SubSystem)' == 'Desktop'"/>
<MSBuild Targets="$(BuildTargets)"
Projects="@(SampleProjects)"
Properties="Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset)" Condition="'$(SubSystem)' == 'Desktop'"/>
<MSBuild Targets="$(BuildTargets)"
Projects="@(ManagedProjects)"
Properties="Configuration=$(Configuration)" Condition="'$(SubSystem)' == 'Desktop'"/>
</Target>
<Target Name="Clean">
<MSBuild Targets="Clean"
Projects="@(Projects)" />
<MSBuild Targets="Clean"
Projects="@(TestProjects)" />
<MSBuild Targets="Clean"
Projects="@(SampleProjects)" />
<MSBuild Targets="Clean"
Projects="@(ManagedProjects)" />
</Target>
<Target Name="Rebuild">
<MSBuild Targets="Clean;Build"
Projects="$(MSBuildProjectFile)"
Properties="BuildTargets=Rebuild;Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset);SubSystem=$(SubSystem)"/>
</Target>
<Target Name="Test" DependsOnTargets="Build" Condition="'$(SubSystem)' == 'Desktop'">
<Exec Command="$(OutDir)\signalrclienttests.exe --gtest_output=xml:$(OutDir)test_results.xml" />
<ExecAsync Executable="$(SolutionDir)test\signalrclient-testhost\bin\$(Configuration)\signalrclient-testhost.exe" Arguments="60000" />
<!-- give the host some time to open the port otherwise the first tests may fail on slow machines-->
<Sleep TimeoutMs="3000" />
<Exec Command="$(OutDir)\signalrclient-e2e-tests.exe --gtest_output=xml:$(OutDir)e2e_test_results.xml" />
<Exec Command="taskkill /IM signalrclient-testhost.exe /F" ContinueOnError="true" />
</Target>
<Import Project="Config.Definitions.Props" />
<Target Name="CreatePackage">
<PropertyGroup>
<PlatformToolset Condition="'$(PlatformToolset)' == ''">v140</PlatformToolset>
<SubSystem Condition="'$(SubSystem)' != 'UWP'">Desktop</SubSystem>
<PackageSource>$(SolutionDir)bin\Package\$(SubSystem)\$(PlatformToolset)\</PackageSource>
<PackageSourceNative>$(PackageSource)build\native\</PackageSourceNative>
<NuGetArtifactsPath>$(MSBuildThisFileDirectory)..\NuGet\</NuGetArtifactsPath>
<NuSpecTemplatePath>$(NuGetArtifactsPath)signalrclientcpp.nuspec.template</NuSpecTemplatePath>
<PackageOutputDir>$(SolutionDir)artifacts\build</PackageOutputDir>
<PrivateSymbols>$(SolutionDir)bin\Symbols\$(SubSystem)\$(PlatformToolset)\</PrivateSymbols>
</PropertyGroup>
<Error Text="UWP not supported with v120 toolset" Condition="'$(SubSystem)' == 'UWP' And '$(PlatformToolset)' != 'v140'" />
<ItemGroup>
<Include Include="$(SolutionDir)include\**\*.*" />
</ItemGroup>
<Copy SourceFiles="@(Include)" DestinationFolder="$(PackageSourceNative)include\%(RecursiveDir)" />
<MakeDir Directories="$(PackageSource)" />
<RegexReplaceInFile InputFileName="$(NuSpecTemplatePath)" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#Toolset#" Replacement="$(PlatformToolset)" />
<RegexReplaceInFile InputFileName="$(PackageSource)signalrclientcpp.nuspec" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#casablanca-subsystem#" Replacement="windesktop" Condition="'$(SubSystem)' == 'Desktop'" />
<RegexReplaceInFile InputFileName="$(PackageSource)signalrclientcpp.nuspec" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#SubSystem#" Replacement="WinDesktop" Condition="'$(SubSystem)' == 'Desktop'" />
<RegexReplaceInFile InputFileName="$(PackageSource)signalrclientcpp.nuspec" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#casablanca-subsystem#" Replacement="winapp" Condition="'$(SubSystem)' == 'UWP'" />
<RegexReplaceInFile InputFileName="$(PackageSource)signalrclientcpp.nuspec" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#SubSystem#" Replacement="UWP" Condition="'$(SubSystem)' == 'UWP'" />
<RegexReplaceInFile InputFileName="$(NuGetArtifactsPath)\Microsoft.AspNet.SignalR.Client.Cpp.WinDesktop.targets.template"
OutputFileName="$(PackageSourceNative)Microsoft.AspNet.SignalR.Client.Cpp.$(PlatformToolset).WinDesktop.targets" Pattern="#Toolset#" Replacement="$(PlatformToolset)" Condition="'$(SubSystem)' == 'Desktop'" />
<RegexReplaceInFile InputFileName="$(NuGetArtifactsPath)\Microsoft.AspNet.SignalR.Client.Cpp.UWP.targets.template"
OutputFileName="$(PackageSourceNative)Microsoft.AspNet.SignalR.Client.Cpp.$(PlatformToolset).UWP.targets" Pattern="#Toolset#" Replacement="$(PlatformToolset)" Condition="'$(SubSystem)' == 'UWP'" />
<MSBuild Targets="RestorePackages" Projects="@(Projects)" />
<MSBuild Targets="BuildForNuget"
Projects="$(MSBuildThisFile)" Properties="PackageSourceNative=$(PackageSourceNative);PrivateSymbols=$(PrivateSymbols);Configuration=%(ProjectConfiguration.Configuration);Platform=%(ProjectConfiguration.Platform);PlatformToolset=$(PlatformToolset);SubSystem=$(SubSystem);SignalrClientTargetName=$(SignalrClientTargetName)" />
<MakeDir Directories="$(PackageOutputDir)" />
<Exec Command="$(NuGetCommand) pack $(PackageSource)signalrclientcpp.nuspec -BasePath $(PackageSource) -OutputDirectory $(PackageOutputDir) -Version $(SignalRClientCppVersionString)" LogStandardErrorAsError="true" />
<ZipDir InputDir="$(PrivateSymbols)" OutputFileName="$(PackageOutputDir)\Symbols_$(PlatformToolset)_$(SubSystem).zip" IncludeBaseDir="false"/>
</Target>
<Target Name="BuildForNuget">
<MSBuild Targets="$(BuildTargets)"
Projects="@(Projects)"
Properties="Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset);SubSystem=$(SubSystem)" />
<Copy SourceFiles="$(OutDir)dll\$(SignalrClientTargetName).lib" DestinationFolder="$(PackageSourceNative)lib\$(Platform)\$(PlatformToolset)\$(Configuration)" />
<Copy SourceFiles="$(OutDir)dll\$(SignalrClientTargetName).dll" DestinationFolder="$(PackageSourceNative)dll\$(Platform)\$(PlatformToolset)\$(Configuration)" />
<Copy SourceFiles="$(OutDir)dll\$(SignalrClientTargetName).pub.pdb" DestinationFiles="$(PackageSourceNative)dll\$(Platform)\$(PlatformToolset)\$(Configuration)\$(SignalrClientTargetName).pdb" />
<Copy SourceFiles="$(OutDir)dll\$(SignalrClientTargetName).pdb" DestinationFiles="$(PrivateSymbols)$(Platform)\$(PlatformToolset)\$(Configuration)\$(SignalrClientTargetName).pdb" />
</Target>
<Target Name="NuGetPush">
<PropertyGroup>
<NuGetExePath Condition="'$(NuGetExePath)' == ''">$(PUSH_NUGET_EXE)</NuGetExePath>
<NuGetExePath Condition="'$(NuGetExePath)' == ''">$(MSBuildThisFileDirectory)..\.nuget\NuGet.exe</NuGetExePath>
</PropertyGroup>
<ItemGroup>
<Package Include="$(SolutionDir)artifacts\build\*.nupkg" />
<Package Include="$(SolutionDir)artifacts\build\*.symbols.nupkg" />
</ItemGroup>
<Exec Command="$(NuGetExePath) push -nosymbols %(Package.Identity) -Source $(NUGET_PUBLISH_FEED) -ApiKey $(APIKEY)" />
</Target>
</Project>

View File

@ -1,19 +0,0 @@
cmake_minimum_required (VERSION 2.8.11)
project (signalrclient)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC -L -lcpprest")
set(CPPREST_INCLUDE_DIR "" CACHE FILEPATH "Path to casablanca include dir")
include_directories (
include
"${CPPREST_INCLUDE_DIR}")
find_library(CPPREST_SO NAMES "cpprest" PATHS ${CPPREST_LIB_DIR} REQUIRED)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
add_subdirectory(src/signalrclient)
add_subdirectory(test)

View File

@ -1,4 +0,0 @@
Contributing
======
Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo.

View File

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>

View File

@ -1,69 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="signalrclient_uwp_inittarget">
<PropertyGroup Condition="'$(PlatformToolset)' != 'v140' Or '$(ApplicationType)' != 'Windows Store'">
<DisableUwp>True</DisableUwp>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(DisableUwp)' == ''">
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<ResourceCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="x64 and #Toolset# and Release" Condition="'$(DisableUwp)' == '' And '$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
<Link>
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\x64\#Toolset#\Release\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="x64 and #Toolset# and Debug" Condition="'$(DisableUwp)' == '' And '$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) &gt; -1">
<Link>
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\x64\#Toolset#\Debug\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="Win32 and #Toolset# and Release" Condition="'$(DisableUwp)' == '' And '$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
<Link>
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\Win32\#Toolset#\Release\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="Win32 and #Toolset# and Debug" Condition="'$(DisableUwp)' == '' And '$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) &gt; -1">
<Link>
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\Win32\#Toolset#\Debug\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Target Name="signalrclient_uwp_AfterBuild" AfterTargets="AfterBuild" Condition="'$(DisableUwp)' == ''">
<PropertyGroup>
<UseHardlinksIfPossible Condition="'$(UseHardlinksIfPossible)' == ''">true</UseHardlinksIfPossible>
</PropertyGroup>
<Copy DestinationFolder="$(TargetDir)" SourceFiles="@(CopyToOutput)" SkipUnchangedFiles="true" UseHardlinksIfPossible="$(UseHardlinksIfPossible)">
<Output TaskParameter="DestinationFiles" PropertyName="DestinationFiles" />
<Output TaskParameter="DestinationFiles" ItemName="DestinationFiles" />
<Output TaskParameter="CopiedFiles" PropertyName="CopiedFiles" />
<Output TaskParameter="CopiedFiles" ItemName="CopiedFiles" />
</Copy>
</Target>
<Target Name="signalrclient_uwp_inittarget" Condition="'$(DisableUwp)' == ''">
<ItemGroup Label="x64 and #Toolset# and Debug" Condition="'$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) &gt; -1">
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.dll" />
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.pdb" />
</ItemGroup>
<ItemGroup Label="x64 and #Toolset# and Release" Condition="'$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.dll" />
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.pdb" />
</ItemGroup>
<ItemGroup Label="Win32 and #Toolset# and Debug" Condition="'$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) &gt; -1">
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.dll" />
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.pdb" />
</ItemGroup>
<ItemGroup Label="Win32 and #Toolset# and Release" Condition="'$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.dll" />
<ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.pdb" />
</ItemGroup>
</Target>
</Project>

View File

@ -1,82 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="signalrclient_inittarget">
<PropertyGroup Condition="'$(ApplicationType)' != ''">
<DisableDesktop>True</DisableDesktop>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(DisableDesktop)' == ''">
<ClCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<ResourceCompile>
<AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="x64 and #Toolset# and Release" Condition="'$(DisableDesktop)' == '' And '$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
<Link>
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\x64\#Toolset#\Release\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="x64 and #Toolset# and Debug" Condition="'$(DisableDesktop)' == '' And '$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) &gt; -1">
<Link>
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\x64\#Toolset#\Debug\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="Win32 and #Toolset# and Release" Condition="'$(DisableDesktop)' == '' And '$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
<Link>
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\Win32\#Toolset#\Release\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Label="Win32 and #Toolset# and Debug" Condition="'$(DisableDesktop)' == '' And '$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) &gt; -1">
<Link>
<AdditionalDependencies>$(MSBuildThisFileDirectory)lib\Win32\#Toolset#\Debug\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Target Name="signalrclient_AfterBuild" AfterTargets="AfterBuild" Condition="'$(DisableDesktop)' == ''">
<PropertyGroup>
<UseHardlinksIfPossible Condition="'$(UseHardlinksIfPossible)' == ''">true</UseHardlinksIfPossible>
</PropertyGroup>
<Copy DestinationFolder="$(TargetDir)" SourceFiles="@(CopyToOutput)" SkipUnchangedFiles="true" UseHardlinksIfPossible="$(UseHardlinksIfPossible)">
<Output TaskParameter="DestinationFiles" PropertyName="DestinationFiles" />
<Output TaskParameter="DestinationFiles" ItemName="DestinationFiles" />
<Output TaskParameter="CopiedFiles" PropertyName="CopiedFiles" />
<Output TaskParameter="CopiedFiles" ItemName="CopiedFiles" />
</Copy>
</Target>
<Target Name="signalrclient_inittarget" Condition="'$(DisableDesktop)' == ''">
<ItemGroup Label="x64 and #Toolset# and Debug" Condition="'$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) &gt; -1">
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.dll" />
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.pdb" />
<None Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.dll">
<DeploymentContent>true</DeploymentContent>
</None>
</ItemGroup>
<ItemGroup Label="x64 and #Toolset# and Release" Condition="'$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.dll" />
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.pdb" />
<None Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.dll">
<DeploymentContent>true</DeploymentContent>
</None>
</ItemGroup>
<ItemGroup Label="Win32 and #Toolset# and Debug" Condition="'$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) &gt; -1">
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.dll" />
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.pdb" />
<None Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.dll">
<DeploymentContent>true</DeploymentContent>
</None>
</ItemGroup>
<ItemGroup Label="Win32 and #Toolset# and Release" Condition="'$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1">
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.dll" />
<CopyToOutput Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.pdb" />
<None Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.dll">
<DeploymentContent>true</DeploymentContent>
</None>
</ItemGroup>
</Target>
</Project>

View File

@ -1,21 +0,0 @@
<?xml version="1.0"?>
<package>
<metadata>
<id>Microsoft.AspNet.SignalR.Client.Cpp.#Toolset#.#SubSystem#</id>
<title>Microsoft ASP.NET SignalR C++ Client</title>
<version>0.0.0</version>
<authors>Microsoft</authors>
<owners>Microsoft</owners>
<licenseUrl>http://www.microsoft.com/web/webpi/eula/net_library_eula_ENU.htm</licenseUrl>
<copyright>© Microsoft Corporation. All rights reserved.</copyright>
<projectUrl>http://www.asp.net/signalr</projectUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<description>C++ client for ASP.NET SignalR.</description>
<language>en-US</language>
<tags>Microsoft AspNet SignalR AspNetSignalR Client C++ native</tags>
<releaseNotes>https://github.com/aspnet/SignalR-Client-Cpp/releases</releaseNotes>
<dependencies>
<dependency id="cpprestsdk.#Toolset#.#casablanca-subsystem#.msvcstl.dyn.rt-dyn" version="2.9.1" />
</dependencies>
</metadata>
</package>

View File

@ -1,6 +0,0 @@
ASP.NET Core SignalR C++ Client
========
This folder contains a C++ client for ASP.NET Core SignalR.
**There are no plans to ship this client at this time.**

View File

@ -1 +0,0 @@
msbuild "%~dp0\Build\build.msbuild" /v:minimal /maxcpucount /nodeReuse:false %*

View File

@ -1,14 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#ifdef NO_SIGNALRCLIENT_EXPORTS
#define SIGNALRCLIENT_API
#else
#ifdef SIGNALRCLIENT_EXPORTS
#define SIGNALRCLIENT_API __declspec(dllexport)
#else
#define SIGNALRCLIENT_API __declspec(dllimport)
#endif // SIGNALRCLIENT_EXPORTS
#endif // NO_SIGNALRCLIENT_EXPORTS

View File

@ -1,52 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include "_exports.h"
#include <memory>
#include <functional>
#include "connection_state.h"
#include "trace_level.h"
#include "log_writer.h"
#include "signalr_client_config.h"
namespace signalr
{
class connection_impl;
class connection
{
public:
typedef std::function<void __cdecl(const std::string&)> message_received_handler;
SIGNALRCLIENT_API explicit connection(const std::string& url, trace_level trace_level = trace_level::all, std::shared_ptr<log_writer> log_writer = nullptr);
SIGNALRCLIENT_API ~connection();
connection(const connection&) = delete;
connection& operator=(const connection&) = delete;
SIGNALRCLIENT_API void __cdecl start(std::function<void(std::exception_ptr)> callback) noexcept;
SIGNALRCLIENT_API void __cdecl send(const std::string& data, std::function<void(std::exception_ptr)> callback) noexcept;
SIGNALRCLIENT_API void __cdecl set_message_received(const message_received_handler& message_received_callback);
SIGNALRCLIENT_API void __cdecl set_disconnected(const std::function<void __cdecl()>& disconnected_callback);
SIGNALRCLIENT_API void __cdecl set_client_config(const signalr_client_config& config);
SIGNALRCLIENT_API void __cdecl stop(std::function<void(std::exception_ptr)> callback) noexcept;
SIGNALRCLIENT_API connection_state __cdecl get_connection_state() const noexcept;
SIGNALRCLIENT_API std::string __cdecl get_connection_id() const;
private:
// The recommended smart pointer to use when doing pImpl is the `std::unique_ptr`. However
// we are capturing the m_pImpl instance in the lambdas used by tasks which can outlive
// the connection instance. Using `std::shared_ptr` guarantees that we won't be using
// a deleted object if the task is run after the `connection` instance goes away.
std::shared_ptr<connection_impl> m_pImpl;
};
}

View File

@ -1,15 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
namespace signalr
{
enum class connection_state
{
connecting,
connected,
disconnecting,
disconnected
};
}

View File

@ -1,54 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include <string>
#include <functional>
#include <map>
#include <chrono>
namespace signalr
{
enum class http_method
{
GET,
POST
};
class http_request
{
public:
http_method method;
std::map<std::string, std::string> headers;
std::string content;
std::chrono::seconds timeout;
};
class http_response
{
public:
http_response() {}
http_response(http_response&& rhs) noexcept : status_code(rhs.status_code), content(std::move(rhs.content)) {}
http_response(int code, const std::string& content) : status_code(code), content(content) {}
http_response& operator=(http_response&& rhs)
{
status_code = rhs.status_code;
content = std::move(rhs.content);
return *this;
}
int status_code = 0;
std::string content;
};
class http_client
{
public:
virtual void send(std::string url, http_request request, std::function<void(http_response, std::exception_ptr)> callback) = 0;
virtual ~http_client() {}
};
}

View File

@ -1,52 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include "_exports.h"
#include <memory>
#include <functional>
#include "cpprest/json.h"
#include "connection_state.h"
#include "trace_level.h"
#include "log_writer.h"
#include "signalr_client_config.h"
namespace signalr
{
class hub_connection_impl;
class hub_connection
{
public:
typedef std::function<void __cdecl (const web::json::value&)> method_invoked_handler;
SIGNALRCLIENT_API explicit hub_connection(const std::string& url, trace_level trace_level = trace_level::all,
std::shared_ptr<log_writer> log_writer = nullptr);
SIGNALRCLIENT_API ~hub_connection();
hub_connection(const hub_connection&) = delete;
hub_connection& operator=(const hub_connection&) = delete;
SIGNALRCLIENT_API void __cdecl start(std::function<void(std::exception_ptr)> callback) noexcept;
SIGNALRCLIENT_API void __cdecl stop(std::function<void(std::exception_ptr)> callback) noexcept;
SIGNALRCLIENT_API connection_state __cdecl get_connection_state() const;
SIGNALRCLIENT_API std::string __cdecl get_connection_id() const;
SIGNALRCLIENT_API void __cdecl set_disconnected(const std::function<void __cdecl()>& disconnected_callback);
SIGNALRCLIENT_API void __cdecl set_client_config(const signalr_client_config& config);
SIGNALRCLIENT_API void __cdecl on(const std::string& event_name, const method_invoked_handler& handler);
SIGNALRCLIENT_API void invoke(const std::string& method_name, const web::json::value& arguments = web::json::value::array(), std::function<void(const web::json::value&, std::exception_ptr)> callback = [](const web::json::value&, std::exception_ptr) {}) noexcept;
SIGNALRCLIENT_API void send(const std::string& method_name, const web::json::value& arguments = web::json::value::array(), std::function<void(std::exception_ptr)> callback = [](std::exception_ptr) {}) noexcept;
private:
std::shared_ptr<hub_connection_impl> m_pImpl;
};
}

View File

@ -1,18 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include <stdexcept>
#include "signalr_exception.h"
namespace signalr
{
class hub_exception : public signalr_exception
{
public:
hub_exception(const std::string &what)
: signalr_exception(what)
{}
};
}

View File

@ -1,14 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
namespace signalr
{
class log_writer
{
public:
// NOTE: the caller does not enforce thread safety of this call
virtual void __cdecl write(const std::string &entry) = 0;
};
}

View File

@ -1,36 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include "cpprest/http_client.h"
#include "cpprest/ws_client.h"
#include "_exports.h"
namespace signalr
{
class signalr_client_config
{
public:
SIGNALRCLIENT_API void __cdecl set_proxy(const web::web_proxy &proxy);
// Please note that setting credentials does not work in all cases.
// For example, Basic Authentication fails under Win32.
// As a workaround, you can set the required authorization headers directly
// using signalr_client_config::set_http_headers
SIGNALRCLIENT_API void __cdecl set_credentials(const web::credentials &credentials);
SIGNALRCLIENT_API web::http::client::http_client_config __cdecl get_http_client_config() const;
SIGNALRCLIENT_API void __cdecl set_http_client_config(const web::http::client::http_client_config& http_client_config);
SIGNALRCLIENT_API web::websockets::client::websocket_client_config __cdecl get_websocket_client_config() const noexcept;
SIGNALRCLIENT_API void __cdecl set_websocket_client_config(const web::websockets::client::websocket_client_config& websocket_client_config);
SIGNALRCLIENT_API web::http::http_headers __cdecl get_http_headers() const noexcept;
SIGNALRCLIENT_API void __cdecl set_http_headers(const web::http::http_headers& http_headers);
private:
web::http::client::http_client_config m_http_client_config;
web::websockets::client::websocket_client_config m_websocket_client_config;
web::http::http_headers m_http_headers;
};
}

View File

@ -1,17 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include <stdexcept>
namespace signalr
{
class signalr_exception : public std::runtime_error
{
public:
explicit signalr_exception(const std::string &what)
: runtime_error(what)
{}
};
}

View File

@ -1,28 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
namespace signalr
{
enum class trace_level : int
{
none = 0,
messages = 1,
events = 2,
state_changes = 4,
errors = 8,
info = 16,
all = messages | events | state_changes | errors | info
};
inline trace_level operator|(trace_level lhs, trace_level rhs) noexcept
{
return static_cast<trace_level>(static_cast<int>(lhs) | static_cast<int>(rhs));
}
inline trace_level operator&(trace_level lhs, trace_level rhs) noexcept
{
return static_cast<trace_level>(static_cast<int>(lhs) & static_cast<int>(rhs));
}
}

View File

@ -1,13 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
namespace signalr
{
enum class transfer_format
{
text,
binary
};
}

View File

@ -1,13 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
namespace signalr
{
enum class transport_type
{
long_polling,
websockets
};
}

View File

@ -1,25 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include <stdexcept>
namespace signalr
{
class web_exception : public std::runtime_error
{
public:
web_exception(const std::string &what, unsigned short status_code)
: runtime_error(what), m_status_code(status_code)
{}
unsigned short status_code() const noexcept
{
return m_status_code;
}
private:
unsigned short m_status_code;
};
}

View File

@ -1,23 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include "transfer_format.h"
namespace signalr
{
class websocket_client
{
public:
virtual ~websocket_client() {};
virtual void start(std::string url, transfer_format format, std::function<void(std::exception_ptr)> callback) = 0;
virtual void stop(std::function<void(std::exception_ptr)> callback) = 0;
virtual void send(std::string payload, std::function<void(std::exception_ptr)> callback) = 0;
virtual void receive(std::function<void(std::string, std::exception_ptr)> callback) = 0;
};
}

View File

@ -1,63 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 16.0.0.0
MinimumVisualStudioVersion = 16.0.0.0
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PersistentConnectionSample", "samples\PersistentConnectionSample\PersistentConnectionSample.vcxproj", "{BD075706-11E9-403B-A2E3-A5E1397E53EF}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HubConnectionSample", "samples\HubConnectionSample\HubConnectionSample.vcxproj", "{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SignalRServer", "samples\SignalRServer\SignalRServer.csproj", "{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{4AA7C02A-A2E9-4E22-A026-B43D623C272F}"
ProjectSection(SolutionItems) = preProject
.nuget\NuGet.Config = .nuget\NuGet.Config
.nuget\NuGet.exe = .nuget\NuGet.exe
.nuget\NuGet.targets = .nuget\NuGet.targets
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Any CPU.ActiveCfg = Debug|Win32
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Win32.ActiveCfg = Debug|Win32
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Win32.Build.0 = Debug|Win32
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Any CPU.ActiveCfg = Release|Win32
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Mixed Platforms.Build.0 = Release|Win32
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Win32.ActiveCfg = Release|Win32
{BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Win32.Build.0 = Release|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Any CPU.ActiveCfg = Debug|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Win32.ActiveCfg = Debug|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Win32.Build.0 = Debug|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Any CPU.ActiveCfg = Release|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Mixed Platforms.Build.0 = Release|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Win32.ActiveCfg = Release|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Win32.Build.0 = Release|Win32
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Win32.ActiveCfg = Debug|Any CPU
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Any CPU.Build.0 = Release|Any CPU
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Win32.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -1,112 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include <iostream>
#include <sstream>
#include "hub_connection.h"
#include "log_writer.h"
#include <future>
class logger : public signalr::log_writer
{
// Inherited via log_writer
virtual void __cdecl write(const std::string & entry) override
{
//std::cout << utility::conversions::to_utf8string(entry) << std::endl;
}
};
void send_message(signalr::hub_connection& connection, const std::string& message)
{
web::json::value args{};
args[0] = web::json::value(utility::conversions::to_string_t(message));
// if you get an internal compiler error uncomment the lambda below or install VS Update 4
connection.invoke("Send", args, [](const web::json::value& value, std::exception_ptr exception)
{
try
{
if (exception)
{
std::rethrow_exception(exception);
}
ucout << U("Received: ") << value.serialize() << std::endl;
}
catch (const std::exception &e)
{
ucout << U("Error while sending data: ") << e.what() << std::endl;
}
});
}
void chat()
{
signalr::hub_connection connection("http://localhost:5000/default", signalr::trace_level::all, std::make_shared<logger>());
connection.on("Send", [](const web::json::value & m)
{
ucout << std::endl << m.at(0).as_string() << /*U(" wrote:") << m.at(1).as_string() <<*/ std::endl << U("Enter your message: ");
});
std::promise<void> task;
connection.start([&connection, &task](std::exception_ptr exception)
{
if (exception)
{
try
{
std::rethrow_exception(exception);
}
catch (const std::exception & ex)
{
ucout << U("exception when starting connection: ") << ex.what() << std::endl;
}
task.set_value();
return;
}
ucout << U("Enter your message:");
for (;;)
{
std::string message;
std::getline(std::cin, message);
if (message == ":q")
{
break;
}
send_message(connection, message);
}
connection.stop([&task](std::exception_ptr exception)
{
try
{
if (exception)
{
std::rethrow_exception(exception);
}
ucout << U("connection stopped successfully") << std::endl;
}
catch (const std::exception & e)
{
ucout << U("exception when stopping connection: ") << e.what() << std::endl;
}
task.set_value();
});
});
task.get_future().get();
}
int main()
{
chat();
return 0;
}

View File

@ -1,118 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\Build\SignalRClient.Build.Settings" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>HubConnectionSample</RootNamespace>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe>
<RestorePackages>true</RestorePackages>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
<Import Project="..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include\signalrclient;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>
</AdditionalLibraryDirectories>
<AdditionalDependencies>$(MSBuildThisFileDirectory)..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\lib\native\v140\windesktop\msvcstl\dyn\rt-dyn\x86\Debug\cpprest140d_2_9.lib;$(MSBuildThisFileDirectory)..\..\bin\Desktop\Win32\Debug\dll\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\include\signalrclient;$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="HubConnectionSample.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\signalrclient\Build\VS\signalrclient.vcxproj">
<Project>{87ed3ad4-d820-48cd-8382-a12564213a12}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
</Target>
<Target Name="AfterBuild">
<Exec Command="copy /y &quot;$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\dll\$(SignalrClientTargetName).dll&quot; &quot;$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\$(SignalrClientTargetName).dll&quot;" />
<Exec Command="copy /y &quot;$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\dll\$(SignalrClientTargetName).pdb&quot; &quot;$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\$(SignalrClientTargetName).pdb&quot;" />
</Target>
</Project>

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="HubConnectionSample.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" version="2.9.1" targetFramework="native" />
</packages>

View File

@ -1,4 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"

View File

@ -1,4 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once

View File

@ -1,64 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "signalrclient\connection.h"
#include <iostream>
void send_message(signalr::connection &connection, const utility::string_t& message)
{
connection.send(message)
.then([](pplx::task<void> send_task) // fire and forget but we need to observe exceptions
{
try
{
send_task.get();
}
catch (const std::exception &e)
{
ucout << U("Error while sending data: ") << e.what();
}
});
}
int main()
{
signalr::connection connection{ U("http://localhost:34281/echo") };
connection.set_message_received([](const utility::string_t& m)
{
ucout << U("Message received:") << m << std::endl << U("Enter message: ");
});
connection.start()
.then([&connection]() // fine to capture by reference - we are blocking so it is guaranteed to be valid
{
for (;;)
{
utility::string_t message;
std::getline(ucin, message);
if (message == U(":q"))
{
break;
}
send_message(connection, message);
}
return connection.stop();
})
.then([](pplx::task<void> stop_task)
{
try
{
stop_task.get();
ucout << U("connection stopped successfully") << std::endl;
}
catch (const std::exception &e)
{
ucout << U("exception when starting or closing connection: ") << e.what() << std::endl;
}
}).get();
return 0;
}

View File

@ -1,109 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{BD075706-11E9-403B-A2E3-A5E1397E53EF}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>PersistentConnectionSample</RootNamespace>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe>
<RestorePackages>true</RestorePackages>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>Use</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="PersistentConnectionSample.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Import Project="..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.7.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.7.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" />
<Import Project="..\..\packages\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.1.0.0-beta1\build\native\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.targets" Condition="Exists('..\..\packages\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.1.0.0-beta1\build\native\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
<Error Condition="!Exists('..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.7.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.7.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.1.0.0-beta1\build\native\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.1.0.0-beta1\build\native\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.targets'))" />
</Target>
</Project>

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="PersistentConnectionSample.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" version="2.7.0" targetFramework="native" />
<package id="Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop" version="1.0.0-beta1" targetFramework="native" />
</packages>

View File

@ -1,4 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"

View File

@ -1,4 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once

View File

@ -1,20 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace SignalRServer
{
public class ChatHub : Hub
{
public void Send(string name, string message)
{
// Call the broadcastMessage method to update clients.
Clients.All.broadcastMessage(name, message);
}
}
}

View File

@ -1,21 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
namespace SignalRServer
{
public class EchoConnection : PersistentConnection
{
protected override Task OnConnected(IRequest request, string connectionId)
{
return Connection.Send(connectionId, "Welcome!");
}
protected override Task OnReceived(IRequest request, string connectionId, string data)
{
return Connection.Broadcast(data);
}
}
}

View File

@ -1,35 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SignalRServer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SignalRServer")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("64b40dbb-f6c1-45b4-8fc4-764526e9f16c")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,153 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}</ProjectGuid>
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SignalRServer</RootNamespace>
<AssemblyName>SignalRServer</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<UseIISExpress>true</UseIISExpress>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe>
<RestorePackages>true</RestorePackages>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.AspNet.SignalR.Core">
<HintPath>..\..\packages\Microsoft.AspNet.SignalR.Core.2.2.0\lib\net45\Microsoft.AspNet.SignalR.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AspNet.SignalR.SystemWeb">
<HintPath>..\..\packages\Microsoft.AspNet.SignalR.SystemWeb.2.2.0\lib\net45\Microsoft.AspNet.SignalR.SystemWeb.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Host.SystemWeb">
<HintPath>..\..\packages\Microsoft.Owin.Host.SystemWeb.3.0.0\lib\net45\Microsoft.Owin.Host.SystemWeb.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security">
<HintPath>..\..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Owin">
<HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
</Reference>
<Reference Include="System.Web.DynamicData" />
<Reference Include="System.Web.Entity" />
<Reference Include="System.Web.ApplicationServices" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Core" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
</ItemGroup>
<ItemGroup>
<Content Include="packages.config" />
<Content Include="Scripts\jquery-1.10.2.min.map" />
<None Include="Web.Debug.config">
<DependentUpon>Web.config</DependentUpon>
</None>
<None Include="Web.Release.config">
<DependentUpon>Web.config</DependentUpon>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Scripts\jquery-1.10.2.intellisense.js" />
<Content Include="index.html" />
<Content Include="Scripts\jquery-1.10.2.js" />
<Content Include="Scripts\jquery-1.10.2.min.js" />
<Content Include="Scripts\jquery.signalR-2.2.0.js" />
<Content Include="Scripts\jquery.signalR-2.2.0.min.js" />
<Content Include="Web.config" />
</ItemGroup>
<ItemGroup>
<Compile Include="ChatHub.cs" />
<Compile Include="EchoConnection.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Startup.cs" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
<WebProjectProperties>
<UseIIS>True</UseIIS>
<AutoAssignPort>True</AutoAssignPort>
<DevelopmentServerPort>34281</DevelopmentServerPort>
<DevelopmentServerVPath>/</DevelopmentServerVPath>
<IISUrl>http://localhost:34281/</IISUrl>
<NTLMAuthentication>False</NTLMAuthentication>
<UseCustomServer>False</UseCustomServer>
<CustomServerUrl>
</CustomServerUrl>
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
</VisualStudio>
</ProjectExtensions>
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -1,21 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalRServer.Startup))]
namespace SignalRServer
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
app.MapSignalR<EchoConnection>("/echo");
}
}
}

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an attribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
</configuration>

View File

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<!--
In the example below, the "SetAttributes" transform will change the value of
"connectionString" to use "ReleaseSQLServer" only when the "Match" locator
finds an attribute "name" that has a value of "MyDB".
<connectionStrings>
<add name="MyDB"
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
</connectionStrings>
-->
<system.web>
<compilation xdt:Transform="RemoveAttributes(debug)" />
<!--
In the example below, the "Replace" transform will replace the entire
<customErrors> section of your web.config file.
Note that because there is only one customErrors section under the
<system.web> node, there is no need to use the "xdt:Locator" attribute.
<customErrors defaultRedirect="GenericError.htm"
mode="RemoteOnly" xdt:Transform="Replace">
<error statusCode="500" redirect="InternalError.htm"/>
</customErrors>
-->
</system.web>
</configuration>

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=169433
-->
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
</system.web>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -1,58 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>SignalR Simple Chat</title>
<style type="text/css">
.container {
background-color: #99CCFF;
border: thick solid #808080;
padding: 20px;
margin: 20px;
}
</style>
</head>
<body>
<div class="container">
<input type="text" id="message" />
<input type="button" id="sendmessage" value="Send" />
<input type="hidden" id="displayname" />
<ul id="discussion"></ul>
</div>
<!--Script references. -->
<!--Reference the jQuery library. -->
<script src="Scripts/jquery-1.10.2.min.js"></script>
<!--Reference the SignalR library. -->
<script src="Scripts/jquery.signalR-2.2.0.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="signalr/hubs"></script>
<!--Add script to update the page and send messages.-->
<script type="text/javascript">
$(function () {
// Declare a proxy to reference the hub.
var chat = $.connection.chatHub;
// Create a function that the hub can call to broadcast messages.
chat.client.broadcastMessage = function (name, message) {
// Html encode display name and message.
var encodedName = $('<div />').text(name).html();
var encodedMsg = $('<div />').text(message).html();
// Add the message to the page.
$('#discussion').append('<li><strong>' + encodedName
+ '</strong>:&nbsp;&nbsp;' + encodedMsg + '</li>');
};
// Get the user name and store it to prepend to messages.
$('#displayname').val(prompt('Enter your name:', ''));
// Set initial focus to message input box.
$('#message').focus();
// Start the connection.
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send($('#displayname').val(), $('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
});
</script>
</body>
</html>

View File

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="jQuery" version="1.10.2" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR" version="2.2.0" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR.Core" version="2.2.0" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR.JS" version="2.2.0" targetFramework="net45" />
<package id="Microsoft.AspNet.SignalR.SystemWeb" version="2.2.0" targetFramework="net45" />
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.0" targetFramework="net45" />
<package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" />
<package id="Owin" version="1.0" targetFramework="net45" />
</packages>

View File

@ -1,144 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.0.0
MinimumVisualStudioVersion = 16.0.0.0
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "signalrclient", "src\signalrclient\Build\VS\signalrclient.vcxproj", "{87ED3AD4-D820-48CD-8382-A12564213A12}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "signalrclienttests", "test\signalrclienttests\Build\VS\signalrclienttests.vcxproj", "{10376148-BCF4-4B55-98A5-3C98C87FD898}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "signalrclientdll", "src\signalrclientdll\Build\VS\signalrclientdll.vcxproj", "{18377AE8-E372-40CE-94FD-7F65008D39A3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{AABF08B1-12A4-4D06-A188-F01FBF8A9658}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "signalrclient-e2e-tests", "test\signalrclient-e2e-tests\Build\VS\signalrclient-e2e-tests.vcxproj", "{6006C96A-29F0-4B18-8DDD-764DC3419E2F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "signalrclient-testhost", "test\signalrclient-testhost\signalrclient-testhost.csproj", "{11848039-1F13-4047-9539-8F9F45930788}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HubConnectionSample", "samples\HubConnectionSample\HubConnectionSample.vcxproj", "{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}"
ProjectSection(ProjectDependencies) = postProject
{18377AE8-E372-40CE-94FD-7F65008D39A3} = {18377AE8-E372-40CE-94FD-7F65008D39A3}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "test\gtest\gtest.vcxproj", "{CAC1267B-8778-4257-AAC6-CAF481723B01}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|Any CPU.ActiveCfg = Debug|Win32
{87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|Win32.ActiveCfg = Debug|Win32
{87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|Win32.Build.0 = Debug|Win32
{87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|x64.ActiveCfg = Debug|x64
{87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|x64.Build.0 = Debug|x64
{87ED3AD4-D820-48CD-8382-A12564213A12}.Release|Any CPU.ActiveCfg = Release|Win32
{87ED3AD4-D820-48CD-8382-A12564213A12}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{87ED3AD4-D820-48CD-8382-A12564213A12}.Release|Mixed Platforms.Build.0 = Release|Win32
{87ED3AD4-D820-48CD-8382-A12564213A12}.Release|Win32.ActiveCfg = Release|Win32
{87ED3AD4-D820-48CD-8382-A12564213A12}.Release|Win32.Build.0 = Release|Win32
{87ED3AD4-D820-48CD-8382-A12564213A12}.Release|x64.ActiveCfg = Release|x64
{87ED3AD4-D820-48CD-8382-A12564213A12}.Release|x64.Build.0 = Release|x64
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|Any CPU.ActiveCfg = Debug|Win32
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|Win32.ActiveCfg = Debug|Win32
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|Win32.Build.0 = Debug|Win32
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|x64.ActiveCfg = Debug|x64
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|x64.Build.0 = Debug|x64
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|Any CPU.ActiveCfg = Release|Win32
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|Mixed Platforms.Build.0 = Release|Win32
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|Win32.ActiveCfg = Release|Win32
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|Win32.Build.0 = Release|Win32
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|x64.ActiveCfg = Release|x64
{10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|x64.Build.0 = Release|x64
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|Any CPU.ActiveCfg = Debug|Win32
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|Win32.ActiveCfg = Debug|Win32
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|Win32.Build.0 = Debug|Win32
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|x64.ActiveCfg = Debug|x64
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|x64.Build.0 = Debug|x64
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|Any CPU.ActiveCfg = Release|Win32
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|Mixed Platforms.Build.0 = Release|Win32
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|Win32.ActiveCfg = Release|Win32
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|Win32.Build.0 = Release|Win32
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|x64.ActiveCfg = Release|x64
{18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|x64.Build.0 = Release|x64
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|Any CPU.ActiveCfg = Debug|Win32
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|Win32.ActiveCfg = Debug|Win32
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|Win32.Build.0 = Debug|Win32
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|x64.ActiveCfg = Debug|x64
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|x64.Build.0 = Debug|x64
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|Any CPU.ActiveCfg = Release|Win32
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|Mixed Platforms.Build.0 = Release|Win32
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|Win32.ActiveCfg = Release|Win32
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|Win32.Build.0 = Release|Win32
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|x64.ActiveCfg = Release|x64
{6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|x64.Build.0 = Release|x64
{11848039-1F13-4047-9539-8F9F45930788}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11848039-1F13-4047-9539-8F9F45930788}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11848039-1F13-4047-9539-8F9F45930788}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{11848039-1F13-4047-9539-8F9F45930788}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{11848039-1F13-4047-9539-8F9F45930788}.Debug|Win32.ActiveCfg = Debug|Any CPU
{11848039-1F13-4047-9539-8F9F45930788}.Debug|x64.ActiveCfg = Debug|Any CPU
{11848039-1F13-4047-9539-8F9F45930788}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11848039-1F13-4047-9539-8F9F45930788}.Release|Any CPU.Build.0 = Release|Any CPU
{11848039-1F13-4047-9539-8F9F45930788}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{11848039-1F13-4047-9539-8F9F45930788}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{11848039-1F13-4047-9539-8F9F45930788}.Release|Win32.ActiveCfg = Release|Any CPU
{11848039-1F13-4047-9539-8F9F45930788}.Release|x64.ActiveCfg = Release|Any CPU
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Any CPU.ActiveCfg = Debug|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Win32.ActiveCfg = Debug|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Win32.Build.0 = Debug|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|x64.ActiveCfg = Debug|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Any CPU.ActiveCfg = Release|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Mixed Platforms.Build.0 = Release|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Win32.ActiveCfg = Release|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Win32.Build.0 = Release|Win32
{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|x64.ActiveCfg = Release|Win32
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|Any CPU.ActiveCfg = Debug|Win32
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|Mixed Platforms.Build.0 = Debug|Win32
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|Win32.ActiveCfg = Debug|Win32
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|Win32.Build.0 = Debug|Win32
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|x64.ActiveCfg = Debug|x64
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|x64.Build.0 = Debug|x64
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|Any CPU.ActiveCfg = Release|Win32
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|Mixed Platforms.ActiveCfg = Release|Win32
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|Mixed Platforms.Build.0 = Release|Win32
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|Win32.ActiveCfg = Release|Win32
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|Win32.Build.0 = Release|Win32
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|x64.ActiveCfg = Release|x64
{CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{10376148-BCF4-4B55-98A5-3C98C87FD898} = {AABF08B1-12A4-4D06-A188-F01FBF8A9658}
{6006C96A-29F0-4B18-8DDD-764DC3419E2F} = {AABF08B1-12A4-4D06-A188-F01FBF8A9658}
{11848039-1F13-4047-9539-8F9F45930788} = {AABF08B1-12A4-4D06-A188-F01FBF8A9658}
{CAC1267B-8778-4257-AAC6-CAF481723B01} = {AABF08B1-12A4-4D06-A188-F01FBF8A9658}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0286287F-3519-42E6-9165-FB342028F9FF}
EndGlobalSection
EndGlobal

View File

@ -1,112 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\Build\SignalRClient.Build.Settings" />
<PropertyGroup Label="Globals">
<ProjectGuid>{87ED3AD4-D820-48CD-8382-A12564213A12}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>signalr</RootNamespace>
<ProjectName>signalrclient</ProjectName>
<TargetName>$(SignalrClientTargetName)</TargetName>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\..\</SolutionDir>
<OutDir Condition="'$(OutDir)' == ''">$(SolutionDir)$(Configuration)\</OutDir>
<OutDir>$(OutDir)lib\</OutDir>
<IntDir>$(Configuration)\lib\</IntDir>
<ConfigurationType>StaticLibrary</ConfigurationType>
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="..\..\..\..\Build\Config.Definitions.props" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformToolset>v141</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup>
<ClCompile>
<PreprocessorDefinitions>_WINDOWS;_USRDLL;NO_SIGNALRCLIENT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\include\signalrclient\connection.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\connection_state.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\http_client.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\hub_connection.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\hub_exception.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\log_writer.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\signalr_client_config.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\signalr_exception.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\trace_level.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\transfer_format.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\transport_type.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\websocket_client.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\web_exception.h" />
<ClInclude Include="..\..\..\..\include\signalrclient\_exports.h" />
<ClInclude Include="..\..\case_insensitive_comparison_utils.h" />
<ClInclude Include="..\..\connection_impl.h" />
<ClInclude Include="..\..\constants.h" />
<ClInclude Include="..\..\default_http_client.h" />
<ClInclude Include="..\..\default_websocket_client.h" />
<ClInclude Include="..\..\event.h" />
<ClInclude Include="..\..\http_sender.h" />
<ClInclude Include="..\..\hub_connection_impl.h" />
<ClInclude Include="..\..\callback_manager.h" />
<ClInclude Include="..\..\logger.h" />
<ClInclude Include="..\..\negotiation_response.h" />
<ClInclude Include="..\..\negotiate.h" />
<ClInclude Include="..\..\stdafx.h" />
<ClInclude Include="..\..\trace_log_writer.h" />
<ClInclude Include="..\..\transport.h" />
<ClInclude Include="..\..\transport_factory.h" />
<ClInclude Include="..\..\url_builder.h" />
<ClInclude Include="..\..\websocket_transport.h" />
<ClInclude Include="..\..\web_request.h" />
<ClInclude Include="..\..\web_request_factory.h" />
<ClInclude Include="..\..\web_response.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\connection.cpp" />
<ClCompile Include="..\..\connection_impl.cpp" />
<ClCompile Include="..\..\default_http_client.cpp" />
<ClCompile Include="..\..\http_sender.cpp" />
<ClCompile Include="..\..\hub_connection.cpp" />
<ClCompile Include="..\..\hub_connection_impl.cpp" />
<ClCompile Include="..\..\callback_manager.cpp" />
<ClCompile Include="..\..\logger.cpp" />
<ClCompile Include="..\..\negotiate.cpp" />
<ClCompile Include="..\..\signalr_client_config.cpp" />
<ClCompile Include="..\..\stdafx.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="..\..\trace_log_writer.cpp" />
<ClCompile Include="..\..\transport.cpp" />
<ClCompile Include="..\..\transport_factory.cpp" />
<ClCompile Include="..\..\url_builder.cpp" />
<ClCompile Include="..\..\default_websocket_client.cpp" />
<ClCompile Include="..\..\websocket_transport.cpp" />
<ClCompile Include="..\..\web_request.cpp" />
<ClCompile Include="..\..\web_request_factory.cpp" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="cpprestsdk" Version="2.9.1.1" />
<PackageReference Include="cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn" Version="2.9.1" />
<PackageReference Include="cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn" Version="2.9.1" />
<PackageReference Include="cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn" Version="2.9.1" />
<PackageReference Include="cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn" Version="2.9.1" />
<PackageReference Include="cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn" Version="2.9.1" />
<PackageReference Include="cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn" Version="2.9.1" />
<PackageReference Include="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" Version="2.9.1" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

View File

@ -1,183 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\connection.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\_exports.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\transport_type.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\trace_level.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\url_builder.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\constants.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\http_sender.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\web_exception.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\negotiation_response.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\websocket_transport.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\connection_impl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\connection_state.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\default_websocket_client.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\log_writer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\logger.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\trace_log_writer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\transport_factory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\web_request_factory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\transport.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\web_response.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\web_request.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\hub_connection_impl.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\callback_manager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\hub_exception.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\hub_connection.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\case_insensitive_comparison_utils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\event.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\signalr_exception.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\signalr_client_config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\default_http_client.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\negotiate.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\http_client.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\transfer_format.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\..\include\signalrclient\websocket_client.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\url_builder.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\web_request.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\connection_impl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\http_sender.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\connection.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\transport_factory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\web_request_factory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\default_websocket_client.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\websocket_transport.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\logger.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\transport.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\hub_connection_impl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\callback_manager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\hub_connection.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\trace_log_writer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\signalr_client_config.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\default_http_client.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\negotiate.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -1,26 +0,0 @@
set (SOURCES
callback_manager.cpp
connection.cpp
connection_impl.cpp
default_websocket_client.cpp
http_sender.cpp
hub_connection.cpp
hub_connection_impl.cpp
logger.cpp
request_sender.cpp
signalr_client_config.cpp
stdafx.cpp
trace_log_writer.cpp
transport.cpp
transport_factory.cpp
url_builder.cpp
web_request.cpp
web_request_factory.cpp
websocket_transport.cpp
)
add_library (signalrclient SHARED ${SOURCES})
target_link_libraries(signalrclient ${CPPREST_SO})

View File

@ -1,91 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "callback_manager.h"
namespace signalr
{
// dtor_clear_arguments will be passed when closing any pending callbacks when the `callback_manager` is
// destroyed (i.e. in the dtor)
callback_manager::callback_manager(const web::json::value& dtor_clear_arguments)
: m_dtor_clear_arguments(dtor_clear_arguments)
{ }
callback_manager::~callback_manager()
{
clear(m_dtor_clear_arguments);
}
// note: callback must not throw except for the `on_progress` callback which will never be invoked from the dtor
std::string callback_manager::register_callback(const std::function<void(const web::json::value&)>& callback)
{
auto callback_id = get_callback_id();
{
std::lock_guard<std::mutex> lock(m_map_lock);
m_callbacks.insert(std::make_pair(callback_id, callback));
}
return callback_id;
}
// invokes a callback and stops tracking it if remove callback set to true
bool callback_manager::invoke_callback(const std::string& callback_id, const web::json::value& arguments, bool remove_callback)
{
std::function<void(const web::json::value& arguments)> callback;
{
std::lock_guard<std::mutex> lock(m_map_lock);
auto iter = m_callbacks.find(callback_id);
if (iter == m_callbacks.end())
{
return false;
}
callback = iter->second;
if (remove_callback)
{
m_callbacks.erase(callback_id);
}
}
callback(arguments);
return true;
}
bool callback_manager::remove_callback(const std::string& callback_id)
{
{
std::lock_guard<std::mutex> lock(m_map_lock);
return m_callbacks.erase(callback_id) != 0;
}
}
void callback_manager::clear(const web::json::value& arguments)
{
{
std::lock_guard<std::mutex> lock(m_map_lock);
for (auto& kvp : m_callbacks)
{
kvp.second(arguments);
}
m_callbacks.clear();
}
}
std::string callback_manager::get_callback_id()
{
const auto callback_id = m_id++;
std::stringstream ss;
ss << callback_id;
return ss.str();
}
}

View File

@ -1,36 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include <atomic>
#include <unordered_map>
#include <functional>
#include <mutex>
#include "cpprest/json.h"
namespace signalr
{
class callback_manager
{
public:
explicit callback_manager(const web::json::value& dtor_error);
~callback_manager();
callback_manager(const callback_manager&) = delete;
callback_manager& operator=(const callback_manager&) = delete;
std::string register_callback(const std::function<void(const web::json::value&)>& callback);
bool invoke_callback(const std::string& callback_id, const web::json::value& arguments, bool remove_callback);
bool remove_callback(const std::string& callback_id);
void clear(const web::json::value& arguments);
private:
std::atomic<int> m_id { 0 };
std::unordered_map<std::string, std::function<void(const web::json::value&)>> m_callbacks;
std::mutex m_map_lock;
const web::json::value m_dtor_clear_arguments;
std::string get_callback_id();
};
}

View File

@ -1,50 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include <functional>
#include <cctype>
#include "cpprest/details/basic_types.h"
namespace signalr
{
// Note: These functions are not pretending to be all-purpose helpers for case insensitive string comparison. Rather
// we use them to compare hub and hub method names which are expected to be almost exclusively ASCII and this is the
// simplest thing that would work without having to take dependencies on third party libraries.
struct case_insensitive_equals : std::binary_function<std::string, std::string, bool>
{
bool operator()(const std::string& s1, const std::string& s2) const
{
if (s1.length() != s2.length())
{
return false;
}
for (auto s1_iterator = s1.begin(), s2_iterator = s2.begin(); s1_iterator != s1.end(); ++s1_iterator, ++s2_iterator)
{
if (std::toupper(*s1_iterator) != std::toupper(*s2_iterator))
{
return false;
}
}
return true;
}
};
struct case_insensitive_hash : std::unary_function<std::string, std::size_t>
{
std::size_t operator()(const std::string& s) const noexcept
{
size_t hash = 0;
std::hash<size_t> hasher;
for (const utility::char_t& c : s)
{
hash ^= hasher(std::toupper(c)) + (hash << 5) + (hash >> 2);
}
return hash;
}
};
}

View File

@ -1,58 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "signalrclient/connection.h"
#include "signalrclient/transport_type.h"
#include "connection_impl.h"
namespace signalr
{
connection::connection(const std::string& url, trace_level trace_level, std::shared_ptr<log_writer> log_writer)
: m_pImpl(connection_impl::create(url, trace_level, std::move(log_writer)))
{}
// Do NOT remove this destructor. Letting the compiler generate and inline the default dtor may lead to
// undefinded behavior since we are using an incomplete type. More details here: http://herbsutter.com/gotw/_100/
connection::~connection() = default;
void connection::start(std::function<void(std::exception_ptr)> callback) noexcept
{
m_pImpl->start(callback);
}
void connection::send(const std::string& data, std::function<void(std::exception_ptr)> callback) noexcept
{
m_pImpl->send(data, callback);
}
void connection::set_message_received(const message_received_handler& message_received_callback)
{
m_pImpl->set_message_received(message_received_callback);
}
void connection::set_disconnected(const std::function<void()>& disconnected_callback)
{
m_pImpl->set_disconnected(disconnected_callback);
}
void connection::set_client_config(const signalr_client_config& config)
{
m_pImpl->set_client_config(config);
}
void connection::stop(std::function<void(std::exception_ptr)> callback) noexcept
{
m_pImpl->stop(callback);
}
connection_state connection::get_connection_state() const noexcept
{
return m_pImpl->get_connection_state();
}
std::string connection::get_connection_id() const
{
return m_pImpl->get_connection_id();
}
}

View File

@ -1,627 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include <thread>
#include <algorithm>
#include "constants.h"
#include "connection_impl.h"
#include "negotiate.h"
#include "url_builder.h"
#include "trace_log_writer.h"
#include "make_unique.h"
#include "signalrclient/signalr_exception.h"
#include "default_http_client.h"
namespace signalr
{
// unnamed namespace makes it invisble outside this translation unit
namespace
{
// this is a workaround for a compiler bug where mutable lambdas won't sometimes compile
static void log(const logger& logger, trace_level level, const std::string& entry);
}
std::shared_ptr<connection_impl> connection_impl::create(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer)
{
return connection_impl::create(url, trace_level, log_writer, nullptr, std::make_unique<transport_factory>());
}
std::shared_ptr<connection_impl> connection_impl::create(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory)
{
return std::shared_ptr<connection_impl>(new connection_impl(url, trace_level,
log_writer ? log_writer : std::make_shared<trace_log_writer>(), std::move(http_client), std::move(transport_factory)));
}
connection_impl::connection_impl(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory)
: m_base_url(url), m_connection_state(connection_state::disconnected), m_logger(log_writer, trace_level), m_transport(nullptr),
m_transport_factory(std::move(transport_factory)), m_message_received([](const std::string&) noexcept {}), m_disconnected([]() noexcept {})
{
if (http_client != nullptr)
{
m_http_client = std::move(http_client);
}
else
{
m_http_client = std::unique_ptr<class http_client>(new default_http_client());
}
}
connection_impl::~connection_impl()
{
try
{
// Signaling the event is safe here. We are in the dtor so noone is using this instance. There might be some
// outstanding threads that hold on to the connection via a weak pointer but they won't be able to acquire
// the instance since it is being destroyed. Note that the event may actually be in non-signaled state here.
m_start_completed_event.set();
shutdown().get();
}
catch (const pplx::task_canceled&)
{
// because we are in the dtor and the `connection_imp` is ref counted we should not get the `task_canceled`
// exception because it would indicate that some other thread/task still holds reference to this instance
// so how come we are in the dtor?
_ASSERTE(false);
return;
}
catch (...) // must not throw from destructors
{ }
m_transport = nullptr;
change_state(connection_state::disconnected);
}
void connection_impl::start(std::function<void(std::exception_ptr)> callback) noexcept
{
{
std::lock_guard<std::mutex> lock(m_stop_lock);
if (!change_state(connection_state::disconnected, connection_state::connecting))
{
callback(std::make_exception_ptr(signalr_exception("cannot start a connection that is not in the disconnected state")));
return;
}
// there should not be any active transport at this point
_ASSERTE(!m_transport);
m_disconnect_cts = pplx::cancellation_token_source();
m_start_completed_event.reset();
m_connection_id = "";
}
start_negotiate(m_base_url, 0)
.then([callback](pplx::task<void> prev_task)
{
try
{
prev_task.get();
callback(nullptr);
}
catch (...)
{
callback(std::current_exception());
}
});
}
pplx::task<void> connection_impl::start_negotiate(const std::string& url, int redirect_count)
{
if (redirect_count >= MAX_NEGOTIATE_REDIRECTS)
{
return pplx::task_from_exception<void>(signalr_exception("Negotiate redirection limit exceeded."));
}
pplx::task_completion_event<void> start_tce;
std::weak_ptr<connection_impl> weak_connection = shared_from_this();
pplx::task_from_result()
.then([weak_connection, url]()
{
auto connection = weak_connection.lock();
if (!connection)
{
return pplx::task_from_exception<negotiation_response>("connection no longer exists");
}
return negotiate::negotiate(*connection->m_http_client, url, connection->m_signalr_client_config);
}, m_disconnect_cts.get_token())
.then([weak_connection, start_tce, redirect_count, url](negotiation_response negotiation_response)
{
auto connection = weak_connection.lock();
if (!connection)
{
return pplx::task_from_exception<void>("connection no longer exists");
}
if (!negotiation_response.error.empty())
{
return pplx::task_from_exception<void>(signalr_exception(negotiation_response.error));
}
if (!negotiation_response.url.empty())
{
if (!negotiation_response.accessToken.empty())
{
auto headers = connection->m_signalr_client_config.get_http_headers();
headers[_XPLATSTR("Authorization")] = utility::conversions::to_string_t("Bearer " + negotiation_response.accessToken);
connection->m_signalr_client_config.set_http_headers(headers);
}
return connection->start_negotiate(negotiation_response.url, redirect_count + 1);
}
connection->m_connection_id = std::move(negotiation_response.connectionId);
// TODO: fallback logic
bool foundWebsockets = false;
for (auto availableTransport : negotiation_response.availableTransports)
{
if (availableTransport.transport == "WebSockets")
{
foundWebsockets = true;
break;
}
}
if (!foundWebsockets)
{
return pplx::task_from_exception<void>(signalr_exception("The server does not support WebSockets which is currently the only transport supported by this client."));
}
// TODO: use transfer format
return connection->start_transport(url)
.then([weak_connection, start_tce](std::shared_ptr<transport> transport)
{
auto connection = weak_connection.lock();
if (!connection)
{
return pplx::task_from_exception<void>("connection no longer exists");
}
connection->m_transport = transport;
if (!connection->change_state(connection_state::connecting, connection_state::connected))
{
connection->m_logger.log(trace_level::errors,
std::string("internal error - transition from an unexpected state. expected state: connecting, actual state: ")
.append(translate_connection_state(connection->get_connection_state())));
_ASSERTE(false);
}
return pplx::task_from_result();
});
}, m_disconnect_cts.get_token())
.then([start_tce, weak_connection](pplx::task<void> previous_task)
{
auto connection = weak_connection.lock();
if (!connection)
{
return pplx::task_from_exception<void>(_XPLATSTR("connection no longer exists"));
}
try
{
previous_task.get();
connection->m_start_completed_event.set();
start_tce.set();
}
catch (const std::exception & e)
{
auto task_canceled_exception = dynamic_cast<const pplx::task_canceled*>(&e);
if (task_canceled_exception)
{
connection->m_logger.log(trace_level::info,
"starting the connection has been canceled.");
}
else
{
connection->m_logger.log(trace_level::errors,
std::string("connection could not be started due to: ")
.append(e.what()));
}
connection->m_transport = nullptr;
connection->change_state(connection_state::disconnected);
connection->m_start_completed_event.set();
start_tce.set_exception(std::current_exception());
}
return pplx::task_from_result();
});
return pplx::create_task(start_tce);
}
pplx::task<std::shared_ptr<transport>> connection_impl::start_transport(const std::string& url)
{
auto connection = shared_from_this();
pplx::task_completion_event<void> connect_request_tce;
auto weak_connection = std::weak_ptr<connection_impl>(connection);
const auto& disconnect_cts = m_disconnect_cts;
const auto& logger = m_logger;
auto transport = connection->m_transport_factory->create_transport(
transport_type::websockets, connection->m_logger, connection->m_signalr_client_config);
transport->on_receive([disconnect_cts, connect_request_tce, logger, weak_connection](std::string message, std::exception_ptr exception)
{
if (exception != nullptr)
{
try
{
// Rethrowing the exception so we can log it
std::rethrow_exception(exception);
}
catch (const std::exception & e)
{
// When a connection is stopped we don't wait for its transport to stop. As a result if the same connection
// is immediately re-started the old transport can still invoke this callback. To prevent this we capture
// the disconnect_cts by value which allows distinguishing if the error is for the running connection
// or for the one that was already stopped. If this is the latter we just ignore it.
if (disconnect_cts.get_token().is_canceled())
{
logger.log(trace_level::info,
std::string{ "ignoring stray error received after connection was restarted. error: " }
.append(e.what()));
return;
}
// no op after connection started successfully
connect_request_tce.set_exception(exception);
}
}
else
{
if (disconnect_cts.get_token().is_canceled())
{
logger.log(trace_level::info,
std::string{ "ignoring stray message received after connection was restarted. message: " }
.append(message));
return;
}
auto connection = weak_connection.lock();
if (connection)
{
connection->process_response(message);
}
}
});
pplx::create_task([connect_request_tce, disconnect_cts, weak_connection]()
{
// TODO? std::this_thread::sleep_for(std::chrono::milliseconds(negotiation_response.transport_connect_timeout));
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
// if the disconnect_cts is canceled it means that the connection has been stopped or went out of scope in
// which case we should not throw due to timeout. Instead we need to set the tce prevent the task that is
// using this tce from hanging indifinitely. (This will eventually result in throwing the pplx::task_canceled
// exception to the user since this is what we do in the start() function if disconnect_cts is tripped).
if (disconnect_cts.get_token().is_canceled())
{
connect_request_tce.set();
}
else
{
connect_request_tce.set_exception(signalr_exception("transport timed out when trying to connect"));
}
});
return connection->send_connect_request(transport, url, connect_request_tce)
.then([transport](){ return pplx::task_from_result(transport); });
}
pplx::task<void> connection_impl::send_connect_request(const std::shared_ptr<transport>& transport, const std::string& url, const pplx::task_completion_event<void>& connect_request_tce)
{
auto logger = m_logger;
auto query_string = "id=" + m_connection_id;
auto connect_url = url_builder::build_connect(url, transport->get_transport_type(), query_string);
transport->start(connect_url, transfer_format::text, [transport, connect_request_tce, logger](std::exception_ptr exception)
mutable {
try
{
if (exception != nullptr)
{
std::rethrow_exception(exception);
}
connect_request_tce.set();
}
catch (const std::exception& e)
{
logger.log(
trace_level::errors,
std::string("transport could not connect due to: ")
.append(e.what()));
connect_request_tce.set_exception(std::current_exception());
}
});
return pplx::create_task(connect_request_tce);
}
void connection_impl::process_response(const std::string& response)
{
m_logger.log(trace_level::messages,
std::string("processing message: ").append(response));
invoke_message_received(response);
}
void connection_impl::invoke_message_received(const std::string& message)
{
try
{
m_message_received(message);
}
catch (const std::exception &e)
{
m_logger.log(
trace_level::errors,
std::string("message_received callback threw an exception: ")
.append(e.what()));
}
catch (...)
{
m_logger.log(trace_level::errors, "message_received callback threw an unknown exception");
}
}
void connection_impl::send(const std::string& data, std::function<void(std::exception_ptr)> callback) noexcept
{
// To prevent an (unlikely) condition where the transport is nulled out after we checked the connection_state
// and before sending data we store the pointer in the local variable. In this case `send()` will throw but
// we won't crash.
auto transport = m_transport;
const auto connection_state = get_connection_state();
if (connection_state != signalr::connection_state::connected || !transport)
{
callback(std::make_exception_ptr(signalr_exception(
std::string("cannot send data when the connection is not in the connected state. current connection state: ")
.append(translate_connection_state(connection_state)))));
return;
}
auto logger = m_logger;
logger.log(trace_level::info, std::string("sending data: ").append(data));
transport->send(data, [logger, callback](std::exception_ptr exception)
mutable {
try
{
if (exception != nullptr)
{
std::rethrow_exception(exception);
}
callback(nullptr);
}
catch (const std::exception &e)
{
logger.log(
trace_level::errors,
std::string("error sending data: ")
.append(e.what()));
callback(exception);
}
});
}
void connection_impl::stop(std::function<void(std::exception_ptr)> callback) noexcept
{
m_logger.log(trace_level::info, "stopping connection");
auto connection = shared_from_this();
shutdown()
.then([connection, callback](pplx::task<void> prev_task)
{
try
{
prev_task.get();
}
catch (...)
{
callback(std::current_exception());
return;
}
{
// the lock prevents a race where the user calls `stop` on a disconnected connection and calls `start`
// on a different thread at the same time. In this case we must not null out the transport if we are
// not in the `disconnecting` state to not affect the 'start' invocation.
std::lock_guard<std::mutex> lock(connection->m_stop_lock);
if (connection->change_state(connection_state::disconnecting, connection_state::disconnected))
{
// we do let the exception through (especially the task_canceled exception)
connection->m_transport = nullptr;
}
}
try
{
connection->m_disconnected();
}
catch (const std::exception &e)
{
connection->m_logger.log(
trace_level::errors,
std::string("disconnected callback threw an exception: ")
.append(e.what()));
}
catch (...)
{
connection->m_logger.log(
trace_level::errors,
std::string("disconnected callback threw an unknown exception"));
}
callback(nullptr);
});
}
// This function is called from the dtor so you must not use `shared_from_this` here (it will throw).
pplx::task<void> connection_impl::shutdown()
{
{
std::lock_guard<std::mutex> lock(m_stop_lock);
m_logger.log(trace_level::info, "acquired lock in shutdown()");
const auto current_state = get_connection_state();
if (current_state == connection_state::disconnected)
{
return pplx::task_from_result();
}
if (current_state == connection_state::disconnecting)
{
// canceled task will be returned if `stop` was called while another `stop` was already in progress.
// This is to prevent from resetting the `m_transport` in the upstream callers because doing so might
// affect the other invocation which is using it.
auto cts = pplx::cancellation_token_source();
cts.cancel();
return pplx::create_task([]() noexcept {}, cts.get_token());
}
// we request a cancellation of the ongoing start (if any) and wait until it is canceled
m_disconnect_cts.cancel();
while (m_start_completed_event.wait(60000) != 0)
{
m_logger.log(trace_level::errors,
"internal error - stopping the connection is still waiting for the start operation to finish which should have already finished or timed out");
}
// at this point we are either in the connected or disconnected state. If we are in the disconnected state
// we must break because the transport has already been nulled out.
if (m_connection_state == connection_state::disconnected)
{
return pplx::task_from_result();
}
_ASSERTE(m_connection_state == connection_state::connected);
change_state(connection_state::disconnecting);
}
pplx::task_completion_event<void> tce;
m_transport->stop([tce](std::exception_ptr exception)
{
if (exception != nullptr)
{
tce.set_exception(exception);
}
else
{
tce.set();
}
});
return pplx::create_task(tce);
}
connection_state connection_impl::get_connection_state() const noexcept
{
return m_connection_state.load();
}
std::string connection_impl::get_connection_id() const noexcept
{
if (m_connection_state.load() == connection_state::connecting)
{
return "";
}
return m_connection_id;
}
void connection_impl::set_message_received(const std::function<void(const std::string&)>& message_received)
{
ensure_disconnected("cannot set the callback when the connection is not in the disconnected state. ");
m_message_received = message_received;
}
void connection_impl::set_client_config(const signalr_client_config& config)
{
ensure_disconnected("cannot set client config when the connection is not in the disconnected state. ");
m_signalr_client_config = config;
}
void connection_impl::set_disconnected(const std::function<void()>& disconnected)
{
ensure_disconnected("cannot set the disconnected callback when the connection is not in the disconnected state. ");
m_disconnected = disconnected;
}
void connection_impl::ensure_disconnected(const std::string& error_message) const
{
const auto state = get_connection_state();
if (state != connection_state::disconnected)
{
throw signalr_exception(
error_message + "current connection state: " + translate_connection_state(state));
}
}
bool connection_impl::change_state(connection_state old_state, connection_state new_state)
{
if (m_connection_state.compare_exchange_strong(old_state, new_state, std::memory_order_seq_cst))
{
handle_connection_state_change(old_state, new_state);
return true;
}
return false;
}
connection_state connection_impl::change_state(connection_state new_state)
{
auto old_state = m_connection_state.exchange(new_state);
if (old_state != new_state)
{
handle_connection_state_change(old_state, new_state);
}
return old_state;
}
void connection_impl::handle_connection_state_change(connection_state old_state, connection_state new_state)
{
m_logger.log(
trace_level::state_changes,
translate_connection_state(old_state)
.append(" -> ")
.append(translate_connection_state(new_state)));
// Words of wisdom (if we decide to add a state_changed callback and invoke it from here):
// "Be extra careful when you add this callback, because this is sometimes being called with the m_stop_lock.
// This could lead to interesting problems.For example, you could run into a segfault if the connection is
// stopped while / after transitioning into the connecting state."
}
std::string connection_impl::translate_connection_state(connection_state state)
{
switch (state)
{
case connection_state::connecting:
return "connecting";
case connection_state::connected:
return "connected";
case connection_state::disconnecting:
return "disconnecting";
case connection_state::disconnected:
return "disconnected";
default:
_ASSERTE(false);
return "(unknown)";
}
}
}

View File

@ -1,87 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include <atomic>
#include <mutex>
#include "signalrclient/http_client.h"
#include "signalrclient/trace_level.h"
#include "signalrclient/connection_state.h"
#include "signalrclient/signalr_client_config.h"
#include "web_request_factory.h"
#include "transport_factory.h"
#include "logger.h"
#include "negotiation_response.h"
#include "event.h"
namespace signalr
{
// Note:
// Factory methods and private constructors prevent from using this class incorrectly. Because this class
// derives from `std::enable_shared_from_this` the instance has to be owned by a `std::shared_ptr` whenever
// a member method calls `std::shared_from_this()` otherwise the behavior is undefined. Therefore constructors
// are private to disallow creating instances directly and factory methods return `std::shared_ptr<connection_impl>`.
class connection_impl : public std::enable_shared_from_this<connection_impl>
{
public:
static std::shared_ptr<connection_impl> create(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer);
static std::shared_ptr<connection_impl> create(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory);
connection_impl(const connection_impl&) = delete;
connection_impl& operator=(const connection_impl&) = delete;
~connection_impl();
void start(std::function<void(std::exception_ptr)> callback) noexcept;
void send(const std::string &data, std::function<void(std::exception_ptr)> callback) noexcept;
void stop(std::function<void(std::exception_ptr)> callback) noexcept;
connection_state get_connection_state() const noexcept;
std::string get_connection_id() const noexcept;
void set_message_received(const std::function<void(const std::string&)>& message_received);
void set_disconnected(const std::function<void()>& disconnected);
void set_client_config(const signalr_client_config& config);
private:
std::string m_base_url;
std::atomic<connection_state> m_connection_state;
logger m_logger;
std::shared_ptr<transport> m_transport;
std::unique_ptr<transport_factory> m_transport_factory;
std::function<void(const std::string&)> m_message_received;
std::function<void()> m_disconnected;
signalr_client_config m_signalr_client_config;
pplx::cancellation_token_source m_disconnect_cts;
std::mutex m_stop_lock;
event m_start_completed_event;
std::string m_connection_id;
std::unique_ptr<http_client> m_http_client;
connection_impl(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory);
pplx::task<std::shared_ptr<transport>> start_transport(const std::string& url);
pplx::task<void> send_connect_request(const std::shared_ptr<transport>& transport,
const std::string& url, const pplx::task_completion_event<void>& connect_request_tce);
pplx::task<void> start_negotiate(const std::string& url, int redirect_count);
void process_response(const std::string& response);
pplx::task<void> shutdown();
bool change_state(connection_state old_state, connection_state new_state);
connection_state change_state(connection_state new_state);
void handle_connection_state_change(connection_state old_state, connection_state new_state);
void invoke_message_received(const std::string& message);
static std::string translate_connection_state(connection_state state);
void ensure_disconnected(const std::string& error_message) const;
};
}

View File

@ -1,8 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#define SIGNALR_VERSION "0.1.0-alpha0"
#define USER_AGENT "SignalR.Client.Cpp/" SIGNALR_VERSION
#define MAX_NEGOTIATE_REDIRECTS 100

View File

@ -1,73 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "default_http_client.h"
namespace signalr
{
void default_http_client::send(std::string url, http_request request, std::function<void(http_response, std::exception_ptr)> callback)
{
web::http::method method;
if (request.method == http_method::GET)
{
method = U("GET");
}
else if (request.method == http_method::POST)
{
method = U("POST");
}
else
{
callback(http_response(), std::make_exception_ptr(std::runtime_error("unknown http method")));
return;
}
web::http::http_request http_request;
http_request.set_method(method);
http_request.set_body(request.content);
if (request.headers.size() > 0)
{
web::http::http_headers headers;
for (auto& header : request.headers)
{
headers.add(utility::conversions::to_string_t(header.first), utility::conversions::to_string_t(header.second));
}
http_request.headers() = headers;
}
auto milliseconds = std::chrono::milliseconds(request.timeout).count();
pplx::cancellation_token_source cts;
if (milliseconds != 0)
{
pplx::create_task([milliseconds, cts]()
{
pplx::wait((unsigned int)milliseconds);
cts.cancel();
});
}
web::http::client::http_client client(utility::conversions::to_string_t(url));
client.request(http_request, cts.get_token())
.then([callback](pplx::task<web::http::http_response> response_task)
{
try
{
auto http_response = response_task.get();
auto status_code = http_response.status_code();
http_response.extract_utf8string()
.then([callback, status_code](std::string response_body)
{
signalr::http_response response;
response.content = response_body;
response.status_code = status_code;
callback(std::move(response), nullptr);
});
}
catch (...)
{
callback(http_response(), std::current_exception());
}
});
}
}

View File

@ -1,16 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include "signalrclient/http_client.h"
#include "cpprest/http_client.h"
namespace signalr
{
class default_http_client : public http_client
{
public:
void send(std::string url, http_request request, std::function<void(http_response, std::exception_ptr)> callback) override;
};
}

View File

@ -1,93 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "default_websocket_client.h"
namespace signalr
{
namespace
{
static web::websockets::client::websocket_client_config create_client_config(const signalr_client_config& signalr_client_config) noexcept
{
auto websocket_client_config = signalr_client_config.get_websocket_client_config();
websocket_client_config.headers() = signalr_client_config.get_http_headers();
return websocket_client_config;
}
}
default_websocket_client::default_websocket_client(const signalr_client_config& signalr_client_config) noexcept
: m_underlying_client(create_client_config(signalr_client_config))
{ }
void default_websocket_client::start(std::string url, transfer_format, std::function<void(std::exception_ptr)> callback)
{
m_underlying_client.connect(utility::conversions::to_string_t(url))
.then([callback](pplx::task<void> task)
{
try
{
task.get();
callback(nullptr);
}
catch (...)
{
callback(std::current_exception());
}
});
}
void default_websocket_client::stop(std::function<void(std::exception_ptr)> callback)
{
m_underlying_client.close()
.then([callback](pplx::task<void> task)
{
try
{
callback(nullptr);
}
catch (...)
{
callback(std::current_exception());
}
});
}
void default_websocket_client::send(std::string payload, std::function<void(std::exception_ptr)> callback)
{
web::websockets::client::websocket_outgoing_message msg;
msg.set_utf8_message(payload);
m_underlying_client.send(msg)
.then([callback](pplx::task<void> task)
{
try
{
task.get();
callback(nullptr);
}
catch (...)
{
callback(std::current_exception());
}
});
}
void default_websocket_client::receive(std::function<void(std::string, std::exception_ptr)> callback)
{
m_underlying_client.receive()
.then([callback](pplx::task<web::websockets::client::websocket_incoming_message> task)
{
try
{
auto response = task.get();
auto msg = response.extract_string().get();
callback(msg, nullptr);
}
catch (...)
{
callback("", std::current_exception());
}
});
}
}

View File

@ -1,24 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include "cpprest/ws_client.h"
#include "signalrclient/signalr_client_config.h"
#include "signalrclient/websocket_client.h"
namespace signalr
{
class default_websocket_client : public websocket_client
{
public:
explicit default_websocket_client(const signalr_client_config& signalr_client_config = {}) noexcept;
void start(std::string url, transfer_format format, std::function<void(std::exception_ptr)> callback) override;
void stop(std::function<void(std::exception_ptr)> callback) override;
void send(std::string payload, std::function<void(std::exception_ptr)> callback) override;
void receive(std::function<void(std::string, std::exception_ptr)> callback) override;
private:
web::websockets::client::websocket_client m_underlying_client;
};
}

View File

@ -1,63 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include <assert.h>
#include <condition_variable>
#include <mutex>
namespace signalr
{
class event
{
private:
std::mutex m_lock;
std::condition_variable m_condition;
bool m_signaled;
public:
static const unsigned int timeout_infinite = 0xFFFFFFFF;
event() noexcept
: m_signaled(false)
{
}
void set()
{
std::lock_guard<std::mutex> lock(m_lock);
m_signaled = true;
m_condition.notify_all();
}
void reset()
{
std::lock_guard<std::mutex> lock(m_lock);
m_signaled = false;
}
unsigned int wait(unsigned int timeout)
{
std::unique_lock<std::mutex> lock(m_lock);
if (timeout == event::timeout_infinite)
{
m_condition.wait(lock, [this]() noexcept { return m_signaled; });
return 0;
}
else
{
const std::chrono::milliseconds period(timeout);
const auto status = m_condition.wait_for(lock, period, [this]() noexcept { return m_signaled; });
assert(status == m_signaled);
// Return 0 if the wait completed as a result of signaling the event. Otherwise, return timeout_infinite
return status ? 0 : event::timeout_infinite;
}
}
unsigned int wait()
{
return wait(event::timeout_infinite);
}
};
}

View File

@ -1,57 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "signalrclient/web_exception.h"
#include "web_request_factory.h"
#include "constants.h"
namespace signalr
{
namespace http_sender
{
pplx::task<std::string> get(web_request_factory& request_factory, const std::string& url,
const signalr_client_config& signalr_client_config)
{
auto request = request_factory.create_web_request(url);
request->set_method(utility::conversions::to_utf8string(web::http::methods::GET));
request->set_user_agent(USER_AGENT);
request->set_client_config(signalr_client_config);
return request->get_response().then([](web_response response)
{
if (response.status_code != 200)
{
std::stringstream oss;
oss << "web exception - " << response.status_code << " " << response.reason_phrase;
throw web_exception(oss.str(), response.status_code);
}
return response.body;
});
}
pplx::task<std::string> post(web_request_factory& request_factory, const std::string& url,
const signalr_client_config& signalr_client_config)
{
auto request = request_factory.create_web_request(url);
request->set_method(utility::conversions::to_utf8string(web::http::methods::POST));
request->set_user_agent(USER_AGENT);
request->set_client_config(signalr_client_config);
return request->get_response().then([](web_response response)
{
if (response.status_code != 200)
{
std::stringstream oss;
oss << "web exception - " << response.status_code << " " << response.reason_phrase;
throw web_exception(oss.str(), response.status_code);
}
return response.body;
});
}
}
}

View File

@ -1,20 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include "pplx/pplxtasks.h"
#include "signalrclient/signalr_client_config.h"
#include "web_request_factory.h"
namespace signalr
{
namespace http_sender
{
pplx::task<std::string> get(web_request_factory& request_factory, const std::string& url,
const signalr_client_config& client_config = signalr_client_config{});
pplx::task<std::string> post(web_request_factory& request_factory, const std::string& url,
const signalr_client_config& client_config = signalr_client_config{});
}
}

View File

@ -1,111 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "signalrclient/hub_connection.h"
#include "hub_connection_impl.h"
#include "signalrclient/signalr_exception.h"
namespace signalr
{
hub_connection::hub_connection(const std::string& url,
trace_level trace_level, std::shared_ptr<log_writer> log_writer)
: m_pImpl(hub_connection_impl::create(url, trace_level, std::move(log_writer)))
{}
// Do NOT remove this destructor. Letting the compiler generate and inline the default dtor may lead to
// undefinded behavior since we are using an incomplete type. More details here: http://herbsutter.com/gotw/_100/
hub_connection::~hub_connection() = default;
void hub_connection::start(std::function<void(std::exception_ptr)> callback) noexcept
{
if (!m_pImpl)
{
callback(std::make_exception_ptr(signalr_exception("start() cannot be called on destructed hub_connection instance")));
}
m_pImpl->start(callback);
}
void hub_connection::stop(std::function<void(std::exception_ptr)> callback) noexcept
{
if (!m_pImpl)
{
callback(std::make_exception_ptr(signalr_exception("stop() cannot be called on destructed hub_connection instance")));
}
m_pImpl->stop(callback);
}
void hub_connection::on(const std::string& event_name, const method_invoked_handler& handler)
{
if (!m_pImpl)
{
throw signalr_exception("on() cannot be called on destructed hub_connection instance");
}
return m_pImpl->on(event_name, handler);
}
void hub_connection::invoke(const std::string& method_name, const web::json::value& arguments, std::function<void(const web::json::value&, std::exception_ptr)> callback) noexcept
{
if (!m_pImpl)
{
callback(web::json::value(), std::make_exception_ptr(signalr_exception("invoke() cannot be called on destructed hub_connection instance")));
return;
}
return m_pImpl->invoke(method_name, arguments, callback);
}
void hub_connection::send(const std::string& method_name, const web::json::value& arguments, std::function<void(std::exception_ptr)> callback) noexcept
{
if (!m_pImpl)
{
callback(std::make_exception_ptr(signalr_exception("send() cannot be called on destructed hub_connection instance")));
return;
}
m_pImpl->send(method_name, arguments, callback);
}
connection_state hub_connection::get_connection_state() const
{
if (!m_pImpl)
{
throw signalr_exception("get_connection_state() cannot be called on destructed hub_connection instance");
}
return m_pImpl->get_connection_state();
}
std::string hub_connection::get_connection_id() const
{
if (!m_pImpl)
{
throw signalr_exception("get_connection_id() cannot be called on destructed hub_connection instance");
}
return m_pImpl->get_connection_id();
}
void hub_connection::set_disconnected(const std::function<void()>& disconnected_callback)
{
if (!m_pImpl)
{
throw signalr_exception("set_disconnected() cannot be called on destructed hub_connection instance");
}
m_pImpl->set_disconnected(disconnected_callback);
}
void hub_connection::set_client_config(const signalr_client_config& config)
{
if (!m_pImpl)
{
throw signalr_exception("set_client_config() cannot be called on destructed hub_connection instance");
}
m_pImpl->set_client_config(config);
}
}

View File

@ -1,405 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "hub_connection_impl.h"
#include "signalrclient/hub_exception.h"
#include "trace_log_writer.h"
#include "make_unique.h"
#include "signalrclient/signalr_exception.h"
using namespace web;
namespace signalr
{
// unnamed namespace makes it invisble outside this translation unit
namespace
{
static std::function<void(const json::value&)> create_hub_invocation_callback(const logger& logger,
const std::function<void(const json::value&)>& set_result,
const std::function<void(const std::exception_ptr e)>& set_exception);
}
std::shared_ptr<hub_connection_impl> hub_connection_impl::create(const std::string& url, trace_level trace_level,
const std::shared_ptr<log_writer>& log_writer)
{
return hub_connection_impl::create(url, trace_level, log_writer,
nullptr, std::make_unique<transport_factory>());
}
std::shared_ptr<hub_connection_impl> hub_connection_impl::create(const std::string& url, trace_level trace_level,
const std::shared_ptr<log_writer>& log_writer, std::unique_ptr<http_client> http_client,
std::unique_ptr<transport_factory> transport_factory)
{
auto connection = std::shared_ptr<hub_connection_impl>(new hub_connection_impl(url, trace_level,
log_writer ? log_writer : std::make_shared<trace_log_writer>(), std::move(http_client), std::move(transport_factory)));
connection->initialize();
return connection;
}
hub_connection_impl::hub_connection_impl(const std::string& url, trace_level trace_level,
const std::shared_ptr<log_writer>& log_writer, std::unique_ptr<http_client> http_client,
std::unique_ptr<transport_factory> transport_factory)
: m_connection(connection_impl::create(url, trace_level, log_writer,
std::move(http_client), std::move(transport_factory))), m_logger(log_writer, trace_level),
m_callback_manager(json::value::parse(_XPLATSTR("{ \"error\" : \"connection went out of scope before invocation result was received\"}"))),
m_disconnected([]() noexcept {}), m_handshakeReceived(false)
{ }
void hub_connection_impl::initialize()
{
// weak_ptr prevents a circular dependency leading to memory leak and other problems
std::weak_ptr<hub_connection_impl> weak_hub_connection = shared_from_this();
m_connection->set_message_received([weak_hub_connection](const std::string& message)
{
auto connection = weak_hub_connection.lock();
if (connection)
{
connection->process_message(message);
}
});
m_connection->set_disconnected([weak_hub_connection]()
{
auto connection = weak_hub_connection.lock();
if (connection)
{
connection->m_handshakeTask.set_exception(signalr_exception("connection closed while handshake was in progress."));
connection->m_disconnected();
}
});
}
void hub_connection_impl::on(const std::string& event_name, const std::function<void(const json::value &)>& handler)
{
if (event_name.length() == 0)
{
throw std::invalid_argument("event_name cannot be empty");
}
auto weak_connection = std::weak_ptr<hub_connection_impl>(shared_from_this());
auto connection = weak_connection.lock();
if (connection && connection->get_connection_state() != connection_state::disconnected)
{
throw signalr_exception("can't register a handler if the connection is in a disconnected state");
}
if (m_subscriptions.find(event_name) != m_subscriptions.end())
{
throw signalr_exception(
"an action for this event has already been registered. event name: " + event_name);
}
m_subscriptions.insert(std::pair<std::string, std::function<void(const json::value &)>> {event_name, handler});
}
void hub_connection_impl::start(std::function<void(std::exception_ptr)> callback) noexcept
{
if (m_connection->get_connection_state() != connection_state::disconnected)
{
callback(std::make_exception_ptr(signalr_exception(
"the connection can only be started if it is in the disconnected state")));
return;
}
m_connection->set_client_config(m_signalr_client_config);
m_handshakeTask = pplx::task_completion_event<void>();
m_handshakeReceived = false;
std::weak_ptr<hub_connection_impl> weak_connection = shared_from_this();
m_connection->start([weak_connection, callback](std::exception_ptr start_exception)
{
auto connection = weak_connection.lock();
if (!connection)
{
// The connection has been destructed
callback(std::make_exception_ptr(signalr_exception("the hub connection has been deconstructed")));
return;
}
if (start_exception)
{
connection->m_connection->stop([start_exception, callback, weak_connection](std::exception_ptr)
{
try
{
auto connection = weak_connection.lock();
if (!connection)
{
callback(std::make_exception_ptr(signalr_exception("the hub connection has been deconstructed")));
return;
}
pplx::task<void>(connection->m_handshakeTask).get();
}
catch (...) {}
callback(start_exception);
});
return;
}
// TODO: Generate this later when we have the protocol abstraction
auto handshake_request = "{\"protocol\":\"json\",\"version\":1}\x1e";
connection->m_connection->send(handshake_request, [weak_connection, callback](std::exception_ptr exception)
{
auto connection = weak_connection.lock();
if (!connection)
{
// The connection has been destructed
callback(std::make_exception_ptr(signalr_exception("the hub connection has been deconstructed")));
return;
}
if (exception)
{
callback(exception);
return;
}
try
{
pplx::task<void>(connection->m_handshakeTask).get();
callback(nullptr);
}
catch (...)
{
auto handshake_exception = std::current_exception();
connection->m_connection->stop([callback, handshake_exception](std::exception_ptr)
{
callback(handshake_exception);
});
}
});
});
}
void hub_connection_impl::stop(std::function<void(std::exception_ptr)> callback) noexcept
{
m_callback_manager.clear(json::value::parse(_XPLATSTR("{ \"error\" : \"connection was stopped before invocation result was received\"}")));
m_connection->stop(callback);
}
enum MessageType
{
Invocation = 1,
StreamItem,
Completion,
StreamInvocation,
CancelInvocation,
Ping,
Close,
};
void hub_connection_impl::process_message(const std::string& response)
{
try
{
auto pos = response.find('\x1e');
std::size_t lastPos = 0;
while (pos != std::string::npos)
{
auto message = response.substr(lastPos, pos - lastPos);
const auto result = web::json::value::parse(utility::conversions::to_string_t(message));
if (!result.is_object())
{
m_logger.log(trace_level::info, std::string("unexpected response received from the server: ")
.append(message));
return;
}
if (!m_handshakeReceived)
{
if (result.has_field(_XPLATSTR("error")))
{
auto error = utility::conversions::to_utf8string(result.at(_XPLATSTR("error")).as_string());
m_logger.log(trace_level::errors, std::string("handshake error: ")
.append(error));
m_handshakeTask.set_exception(signalr_exception(std::string("Received an error during handshake: ").append(error)));
return;
}
else
{
if (result.has_field(_XPLATSTR("type")))
{
m_handshakeTask.set_exception(signalr_exception(std::string("Received unexpected message while waiting for the handshake response.")));
}
m_handshakeReceived = true;
m_handshakeTask.set();
return;
}
}
auto messageType = result.at(_XPLATSTR("type"));
switch (messageType.as_integer())
{
case MessageType::Invocation:
{
auto method = utility::conversions::to_utf8string(result.at(_XPLATSTR("target")).as_string());
auto event = m_subscriptions.find(method);
if (event != m_subscriptions.end())
{
event->second(result.at(_XPLATSTR("arguments")));
}
break;
}
case MessageType::StreamInvocation:
// Sent to server only, should not be received by client
throw std::runtime_error("Received unexpected message type 'StreamInvocation'.");
case MessageType::StreamItem:
// TODO
break;
case MessageType::Completion:
{
if (result.has_field(_XPLATSTR("error")) && result.has_field(_XPLATSTR("result")))
{
// TODO: error
}
invoke_callback(result);
break;
}
case MessageType::CancelInvocation:
// Sent to server only, should not be received by client
throw std::runtime_error("Received unexpected message type 'CancelInvocation'.");
case MessageType::Ping:
// TODO
break;
case MessageType::Close:
// TODO
break;
}
lastPos = pos + 1;
pos = response.find('\x1e', lastPos);
}
}
catch (const std::exception &e)
{
m_logger.log(trace_level::errors, std::string("error occured when parsing response: ")
.append(e.what())
.append(". response: ")
.append(response));
}
}
bool hub_connection_impl::invoke_callback(const web::json::value& message)
{
auto id = utility::conversions::to_utf8string(message.at(_XPLATSTR("invocationId")).as_string());
if (!m_callback_manager.invoke_callback(id, message, true))
{
m_logger.log(trace_level::info, std::string("no callback found for id: ").append(id));
return false;
}
return true;
}
void hub_connection_impl::invoke(const std::string& method_name, const json::value& arguments, std::function<void(const web::json::value&, std::exception_ptr)> callback) noexcept
{
_ASSERTE(arguments.is_array());
const auto callback_id = m_callback_manager.register_callback(
create_hub_invocation_callback(m_logger, [callback](const json::value& result) { callback(result, nullptr); },
[callback](const std::exception_ptr e) { callback(json::value(), e); }));
invoke_hub_method(method_name, arguments, callback_id, nullptr,
[callback](const std::exception_ptr e){ callback(json::value(), e); });
}
void hub_connection_impl::send(const std::string& method_name, const json::value& arguments, std::function<void(std::exception_ptr)> callback) noexcept
{
_ASSERTE(arguments.is_array());
invoke_hub_method(method_name, arguments, "",
[callback]() { callback(nullptr); },
[callback](const std::exception_ptr e){ callback(e); });
}
void hub_connection_impl::invoke_hub_method(const std::string& method_name, const json::value& arguments,
const std::string& callback_id, std::function<void()> set_completion, std::function<void(const std::exception_ptr)> set_exception) noexcept
{
json::value request;
request[_XPLATSTR("type")] = json::value(1);
if (!callback_id.empty())
{
request[_XPLATSTR("invocationId")] = json::value::string(utility::conversions::to_string_t(callback_id));
}
request[_XPLATSTR("target")] = json::value::string(utility::conversions::to_string_t(method_name));
request[_XPLATSTR("arguments")] = arguments;
// weak_ptr prevents a circular dependency leading to memory leak and other problems
auto weak_hub_connection = std::weak_ptr<hub_connection_impl>(shared_from_this());
m_connection->send(utility::conversions::to_utf8string(request.serialize() + _XPLATSTR('\x1e')), [set_completion, set_exception, weak_hub_connection, callback_id](std::exception_ptr exception)
{
if (exception)
{
set_exception(exception);
auto hub_connection = weak_hub_connection.lock();
if (hub_connection)
{
hub_connection->m_callback_manager.remove_callback(callback_id);
}
}
else
{
if (callback_id.empty())
{
// complete nonBlocking call
set_completion();
}
}
});
}
connection_state hub_connection_impl::get_connection_state() const noexcept
{
return m_connection->get_connection_state();
}
std::string hub_connection_impl::get_connection_id() const
{
return m_connection->get_connection_id();
}
void hub_connection_impl::set_client_config(const signalr_client_config& config)
{
m_signalr_client_config = config;
m_connection->set_client_config(config);
}
void hub_connection_impl::set_disconnected(const std::function<void()>& disconnected)
{
m_disconnected = disconnected;
}
// unnamed namespace makes it invisble outside this translation unit
namespace
{
static std::function<void(const json::value&)> create_hub_invocation_callback(const logger& logger,
const std::function<void(const json::value&)>& set_result,
const std::function<void(const std::exception_ptr)>& set_exception)
{
return [logger, set_result, set_exception](const json::value& message)
{
if (message.has_field(_XPLATSTR("result")))
{
set_result(message.at(_XPLATSTR("result")));
}
else if (message.has_field(_XPLATSTR("error")))
{
set_exception(
std::make_exception_ptr(
hub_exception(utility::conversions::to_utf8string(message.at(_XPLATSTR("error")).serialize()))));
}
else
{
set_result(json::value::value());
}
};
}
}
}

View File

@ -1,68 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include <unordered_map>
#include "connection_impl.h"
#include "callback_manager.h"
#include "case_insensitive_comparison_utils.h"
using namespace web;
namespace signalr
{
// Note:
// Factory methods and private constructors prevent from using this class incorrectly. Because this class
// derives from `std::enable_shared_from_this` the instance has to be owned by a `std::shared_ptr` whenever
// a member method calls `std::shared_from_this()` otherwise the behavior is undefined. Therefore constructors
// are private to disallow creating instances directly and factory methods return `std::shared_ptr<connection_impl>`.
class hub_connection_impl : public std::enable_shared_from_this<hub_connection_impl>
{
public:
static std::shared_ptr<hub_connection_impl> create(const std::string& url, trace_level trace_level,
const std::shared_ptr<log_writer>& log_writer);
static std::shared_ptr<hub_connection_impl> create(const std::string& url, trace_level trace_level,
const std::shared_ptr<log_writer>& log_writer, std::unique_ptr<http_client> http_client,
std::unique_ptr<transport_factory> transport_factory);
hub_connection_impl(const hub_connection_impl&) = delete;
hub_connection_impl& operator=(const hub_connection_impl&) = delete;
void on(const std::string& event_name, const std::function<void(const json::value &)>& handler);
void invoke(const std::string& method_name, const json::value& arguments, std::function<void(const json::value&, std::exception_ptr)> callback) noexcept;
void send(const std::string& method_name, const json::value& arguments, std::function<void(std::exception_ptr)> callback) noexcept;
void start(std::function<void(std::exception_ptr)> callback) noexcept;
void stop(std::function<void(std::exception_ptr)> callback) noexcept;
connection_state get_connection_state() const noexcept;
std::string get_connection_id() const;
void set_client_config(const signalr_client_config& config);
void set_disconnected(const std::function<void()>& disconnected);
private:
hub_connection_impl(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory);
std::shared_ptr<connection_impl> m_connection;
logger m_logger;
callback_manager m_callback_manager;
std::unordered_map<std::string, std::function<void(const json::value &)>, case_insensitive_hash, case_insensitive_equals> m_subscriptions;
bool m_handshakeReceived;
pplx::task_completion_event<void> m_handshakeTask;
std::function<void()> m_disconnected;
signalr_client_config m_signalr_client_config;
void initialize();
void process_message(const std::string& message);
void invoke_hub_method(const std::string& method_name, const json::value& arguments, const std::string& callback_id,
std::function<void()> set_completion, std::function<void(const std::exception_ptr)> set_exception) noexcept;
bool invoke_callback(const web::json::value& message);
};
}

View File

@ -1,57 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "logger.h"
#include "cpprest/asyncrt_utils.h"
#include <iomanip>
namespace signalr
{
logger::logger(const std::shared_ptr<log_writer>& log_writer, trace_level trace_level) noexcept
: m_log_writer(log_writer), m_trace_level(trace_level)
{ }
void logger::log(trace_level level, const std::string& entry) const
{
if ((level & m_trace_level) != trace_level::none)
{
try
{
std::stringstream os;
os << utility::conversions::to_utf8string(utility::datetime::utc_now().to_string(utility::datetime::date_format::ISO_8601)) << " ["
<< std::left << std::setw(12) << translate_trace_level(level) << "] "<< entry << std::endl;
m_log_writer->write(os.str());
}
catch (const std::exception &e)
{
std::cerr << "error occurred when logging: " << e.what()
<< std::endl << " entry: " << entry << std::endl;
}
catch (...)
{
std::cerr << "unknown error occurred when logging" << std::endl << " entry: " << entry << std::endl;
}
}
}
std::string logger::translate_trace_level(trace_level trace_level)
{
switch (trace_level)
{
case signalr::trace_level::messages:
return "message";
case signalr::trace_level::state_changes:
return "state change";
case signalr::trace_level::events:
return "event";
case signalr::trace_level::errors:
return "error";
case signalr::trace_level::info:
return "info";
default:
_ASSERTE(false);
return "(unknown)";
}
}
}

View File

@ -1,25 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include <memory>
#include "signalrclient/trace_level.h"
#include "signalrclient/log_writer.h"
namespace signalr
{
class logger
{
public:
logger(const std::shared_ptr<log_writer>& log_writer, trace_level trace_level) noexcept;
void log(trace_level level, const std::string& entry) const;
private:
std::shared_ptr<log_writer> m_log_writer;
trace_level m_trace_level;
static std::string translate_trace_level(trace_level trace_level);
};
}

View File

@ -1,18 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#if defined (__GNUC__)
#include <memory>
namespace std
{
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
}
#endif

View File

@ -1,103 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "negotiate.h"
#include "url_builder.h"
#include "signalrclient/signalr_exception.h"
namespace signalr
{
namespace negotiate
{
pplx::task<negotiation_response> negotiate(http_client& client, const std::string& base_url,
const signalr_client_config& config)
{
auto negotiate_url = url_builder::build_negotiate(base_url);
pplx::task_completion_event<negotiation_response> tce;
// TODO: signalr_client_config
http_request request;
request.method = http_method::POST;
for (auto& header : config.get_http_headers())
{
request.headers.insert(std::make_pair(utility::conversions::to_utf8string(header.first), utility::conversions::to_utf8string(header.second)));
}
client.send(negotiate_url, request, [tce](http_response http_response, std::exception_ptr exception)
{
if (exception != nullptr)
{
tce.set_exception(exception);
return;
}
if (http_response.status_code != 200)
{
tce.set_exception(signalr_exception("negotiate failed with status code " + std::to_string(http_response.status_code)));
return;
}
try
{
auto negotiation_response_json = web::json::value::parse(utility::conversions::to_string_t(http_response.content));
negotiation_response response;
if (negotiation_response_json.has_field(_XPLATSTR("error")))
{
response.error = utility::conversions::to_utf8string(negotiation_response_json[_XPLATSTR("error")].as_string());
tce.set(std::move(response));
return;
}
if (negotiation_response_json.has_field(_XPLATSTR("connectionId")))
{
response.connectionId = utility::conversions::to_utf8string(negotiation_response_json[_XPLATSTR("connectionId")].as_string());
}
if (negotiation_response_json.has_field(_XPLATSTR("availableTransports")))
{
for (auto transportData : negotiation_response_json[_XPLATSTR("availableTransports")].as_array())
{
available_transport transport;
transport.transport = utility::conversions::to_utf8string(transportData[_XPLATSTR("transport")].as_string());
for (auto format : transportData[_XPLATSTR("transferFormats")].as_array())
{
transport.transfer_formats.push_back(utility::conversions::to_utf8string(format.as_string()));
}
response.availableTransports.push_back(transport);
}
}
if (negotiation_response_json.has_field(_XPLATSTR("url")))
{
response.url = utility::conversions::to_utf8string(negotiation_response_json[_XPLATSTR("url")].as_string());
if (negotiation_response_json.has_field(_XPLATSTR("accessToken")))
{
response.accessToken = utility::conversions::to_utf8string(negotiation_response_json[_XPLATSTR("accessToken")].as_string());
}
}
if (negotiation_response_json.has_field(_XPLATSTR("ProtocolVersion")))
{
tce.set_exception(signalr_exception("Detected a connection attempt to an ASP.NET SignalR Server. This client only supports connecting to an ASP.NET Core SignalR Server. See https://aka.ms/signalr-core-differences for details."));
}
tce.set(std::move(response));
}
catch (...)
{
tce.set_exception(std::current_exception());
}
});
return pplx::create_task(tce);
}
}
}

View File

@ -1,19 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include "signalrclient/signalr_client_config.h"
#include "signalrclient/transport_type.h"
#include "web_request_factory.h"
#include "negotiation_response.h"
#include "signalrclient/http_client.h"
namespace signalr
{
namespace negotiate
{
pplx::task<negotiation_response> negotiate(http_client& client, const std::string& base_url,
const signalr_client_config& signalr_client_config = signalr::signalr_client_config{});
}
}

View File

@ -1,22 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
namespace signalr
{
struct available_transport
{
std::string transport;
std::vector<std::string> transfer_formats;
};
struct negotiation_response
{
std::string connectionId;
std::vector<available_transport> availableTransports;
std::string url;
std::string accessToken;
std::string error;
};
}

View File

@ -1,52 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "signalrclient/signalr_client_config.h"
#include "cpprest/http_client.h"
#include "cpprest/ws_client.h"
namespace signalr
{
void signalr_client_config::set_proxy(const web::web_proxy &proxy)
{
m_http_client_config.set_proxy(proxy);
m_websocket_client_config.set_proxy(proxy);
}
void signalr_client_config::set_credentials(const web::credentials &credentials)
{
m_http_client_config.set_credentials(credentials);
m_websocket_client_config.set_credentials(credentials);
}
web::http::client::http_client_config signalr_client_config::get_http_client_config() const
{
return m_http_client_config;
}
void signalr_client_config::set_http_client_config(const web::http::client::http_client_config& http_client_config)
{
m_http_client_config = http_client_config;
}
web::websockets::client::websocket_client_config signalr_client_config::get_websocket_client_config() const noexcept
{
return m_websocket_client_config;
}
void signalr_client_config::set_websocket_client_config(const web::websockets::client::websocket_client_config& websocket_client_config)
{
m_websocket_client_config = websocket_client_config;
}
web::http::http_headers signalr_client_config::get_http_headers() const noexcept
{
return m_http_headers;
}
void signalr_client_config::set_http_headers(const web::http::http_headers& http_headers)
{
m_http_headers = http_headers;
}
}

View File

@ -1,4 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"

View File

@ -1,23 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#ifdef _WIN32 // used in the default log writer and to build the dll
// prevents from defining min/max macros that conflict with std::min()/std::max() functions
#define NOMINMAX
#include <SDKDDKVer.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#include <functional>
#include <unordered_map>
#include "cpprest/details/basic_types.h"
#include "cpprest/json.h"
#include "pplx/pplxtasks.h"

View File

@ -1,25 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "trace_log_writer.h"
namespace signalr
{
void trace_log_writer::write(const std::string &entry)
{
#ifdef _WIN32
// OutputDebugString is thread safe
OutputDebugStringA(entry.c_str());
#else
// Note: there is no data race for standard output streams in C++ 11 but the results
// might be garbled when the method is called concurrently from multiple threads
#ifdef _UTF16_STRINGS
std::wclog << entry;
#else
std::clog << entry;
#endif // _UTF16_STRINGS
#endif // _MS_WINDOWS
}
}

View File

@ -1,15 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include "signalrclient/log_writer.h"
namespace signalr
{
class trace_log_writer : public log_writer
{
public:
void __cdecl write(const std::string &entry) override;
};
}

View File

@ -1,18 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "transport.h"
#include "connection_impl.h"
namespace signalr
{
transport::transport(const logger& logger)
: m_logger(logger)
{}
// Do NOT remove this destructor. Letting the compiler generate and inline the default dtor may lead to
// undefinded behavior since we are using an incomplete type. More details here: http://herbsutter.com/gotw/_100/
transport::~transport()
{ }
}

View File

@ -1,33 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include "pplx/pplxtasks.h"
#include "signalrclient/transport_type.h"
#include "signalrclient/transfer_format.h"
#include "logger.h"
namespace signalr
{
class transport
{
public:
virtual transport_type get_transport_type() const = 0;
virtual ~transport();
virtual void start(const std::string& url, transfer_format format, std::function<void(std::exception_ptr)> callback) noexcept = 0;
virtual void stop(std::function<void(std::exception_ptr)> callback) noexcept = 0;
virtual void on_close(std::function<void(std::exception_ptr)> callback) = 0;
virtual void send(std::string payload, std::function<void(std::exception_ptr)> callback) noexcept = 0;
virtual void on_receive(std::function<void(std::string, std::exception_ptr)> callback) = 0;
protected:
transport(const logger& logger);
logger m_logger;
};
}

View File

@ -1,25 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "transport_factory.h"
#include "websocket_transport.h"
namespace signalr
{
std::shared_ptr<transport> transport_factory::create_transport(transport_type transport_type, const logger& logger,
const signalr_client_config& signalr_client_config)
{
if (transport_type == signalr::transport_type::websockets)
{
return websocket_transport::create(
[signalr_client_config](){ return std::make_shared<default_websocket_client>(signalr_client_config); },
logger);
}
throw std::runtime_error("not implemented");
}
transport_factory::~transport_factory()
{ }
}

View File

@ -1,21 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#pragma once
#include <memory>
#include "signalrclient/signalr_client_config.h"
#include "signalrclient/transport_type.h"
#include "transport.h"
namespace signalr
{
class transport_factory
{
public:
virtual std::shared_ptr<transport> create_transport(transport_type transport_type, const logger& logger,
const signalr_client_config& signalr_client_config);
virtual ~transport_factory();
};
}

View File

@ -1,58 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#include "stdafx.h"
#include "cpprest/http_client.h"
#include "signalrclient/transport_type.h"
namespace signalr
{
namespace url_builder
{
web::uri_builder &convert_to_websocket_url(web::uri_builder &builder, transport_type transport)
{
if (transport == transport_type::websockets)
{
if (builder.scheme() == _XPLATSTR("https"))
{
builder.set_scheme(utility::conversions::to_string_t("wss"));
}
else
{
builder.set_scheme(utility::conversions::to_string_t("ws"));
}
}
return builder;
}
web::uri_builder build_uri(const std::string& base_url, const std::string& command, const std::string& query_string)
{
web::uri_builder builder(utility::conversions::to_string_t(base_url));
builder.append_path(utility::conversions::to_string_t(command));
return builder.append_query(utility::conversions::to_string_t(query_string));
}
web::uri_builder build_uri(const std::string& base_url, const std::string& command)
{
web::uri_builder builder(utility::conversions::to_string_t(base_url));
return builder.append_path(utility::conversions::to_string_t(command));
}
std::string build_negotiate(const std::string& base_url)
{
return utility::conversions::to_utf8string(build_uri(base_url, "negotiate").to_string());
}
std::string build_connect(const std::string& base_url, transport_type transport, const std::string& query_string)
{
auto builder = build_uri(base_url, "", query_string);
return utility::conversions::to_utf8string(convert_to_websocket_url(builder, transport).to_string());
}
std::string build_start(const std::string& base_url, const std::string &query_string)
{
return utility::conversions::to_utf8string(build_uri(base_url, "", query_string).to_string());
}
}
}

Some files were not shown because too many files have changed in this diff Show More