Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
MQTTnet
提交
7931af74
MQTTnet
项目概览
dotNET Platform
/
MQTTnet
10 个月 前同步成功
通知
0
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
MQTTnet
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
7931af74
编写于
4月 18, 2020
作者:
C
Christian Kratky
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add support for certificate validation callback for Web Socket connections.
上级
bb5f023b
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
224 addition
and
103 deletion
+224
-103
Build/MQTTnet.nuspec
Build/MQTTnet.nuspec
+13
-4
Build/build.ps1
Build/build.ps1
+4
-0
Source/MQTTnet/Client/MqttClient.cs
Source/MQTTnet/Client/MqttClient.cs
+1
-1
Source/MQTTnet/Client/Options/MqttClientCertificateValidationCallbackContext.cs
...Options/MqttClientCertificateValidationCallbackContext.cs
+16
-0
Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs
Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs
+1
-0
Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs
...t/Client/Options/MqttClientOptionsBuilderTlsParameters.cs
+3
-1
Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs
Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs
+4
-0
Source/MQTTnet/Diagnostics/TargetFrameworkProvider.cs
Source/MQTTnet/Diagnostics/TargetFrameworkProvider.cs
+2
-0
Source/MQTTnet/Implementations/MqttTcpChannel.cs
Source/MQTTnet/Implementations/MqttTcpChannel.cs
+22
-3
Source/MQTTnet/Implementations/MqttWebSocketChannel.cs
Source/MQTTnet/Implementations/MqttWebSocketChannel.cs
+87
-57
Source/MQTTnet/Internal/BlockingQueue.cs
Source/MQTTnet/Internal/BlockingQueue.cs
+22
-20
Source/MQTTnet/MQTTnet.csproj
Source/MQTTnet/MQTTnet.csproj
+1
-1
Tests/MQTTnet.Core.Tests/BlockingQueue_Tests.cs
Tests/MQTTnet.Core.Tests/BlockingQueue_Tests.cs
+23
-6
Tests/MQTTnet.Core.Tests/MqttClient_Tests.cs
Tests/MQTTnet.Core.Tests/MqttClient_Tests.cs
+12
-0
Tests/MQTTnet.TestApp.NetCore/Program.cs
Tests/MQTTnet.TestApp.NetCore/Program.cs
+13
-10
未找到文件。
Build/MQTTnet.nuspec
浏览文件 @
7931af74
...
...
@@ -14,12 +14,12 @@
<releaseNotes>
* [Core] Renamed some topic filter relevant classes (BREAKING CHANGE!).
* [Core] Improved task management for UWP connections (thanks to @xgstation).
* [LowLevelMqttClient]
* [Client] Added method to trigger PING/PONG manually (connection check etc.).
* [Client] Added support for certificate validation callback when using Web Sockets (requires netstandard2.1+).
* [Client] Fixed a memory leak when web socket based connections trying to reconnect with an offline server.
* [ManagedClient] Added method to trigger PING/PONG manually (connection check etc.).
* [Server]
* [MQTTnet.AspNetCore] improved compatibility with AspNetCore 3.1
* [MQTTnet.Server]
* [MQTTnet.AspNetCore] improved compatibility with AspNetCore 3.1.
* [MQTTnet.Server] Fixed wrong version output.
</releaseNotes>
<copyright>
Copyright Christian Kratky 2016-2020
</copyright>
<tags>
MQTT Message Queue Telemetry Transport MQTTClient MQTTServer Server MQTTBroker Broker NETStandard IoT InternetOfThings Messaging Hardware Arduino Sensor Actuator M2M ESP Smart Home Cities Automation Xamarin
</tags>
...
...
@@ -36,6 +36,12 @@
<dependency
id=
"System.Net.WebSockets"
version=
"4.3.0"
/>
<dependency
id=
"System.Net.WebSockets.Client"
version=
"4.3.2"
/>
</group>
<group
targetFramework=
"netstandard2.1"
>
<dependency
id=
"NETStandard.Library"
version=
"2.0.0"
/>
<dependency
id=
"System.Net.Security"
version=
"4.3.2"
/>
<dependency
id=
"System.Net.WebSockets"
version=
"4.3.0"
/>
<dependency
id=
"System.Net.WebSockets.Client"
version=
"4.3.2"
/>
</group>
<group
targetFramework=
"uap10.0"
>
<dependency
id=
"Microsoft.NETCore.UniversalWindowsPlatform"
version=
"6.2.10"
/>
</group>
...
...
@@ -55,6 +61,9 @@
<!-- .NET Standard 2.0 -->
<file
src=
"..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*"
target=
"lib\netstandard2.0\"
/>
<!-- .NET Standard 2.1 -->
<file
src=
"..\Source\MQTTnet\bin\Release\netstandard2.1\MQTTnet.*"
target=
"lib\netstandard2.1\"
/>
<!-- Universal Windows -->
<file
src=
"..\Source\MQTTnet\bin\Release\uap10.0\MQTTnet.*"
target=
"lib\uap10.0\"
/>
...
...
Build/build.ps1
浏览文件 @
7931af74
...
...
@@ -28,6 +28,7 @@ vstest.console.exe ..\Tests\MQTTnet.AspNetCore.Tests\bin\Release\netcoreapp3.1\M
&
$msbuild
..
\Source\MQTTnet\MQTTnet.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"net461"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet\MQTTnet.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"netstandard1.3"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet\MQTTnet.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"netstandard2.0"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet\MQTTnet.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"netstandard2.1"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet\MQTTnet.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"uap10.0"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
# Build the ASP.NET Core 2.0 extension
...
...
@@ -38,6 +39,7 @@ vstest.console.exe ..\Tests\MQTTnet.AspNetCore.Tests\bin\Release\netcoreapp3.1\M
&
$msbuild
..
\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"net461"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"netstandard1.3"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"netstandard2.0"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"netstandard2.1"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"uap10.0"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
# Build the Managed Client extension
...
...
@@ -45,6 +47,7 @@ vstest.console.exe ..\Tests\MQTTnet.AspNetCore.Tests\bin\Release\netcoreapp3.1\M
&
$msbuild
..
\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"net461"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"netstandard1.3"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"netstandard2.0"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"netstandard2.1"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"uap10.0"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
# Build the WebSocket4Net extension
...
...
@@ -52,6 +55,7 @@ vstest.console.exe ..\Tests\MQTTnet.AspNetCore.Tests\bin\Release\netcoreapp3.1\M
&
$msbuild
..
\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"net461"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"netstandard1.3"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"netstandard2.0"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"netstandard2.1"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
&
$msbuild
..
\Source\MQTTnet.Extensions.WebSocket4Net\MQTTnet.Extensions.WebSocket4Net.csproj
/t:Build
/p:Configuration
=
"Release"
/p:TargetFramework
=
"uap10.0"
/p:FileVersion
=
$assemblyVersion
/p:AssemblyVersion
=
$assemblyVersion
/verbosity:m
/p:SignAssembly
=
true
/p:AssemblyOriginatorKeyFile
=
".\..\..\Build\codeSigningKey.pfx"
# Create NuGet packages.
...
...
Source/MQTTnet/Client/MqttClient.cs
浏览文件 @
7931af74
...
...
@@ -61,7 +61,7 @@ namespace MQTTnet.Client
{
get
{
return
_isConnected
||
Interlocked
.
Read
(
ref
_isDisconnectPending
)
!
=
0
;
return
_isConnected
&&
Interlocked
.
Read
(
ref
_isDisconnectPending
)
=
=
0
;
}
}
...
...
Source/MQTTnet/Client/Options/MqttClientCertificateValidationCallbackContext.cs
0 → 100644
浏览文件 @
7931af74
using
System.Net.Security
;
using
System.Security.Cryptography.X509Certificates
;
namespace
MQTTnet.Client.Options
{
public
class
MqttClientCertificateValidationCallbackContext
{
public
X509Certificate
Certificate
{
get
;
set
;
}
public
X509Chain
Chain
{
get
;
set
;
}
public
SslPolicyErrors
SslPolicyErrors
{
get
;
set
;
}
public
IMqttClientChannelOptions
ClientOptions
{
get
;
set
;
}
}
}
Source/MQTTnet/Client/Options/MqttClientOptionsBuilder.cs
浏览文件 @
7931af74
...
...
@@ -262,6 +262,7 @@ namespace MQTTnet.Client.Options
Certificates
=
_tlsParameters
.
Certificates
?.
ToList
(),
#endif
CertificateValidationCallback
=
_tlsParameters
.
CertificateValidationCallback
,
CertificateValidationHandler
=
_tlsParameters
.
CertificateValidationHandler
,
IgnoreCertificateChainErrors
=
_tlsParameters
.
IgnoreCertificateChainErrors
,
IgnoreCertificateRevocationErrors
=
_tlsParameters
.
IgnoreCertificateRevocationErrors
};
...
...
Source/MQTTnet/Client/Options/MqttClientOptionsBuilderTlsParameters.cs
浏览文件 @
7931af74
...
...
@@ -10,12 +10,15 @@ namespace MQTTnet.Client.Options
{
public
bool
UseTls
{
get
;
set
;
}
[
Obsolete
(
"This property will be removed soon. Use CertificateValidationHandler instead."
)]
public
Func
<
X509Certificate
,
X509Chain
,
SslPolicyErrors
,
IMqttClientOptions
,
bool
>
CertificateValidationCallback
{
get
;
set
;
}
public
Func
<
MqttClientCertificateValidationCallbackContext
,
bool
>
CertificateValidationHandler
{
get
;
set
;
}
public
SslProtocols
SslProtocol
{
get
;
set
;
}
=
SslProtocols
.
Tls12
;
#if WINDOWS_UWP
...
...
@@ -23,7 +26,6 @@ namespace MQTTnet.Client.Options
#else
public
IEnumerable
<
X509Certificate
>
Certificates
{
get
;
set
;
}
#endif
public
bool
AllowUntrustedCertificates
{
get
;
set
;
}
...
...
Source/MQTTnet/Client/Options/MqttClientTlsOptions.cs
浏览文件 @
7931af74
...
...
@@ -15,6 +15,7 @@ namespace MQTTnet.Client.Options
public
bool
IgnoreCertificateChainErrors
{
get
;
set
;
}
public
bool
AllowUntrustedCertificates
{
get
;
set
;
}
#if WINDOWS_UWP
public
List
<
byte
[
]>
Certificates
{
get
;
set
;
}
#else
...
...
@@ -23,6 +24,9 @@ namespace MQTTnet.Client.Options
public
SslProtocols
SslProtocol
{
get
;
set
;
}
=
SslProtocols
.
Tls12
;
[
Obsolete
(
"This property will be removed soon. Use CertificateValidationHandler instead."
)]
public
Func
<
X509Certificate
,
X509Chain
,
SslPolicyErrors
,
IMqttClientOptions
,
bool
>
CertificateValidationCallback
{
get
;
set
;
}
public
Func
<
MqttClientCertificateValidationCallbackContext
,
bool
>
CertificateValidationHandler
{
get
;
set
;
}
}
}
Source/MQTTnet/Diagnostics/TargetFrameworkProvider.cs
浏览文件 @
7931af74
...
...
@@ -16,6 +16,8 @@
return
"netstandard1.3"
;
#elif NETSTANDARD2_0
return
"netstandard2.0"
;
#elif NETSTANDARD2_1
return
"netstandard2.1"
;
#elif WINDOWS_UWP
return
"uap10.0"
;
#endif
...
...
Source/MQTTnet/Implementations/MqttTcpChannel.cs
浏览文件 @
7931af74
...
...
@@ -73,7 +73,7 @@ namespace MQTTnet.Implementations
var
networkStream
=
socket
.
GetStream
();
if
(
_options
.
TlsOptions
.
UseTls
)
if
(
_options
.
TlsOptions
?.
UseTls
==
true
)
{
var
sslStream
=
new
SslStream
(
networkStream
,
false
,
InternalUserCertificateValidationCallback
);
try
...
...
@@ -181,9 +181,28 @@ namespace MQTTnet.Implementations
bool
InternalUserCertificateValidationCallback
(
object
sender
,
X509Certificate
x509Certificate
,
X509Chain
chain
,
SslPolicyErrors
sslPolicyErrors
)
{
if
(
_options
.
TlsOptions
.
CertificateValidationCallback
!=
null
)
#
region
OBSOLETE
var
certificateValidationCallback
=
_options
?.
TlsOptions
?.
CertificateValidationCallback
;
if
(
certificateValidationCallback
!=
null
)
{
return
_options
.
TlsOptions
.
CertificateValidationCallback
(
x509Certificate
,
chain
,
sslPolicyErrors
,
_clientOptions
);
return
certificateValidationCallback
(
x509Certificate
,
chain
,
sslPolicyErrors
,
_clientOptions
);
}
#
endregion
var
certificateValidationHandler
=
_options
?.
TlsOptions
?.
CertificateValidationHandler
;
if
(
certificateValidationHandler
!=
null
)
{
var
context
=
new
MqttClientCertificateValidationCallbackContext
{
Certificate
=
x509Certificate
,
Chain
=
chain
,
SslPolicyErrors
=
sslPolicyErrors
,
ClientOptions
=
_options
};
return
certificateValidationHandler
(
context
);
}
if
(
sslPolicyErrors
==
SslPolicyErrors
.
None
)
...
...
Source/MQTTnet/Implementations/MqttWebSocketChannel.cs
浏览文件 @
7931af74
using
System
;
using
MQTTnet.Channel
;
using
MQTTnet.Client.Options
;
using
MQTTnet.Internal
;
using
System
;
using
System.Net
;
using
System.Net.WebSockets
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
MQTTnet.Channel
;
using
MQTTnet.Client.Options
;
using
MQTTnet.Internal
;
namespace
MQTTnet.Implementations
{
public
class
MqttWebSocketChannel
:
Disposable
,
IMqttChannel
public
sealed
class
MqttWebSocketChannel
:
IMqttChannel
{
private
readonly
MqttClientWebSocketOptions
_options
;
readonly
MqttClientWebSocketOptions
_options
;
private
SemaphoreSlim
_sendLock
=
new
SemaphoreSlim
(
1
,
1
);
private
WebSocket
_webSocket
;
AsyncLock
_sendLock
=
new
AsyncLock
(
);
WebSocket
_webSocket
;
public
MqttWebSocketChannel
(
MqttClientWebSocketOptions
options
)
{
...
...
@@ -53,50 +53,20 @@ namespace MQTTnet.Implementations
}
var
clientWebSocket
=
new
ClientWebSocket
();
if
(
_options
.
ProxyOptions
!=
null
)
try
{
clientWebSocket
.
Options
.
Proxy
=
CreateProxy
();
}
SetupClientWebSocket
(
clientWebSocket
);
if
(
_options
.
RequestHeaders
!=
null
)
{
foreach
(
var
requestHeader
in
_options
.
RequestHeaders
)
{
clientWebSocket
.
Options
.
SetRequestHeader
(
requestHeader
.
Key
,
requestHeader
.
Value
);
}
await
clientWebSocket
.
ConnectAsync
(
new
Uri
(
uri
),
cancellationToken
).
ConfigureAwait
(
false
);
}
if
(
_options
.
SubProtocols
!=
null
)
catch
(
Exception
)
{
foreach
(
var
subProtocol
in
_options
.
SubProtocols
)
{
clientWebSocket
.
Options
.
AddSubProtocol
(
subProtocol
);
}
// Prevent a memory leak when always creating new instance which will fail while connecting.
clientWebSocket
.
Dispose
();
throw
;
}
if
(
_options
.
CookieContainer
!=
null
)
{
clientWebSocket
.
Options
.
Cookies
=
_options
.
CookieContainer
;
}
if
(
_options
.
TlsOptions
?.
UseTls
==
true
&&
_options
.
TlsOptions
?.
Certificates
!=
null
)
{
clientWebSocket
.
Options
.
ClientCertificates
=
new
X509CertificateCollection
();
foreach
(
var
certificate
in
_options
.
TlsOptions
.
Certificates
)
{
#if WINDOWS_UWP
clientWebSocket
.
Options
.
ClientCertificates
.
Add
(
new
X509Certificate
(
certificate
));
#else
clientWebSocket
.
Options
.
ClientCertificates
.
Add
(
certificate
);
#endif
}
}
await
clientWebSocket
.
ConnectAsync
(
new
Uri
(
uri
),
cancellationToken
).
ConfigureAwait
(
false
);
_webSocket
=
clientWebSocket
;
IsSecureConnection
=
uri
.
StartsWith
(
"wss://"
,
StringComparison
.
OrdinalIgnoreCase
);
}
...
...
@@ -131,27 +101,87 @@ namespace MQTTnet.Implementations
return
;
}
await
_sendLock
.
WaitAsync
(
cancellationToken
).
ConfigureAwait
(
false
);
try
using
(
await
_sendLock
.
WaitAsync
(
cancellationToken
).
ConfigureAwait
(
false
))
{
await
_webSocket
.
SendAsync
(
new
ArraySegment
<
byte
>(
buffer
,
offset
,
count
),
WebSocketMessageType
.
Binary
,
true
,
cancellationToken
).
ConfigureAwait
(
false
);
}
finally
{
_sendLock
?.
Release
();
}
}
protected
override
void
Dispose
(
bool
disposing
)
public
void
Dispose
()
{
Cleanup
();
}
void
SetupClientWebSocket
(
ClientWebSocket
clientWebSocket
)
{
if
(
disposing
)
if
(
_options
.
ProxyOptions
!=
null
)
{
clientWebSocket
.
Options
.
Proxy
=
CreateProxy
();
}
if
(
_options
.
RequestHeaders
!=
null
)
{
foreach
(
var
requestHeader
in
_options
.
RequestHeaders
)
{
clientWebSocket
.
Options
.
SetRequestHeader
(
requestHeader
.
Key
,
requestHeader
.
Value
);
}
}
if
(
_options
.
SubProtocols
!=
null
)
{
Cleanup
();
foreach
(
var
subProtocol
in
_options
.
SubProtocols
)
{
clientWebSocket
.
Options
.
AddSubProtocol
(
subProtocol
);
}
}
base
.
Dispose
(
disposing
);
if
(
_options
.
CookieContainer
!=
null
)
{
clientWebSocket
.
Options
.
Cookies
=
_options
.
CookieContainer
;
}
if
(
_options
.
TlsOptions
?.
UseTls
==
true
&&
_options
.
TlsOptions
?.
Certificates
!=
null
)
{
clientWebSocket
.
Options
.
ClientCertificates
=
new
X509CertificateCollection
();
foreach
(
var
certificate
in
_options
.
TlsOptions
.
Certificates
)
{
#if WINDOWS_UWP
clientWebSocket
.
Options
.
ClientCertificates
.
Add
(
new
X509Certificate
(
certificate
));
#else
clientWebSocket
.
Options
.
ClientCertificates
.
Add
(
certificate
);
#endif
}
}
var
certificateValidationHandler
=
_options
.
TlsOptions
?.
CertificateValidationHandler
;
#if NETSTANDARD2_1
if
(
certificateValidationHandler
!=
null
)
{
clientWebSocket
.
Options
.
RemoteCertificateValidationCallback
=
new
System
.
Net
.
Security
.
RemoteCertificateValidationCallback
((
sender
,
certificate
,
chain
,
sslPolicyErrors
)
=>
{
// TODO: Find a way to add client options to same callback. Problem is that they have a different type.
var
context
=
new
MqttClientCertificateValidationCallbackContext
{
Certificate
=
certificate
,
Chain
=
chain
,
SslPolicyErrors
=
sslPolicyErrors
,
ClientOptions
=
_options
};
return
certificateValidationHandler
(
context
);
});
}
#else
if
(
certificateValidationHandler
!=
null
)
{
throw
new
NotSupportedException
(
"The remote certificate validation callback for Web Sockets is only supported for netstandard 2.1+"
);
}
#endif
}
private
void
Cleanup
()
void
Cleanup
()
{
_sendLock
?.
Dispose
();
_sendLock
=
null
;
...
...
@@ -169,7 +199,7 @@ namespace MQTTnet.Implementations
}
}
private
IWebProxy
CreateProxy
()
IWebProxy
CreateProxy
()
{
if
(
string
.
IsNullOrEmpty
(
_options
.
ProxyOptions
?.
Address
))
{
...
...
Source/MQTTnet/Internal/BlockingQueue.cs
浏览文件 @
7931af74
...
...
@@ -4,11 +4,12 @@ using System.Threading;
namespace
MQTTnet.Internal
{
public
class
BlockingQueue
<
TItem
>
:
Disposable
public
sealed
class
BlockingQueue
<
TItem
>
:
I
Disposable
{
private
readonly
object
_syncRoot
=
new
object
();
private
readonly
LinkedList
<
TItem
>
_items
=
new
LinkedList
<
TItem
>();
private
readonly
ManualResetEventSlim
_gate
=
new
ManualResetEventSlim
(
false
);
readonly
object
_syncRoot
=
new
object
();
readonly
LinkedList
<
TItem
>
_items
=
new
LinkedList
<
TItem
>();
ManualResetEventSlim
_gate
=
new
ManualResetEventSlim
(
false
);
public
int
Count
{
...
...
@@ -28,13 +29,13 @@ namespace MQTTnet.Internal
lock
(
_syncRoot
)
{
_items
.
AddLast
(
item
);
_gate
.
Set
();
_gate
?
.
Set
();
}
}
public
TItem
Dequeue
(
CancellationToken
cancellationToken
=
default
(
CancellationToken
)
)
public
TItem
Dequeue
(
CancellationToken
cancellationToken
=
default
)
{
while
(
true
)
while
(
!
cancellationToken
.
IsCancellationRequested
)
{
lock
(
_syncRoot
)
{
...
...
@@ -48,17 +49,19 @@ namespace MQTTnet.Internal
if
(
_items
.
Count
==
0
)
{
_gate
.
Reset
();
_gate
?
.
Reset
();
}
}
_gate
.
Wait
(
cancellationToken
);
_gate
?
.
Wait
(
cancellationToken
);
}
throw
new
OperationCanceledException
();
}
public
TItem
PeekAndWait
(
CancellationToken
cancellationToken
=
default
(
CancellationToken
)
)
public
TItem
PeekAndWait
(
CancellationToken
cancellationToken
=
default
)
{
while
(
true
)
while
(
!
cancellationToken
.
IsCancellationRequested
)
{
lock
(
_syncRoot
)
{
...
...
@@ -69,12 +72,14 @@ namespace MQTTnet.Internal
if
(
_items
.
Count
==
0
)
{
_gate
.
Reset
();
_gate
?
.
Reset
();
}
}
_gate
.
Wait
(
cancellationToken
);
_gate
?
.
Wait
(
cancellationToken
);
}
throw
new
OperationCanceledException
();
}
public
void
RemoveFirst
(
Predicate
<
TItem
>
match
)
...
...
@@ -109,13 +114,10 @@ namespace MQTTnet.Internal
}
}
p
rotected
override
void
Dispose
(
bool
disposing
)
p
ublic
void
Dispose
(
)
{
if
(
disposing
)
{
_gate
.
Dispose
();
}
base
.
Dispose
(
disposing
);
_gate
?.
Dispose
();
_gate
=
null
;
}
}
}
Source/MQTTnet/MQTTnet.csproj
浏览文件 @
7931af74
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard1.3;netstandard2.0</TargetFrameworks>
<TargetFrameworks>netstandard1.3;netstandard2.0
;netstandard2.1
</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' ">$(TargetFrameworks);net452;net461</TargetFrameworks>
<TargetFrameworks Condition=" '$(OS)' == 'Windows_NT' AND '$(MSBuildRuntimeType)' != 'Core' AND '$(SolutionName)' != 'MQTTnet.noUWP' ">$(TargetFrameworks);uap10.0</TargetFrameworks>
<AssemblyName>MQTTnet</AssemblyName>
...
...
Tests/MQTTnet.Core.Tests/BlockingQueue_Tests.cs
浏览文件 @
7931af74
using
System.Threading
;
using
System.Threading.Tasks
;
using
Microsoft.VisualStudio.TestTools.UnitTesting
;
using
Microsoft.VisualStudio.TestTools.UnitTesting
;
using
MQTTnet.Internal
;
using
System
;
using
System.Threading
;
using
System.Threading.Tasks
;
namespace
MQTTnet.Tests
{
...
...
@@ -33,7 +34,7 @@ namespace MQTTnet.Tests
Assert
.
AreEqual
(
"a"
,
queue
.
RemoveFirst
());
Assert
.
AreEqual
(
"b"
,
queue
.
RemoveFirst
());
Assert
.
AreEqual
(
1
,
queue
.
Count
);
Assert
.
AreEqual
(
"c"
,
queue
.
Dequeue
());
...
...
@@ -81,7 +82,7 @@ namespace MQTTnet.Tests
}
[
TestMethod
]
public
void
Wait_For_
Time
s
()
public
void
Wait_For_
Item
s
()
{
var
number
=
0
;
...
...
@@ -104,5 +105,21 @@ namespace MQTTnet.Tests
Interlocked
.
Increment
(
ref
number
);
}
}
[
TestMethod
]
[
ExpectedException
(
typeof
(
OperationCanceledException
))]
public
void
Use_Disposed_Queue
()
{
var
queue
=
new
BlockingQueue
<
int
>();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Task
.
Run
(()
=>
{
Thread
.
Sleep
(
1000
);
queue
.
Dispose
();
});
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
queue
.
Dequeue
(
new
CancellationTokenSource
(
TimeSpan
.
FromSeconds
(
2
)).
Token
);
}
}
}
}
\ No newline at end of file
Tests/MQTTnet.Core.Tests/MqttClient_Tests.cs
浏览文件 @
7931af74
...
...
@@ -23,6 +23,18 @@ namespace MQTTnet.Tests
{
public
TestContext
TestContext
{
get
;
set
;
}
[
TestMethod
]
public
async
Task
Send_Manual_Ping
()
{
using
(
var
testEnvironment
=
new
TestEnvironment
(
TestContext
))
{
await
testEnvironment
.
StartServerAsync
();
var
client
=
await
testEnvironment
.
ConnectClientAsync
();
await
client
.
PingAsync
(
CancellationToken
.
None
);
}
}
[
TestMethod
]
public
async
Task
Send_Reply_In_Message_Handler_For_Same_Client
()
{
...
...
Tests/MQTTnet.TestApp.NetCore/Program.cs
浏览文件 @
7931af74
using
System
;
using
MQTTnet.Client.Options
;
using
MQTTnet.Diagnostics
;
using
MQTTnet.Server
;
using
Newtonsoft.Json
;
using
System
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.Net.Security
;
using
System.Security.Cryptography.X509Certificates
;
using
System.Threading
;
using
System.Threading.Tasks
;
using
MQTTnet.Client
;
using
MQTTnet.Client.Options
;
using
MQTTnet.Diagnostics
;
using
MQTTnet.Server
;
using
Newtonsoft.Json
;
namespace
MQTTnet.TestApp.NetCore
{
...
...
@@ -129,10 +127,15 @@ namespace MQTTnet.TestApp.NetCore
var
options
=
new
MqttClientOptionsBuilder
()
.
WithTls
(
new
MqttClientOptionsBuilderTlsParameters
{
CertificateValidation
Callback
=
(
X509Certificate
x
,
X509Chain
y
,
SslPolicyErrors
z
,
IMqttClientOptions
o
)
=>
CertificateValidation
Handler
=
context
=>
{
// TODO: Check conditions of certificate by using above parameters.
return
true
;
// TODO: Check conditions of certificate by using above context.
if
(
context
.
SslPolicyErrors
==
SslPolicyErrors
.
None
)
{
return
true
;
}
return
false
;
}
})
.
Build
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录