Compare commits

..
1041 Commits
Author SHA1 Message Date
christian 37631730e0 Enable nullable 2025-10-20 11:29:24 +02:00
Christian 5ebc5fcb7e Call enqueue interceptor for retained messages (fix) (#2212)
* Call the event handler also for retained messages

* Update release notes

* Add Unit Test
2025-10-19 21:21:47 +02:00
Christian 51979fa5a4 Call enqueue interceptor for retained messages (#2211)
* Call the event handler also for retained messages

* Update release notes
2025-10-19 19:14:33 +02:00
Christian 7ac7f256ef Update nugets (#2210)
* Upate nugets, fix breaking changes

* Fix CI build
2025-10-17 21:29:46 +02:00
e7ccd897b0 Use License file from code repo (#2197)
* Use License file from code repo

* Configure all relevant projects

* Update release notes

* Restore release notes

---------

Co-authored-by: Jens Nordenbro <jens.nordenbro@beijerelectronics.com>
Co-authored-by: christian <6939810+chkr1011@users.noreply.github.com>
2025-10-17 19:28:45 +02:00
Christian d5d72ac37d Enable support for AOT compilation (#2209)
* Update project files

* Update release notes
2025-10-17 19:06:28 +02:00
Christian a5ef10fddb Restore strong name (#2208)
* Restore strong name certificate

* Migrate strong name certificate loading to linux.

* Fix wrong path

* Restore version, update release notes
2025-10-17 19:05:20 +02:00
zhaowgitandChristian c97bd82334 Issues #2091 Improve the performance of RetainedMessages without subs… (#2093)
* Issues #2091 Improve the performance of RetainedMessages without subscribing to RetainedMessageChangedEvent.

* Fix build errors

* Update release notes

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2025-10-17 19:04:11 +02:00
christian 75ebf116cf Merge remote-tracking branch 'origin/master' 2025-09-14 10:47:46 +02:00
christian 2f7f55e3f5 Update version 2025-09-14 10:47:32 +02:00
Christian e43e7f8e36 Use latest language features (#2176)
* Make use of language features line AsyncDispose, init etc.

* Fix build errors

* Improve Unit Tests

* Improve Unit Tests

* Improve Unit Tests

* Update samples

* Remove obsolete benchmarks

* Code cleanup

* Improve unit tests

* Improve Unit Tests

* Fix Unit Tests

* Improve Unit Tests

* Improve Unit Tests

* Restore unit tests

* Exclude load tests from unit tests
2025-08-30 10:52:59 +02:00
timyhac 247988e633 Remove "MQTTv5 only" in documentation comments for MqttClientConnectResult.IsSessionPresent and MqttClientConnectResult.ResultCode (#2166)
* Remove "MQTTv5" from documentation comments for `IsSessionPresent`

 As far as I can tell, this is available for MQTT v3.1.1

References:
* [OASIS Standard](https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718035)
* [MQTTnet source code](https://github.com/dotnet/MQTTnet/blob/93a9d8d1dbe8dde2b7d79a37c873fae13b4f4797/Source/MQTTnet/Connecting/MqttClientConnectResultFactory.cs#L75)

* Remove "MQTTv5 only" for `ResultCode`
2025-03-29 19:11:53 +01:00
Youssef Victor 93a9d8d1db Move to MTP (#2163) 2025-03-02 11:59:33 +01:00
Christian 24c418cf43 Update README.md 2025-01-07 18:57:58 +01:00
Lucas Tandchristian 948c7c2b69 Corrected Cancellation Source for KeepAlive Messages (#2129)
* Corrected Cancellation Source for KeepAlive Messages

* Use half of the keep alive value for the ping timeout

* Update release notes

* Update ReleaseNotes.md

* Update ReleaseNotes.md

* Update ReleaseNotes.md

---------

Co-authored-by: christian <6939810+chkr1011@users.noreply.github.com>
2025-01-02 12:17:05 +01:00
christian 1cdc343e6d Update release notes 2025-01-02 12:11:57 +01:00
27771f0146 Improve session message injection (#2117)
* Improve session message injection methods

* Add more tests for session injection

* Change return type from MqttPublishPacket to MqttPacketWithIdentifier

* Use dedicated type for MattApplicationMessage injection result

* Code review minor fixes

* Apply project code style

* Update release notes

---------

Co-authored-by: Anton Smolkov <anton.smolkov@idp.zyfra.com>
Co-authored-by: christian <6939810+chkr1011@users.noreply.github.com>
2025-01-02 11:51:46 +01:00
christian e7de2b913a Increase version 2025-01-02 11:34:14 +01:00
christian 3dd3279656 Fix missing release notes in nuget package 2025-01-02 11:34:08 +01:00
christian c5934bf18b Reset release notes 2025-01-02 11:22:19 +01:00
christian 7715bf37dc Remove package suffix for final release version 2024-12-30 11:54:00 +01:00
Christian 9dbe1e4b12 Fix support for enhanced authentication (#2132)
* Implement enhanced authentication for client and server.

* Update samples

* Add abstraction layer

* Merge master

* Use dedicated class for public API.

* Update release notes

* Rename methods to fit naming scheme

* Fix unit tests and samples
2024-12-25 14:17:20 +01:00
christian f13b3eb6bb Update release notes 2024-12-23 12:17:00 +01:00
Anton SmolkovandAnton Smolkov 8eb884fa5d Add ability to get session from server by client id (#2131)
Co-authored-by: Anton Smolkov <anton.smolkov@idp.zyfra.com>
2024-12-23 12:05:09 +01:00
Victornorandchristian 9f81a2bb71 Add deflate compressions options to MqttClientWebSocketOptionsBuilder (#2127)
* fix: unused tryPrivate parameter in WithTryPrivate

* Fix wrong usage of try private

* feat: add option to provide deflate compression options to WebSocketOptionsBuilder

---------

Co-authored-by: christian <6939810+chkr1011@users.noreply.github.com>
2024-12-23 11:21:46 +01:00
老九andchristian e2f8d0f0ac Added UserName property to various Server EventArgs. (#2123)
* Added UserName property to various Server EventArgs.

* InjectedMqttApplicationMessage: Add SenderUserName property.

* Reformat code

* Reformat code

---------

Co-authored-by: christian <6939810+chkr1011@users.noreply.github.com>
2024-12-10 19:44:38 +01:00
Victornorandchristian 981ea02149 Unused parameter in WithTryPrivate causing client to send incorrect version byte in header. (#2125)
* fix: unused tryPrivate parameter in WithTryPrivate

* Fix wrong usage of try private

---------

Co-authored-by: christian <6939810+chkr1011@users.noreply.github.com>
2024-12-10 19:37:29 +01:00
Christian 8566fd5395 Replace all _DataTestMethod_ (#2119)
* Replace all DataTestMethod with TestMethod.

* Update test nugets
2024-12-03 11:40:06 +01:00
老九andchristian 8089c6bdbc Added EndPoint RemoteEndPoint {get;} property to channel (#2111)
* Added EndPoint RemoteEndPoint{get;} property

* Reformat code

* Reformat code

---------

Co-authored-by: christian <6939810+chkr1011@users.noreply.github.com>
2024-12-02 11:52:24 +01:00
christian ef5b6c9b32 Merge remote-tracking branch 'origin/master' 2024-12-02 11:22:11 +01:00
christian 4aa4a12e47 Update release notes 2024-12-02 10:40:05 +01:00
老九 6bf2b4eaca Cannot set any properties of tcpOptions when with WebSocketServer. (#2118) 2024-12-02 10:24:03 +01:00
老九 6ef6b57064 Improve the compatibility of MqttClientOptionsBuilder.WithConnectionUri() (#2107)
* Improve the compatibility of MqttClientOptionsBuilder.WithConnectionUri() method.

* Force UseTls to true for secure schemes.

* Add support for UnixDomainSocket.
2024-12-01 14:10:58 +01:00
老九 7d4027958c Set the default value of SslProtocol to SslProtocols.None. (#2106)
* Set the default value of SslProtocol to SslProtocols.None.

* Add summary of SslProtocol.
2024-12-01 14:06:19 +01:00
老九 bdb74642c2 MqttClientFactory: Fix CreateLowLevelMqttClient not using method parameters (#2110)
* Fix CreateLowLevelMqttClient not using method parameters.

* Remove UseClientAdapterFactory()
2024-11-30 13:46:36 +01:00
Andrea Vouk 63d85184e1 Convert null checks to modern ThrowIfNull checks (#2089)
Convert null check to modern ThrowIfNull checks
2024-10-26 11:41:58 +02:00
Christian 0506857f0d Set max pending mesages per client to 1000 (#2096)
Set max pending mesages per client to 1000.
2024-10-26 11:41:25 +02:00
christian 6417baa081 Fix nuget publish 2024-10-22 11:08:29 +02:00
christian 74bb68ad73 Improve CI 2024-09-22 20:15:50 +02:00
Christian 81a4e7cb86 Pass cancellation token to TCP listeners (#2082) 2024-09-15 16:08:21 +02:00
Christian 2fdbb02dc8 Fix parsing error of AUTH packet with empty body (#2070)
* Reformat code

* Fix issue

* Fix AUTH packet serialization
2024-09-07 09:49:10 +02:00
christian c4eb05105b Update release notes 2024-08-24 12:04:24 +02:00
christian bda21f0fcd Fix build errors 2024-08-24 12:04:14 +02:00
980a5d0a6d Improve performance and drop support for old frameworks (#2068)
* Remove WebSocket4Net extension library

* Remove UWP support

* Drop support for all old frameworks

* Update CI

* Update CI

* Update CI

* Update CI

* Remove obsolete code

* Set default protocol version to 5.0.0

* Remove obsolete tests

* Remove old dependencies

* Reset release notes

* Move server to dedicated project

* Fix unit tests

* Update and cleanup nuget packages

* Fix unit tests
Refactor code

* No longer throw exception when receiving non success CONNACK

* Enable nuget signing

* Enable nuget signing

* Enable nuget signing

* Enable nuget signing

* Enable nuget signing

* Enable nuget signing

* Enable nuget signing

* Enable nuget signing

* Enable code signing

* Enable code signing

* Enable code signing

* Fix client endpoint handling

* Improve CI

* Fix CI

* Fix CI

* Fix CI

* Fix CI

* Import changes from version 4

* Cleanup target frameworks and remove obsolete code

* Drop support for dotnet7.0

* Remove managed client

* Version5 auditmode (#2016)

Added NuGet audit mode and some other settings to get informed about security issues.

* Address warnings from analyzers

* Support for ReadOnlySequence as payload (#2046)

* use ReadOnlySequence as payload

* fix build

* fix build

* skip sign in forks

* remove unnecessary owner

* tests and extensions

* remove test

* simplify WritePacketBuffer, remove unused helper

* Adjust namespaces

* Fix build errors

* Import latest fixes from main branch

* Adjust namespaces

---------

Co-authored-by: SeppPenner <HansM2013@gmx.de>
Co-authored-by: Martin Regen <mregen@microsoft.com>
2024-08-24 11:47:21 +02:00
pigwing e18a91a4b5 fix LoadingRetainedMessageAsync not exec (#2025)
because IHostedService StartAsync before startup Configure
see https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-8.0#ihostapplicationlifetime
2024-06-22 15:24:25 +02:00
drelidan7 b95d352236 Switch SubscribeAsync/UnsubscribeAsync to IEnumerable<string> (#2026)
The function currently requires an ICollection<string>, but doesn't actually depend on the ICollection<string> interface.  Relax the requirement to be IEnumerable<string> for better flexibility.
2024-06-22 14:55:20 +02:00
simonthum c5f4cf1f9b Topic template extension maintenance (#2022)
* Topic templates: Ensure parameter values are checked for wildcard

* Topic templates: Complement extension methods

- add template.BuildMessage()
- add subscribeOptionsBuilder.WithTopicTemplate()

* Topic templates: switch some samples to use a topic template

The changes should be self-explanatory and are
intended to provide more examples.

* Topic templates: add README
2024-06-22 14:54:11 +02:00
Josua Jäger 8650002523 fix Managed_Client_Subscribe_Samples.Connect_Client sample: (#2023)
- Result was never logged (`bool subscribed`)
- `subscribed` was never set, as it was not passed as a reference but as a value.
2024-06-21 19:05:12 +02:00
Christian 25c1da6a21 Restore behavior of _Server_ and _Port_ in client options (#2009)
* Restore old server and port behavior

* Fix unit test
2024-05-23 19:32:22 +02:00
christian 4e3ede42c6 Increase version 2024-05-21 22:36:34 +02:00
Christian 918a3c8d8b Restore old signing to get out hotfix release (#2004) 2024-05-19 16:39:49 +02:00
Christian 290419b3b6 [Client] Fix endpoint handling (#1999)
* Fix endpoint handling

* Fix different behavior for Mono framework.

* Restore old properties to avoid breaking changes
2024-05-19 12:18:12 +02:00
Christian 32b6146532 Setup nuget signing (#2001)
* Setup signing

* Update release notes
2024-05-18 20:21:09 +02:00
Christian 3a73ec21f7 [Client] Restore _WithConnectionUri_ methods (#1998)
Remove obsolete attributes
2024-05-17 17:49:33 +02:00
Christian 41d5b70344 Fix support for unix sockets (#1995)
* Add support for changing the protocol type on socket level

* Do not set NoDelay when not supported by protocol

* Update release notes

* Fix release notes
2024-05-14 18:09:33 +02:00
yztandChristian b4769778af DISCONNECT packet should allow zero-length body (#1994)
* DISCONNECT packet should allow zero-length body

> [If the Remaining Length is less than 1 the value of 0x00 (Normal disconnection) is used.](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901208)

* Update release notes and add comment

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2024-05-14 18:08:54 +02:00
christian 473f9c31b1 Fix unit tests 2024-05-12 11:37:33 +02:00
christian ae4f168066 Fix build 2024-05-12 11:23:03 +02:00
christian c5578a93e8 Fix Unit Tests 2024-05-11 11:21:11 +02:00
christian f4b2a10616 Fix build errors and several warnings 2024-05-09 18:39:08 +02:00
ed63aa4910 Fix comment typos/text, refactor if-else chains to switch statements, optimize return statements, and invert conditional logic (#1961)
* Fix comment typos and refactor if-else chains to switch statements.

* Refactor code

---------

Co-authored-by: Wilmar Arias <wilmar.arias@keylinx.se>
Co-authored-by: christian <6939810+chkr1011@users.noreply.github.com>
2024-05-09 18:21:00 +02:00
dcharlesandchristian 4481869d42 fix: time out and cancel propagation in managed client (#1987)
* fix: time out and cancel propagation in managed client

* Update release notes

* Refactor code

---------

Co-authored-by: christian <6939810+chkr1011@users.noreply.github.com>
2024-05-07 19:16:32 +02:00
fazhoandchristian abbf14b1ec rethrow MqttClientUnexpectedDisconnectReceivedException when Publish … (#1974)
* rethrow MqttClientUnexpectedDisconnectReceivedException when Publish errors out because server disconnects the client and QoS is 0

* use a local var to cache _unexpectedDisconnectPacket

* Add inner exception to new exception

* Update release notes

* set the default inner exception as null

---------

Co-authored-by: christian <6939810+chkr1011@users.noreply.github.com>
2024-05-07 18:31:16 +02:00
Christian 4f9e54ba1d Expose certificate selection in client options (#1984)
* Expose certificate selection in MQTTnet options

* Fix .NET Framework builds

* Update release notes
2024-05-02 22:05:33 +02:00
Christian d80188167a Restore support for null in _AddServer_ method in ASP.NET integration (#1981)
* Upgrade ASP test project to dotnet8.

* Fix broken null support for _AddMqttServer_ method.

* Fix wrong code style

* Downgrade to dotnet7.0

* Expose certificate selection in MQTTnet options

* Revert "Expose certificate selection in MQTTnet options"

This reverts commit f7d098a119.

* Update release notes
2024-05-01 20:08:25 +02:00
Christian 4ab956abd1 Change behavior of NoMatchingSubscribers (#1975)
Change behavior of NoMatchingSubscribers.
2024-04-26 18:35:39 +02:00
simonthum 1aa91e3828 Fix unit tests for topic templates (#1976) 2024-04-26 18:35:27 +02:00
simonthumandchristian 2410d7b4c1 Utility class supporting dynamic topics using topic templates (#1932)
* Add MqttTopicTemplate

The topic template class is a way to deal with dynamic topics that
is less cumbersome and error-prone than String.Format or
other string fu one might use to handle dynamic topics.

Example:

  MyCity/{street}/{crossing}/lights

'street' and 'crossing' would be parameters.

The class and its extension methods are intended to support
dynamic subscription/publication, message-topic matching and
routing. The template syntax is modelled after the well-known
moustache syntax, which conincidentally is also published
as the 'AsyncAPI channel address expressions'.

* Add MQTTnet.Extensions.TopicTemplate to solution

* Apply code style from team shared resharper settings.
Add missing file headers.

* Update release notes

---------

Co-authored-by: christian <6939810+chkr1011@users.noreply.github.com>
2024-04-23 20:09:56 +02:00
Guiorgy b7328e5fd2 fixed a comment typo (#1973) 2024-04-23 20:09:39 +02:00
christian 7f5c437c46 Fix unit tests 2024-04-11 22:26:39 +02:00
christian ae5e038548 Merge remote-tracking branch 'origin/master' 2024-04-09 21:34:31 +02:00
christian 67e0fb8b0b Fix build errors by no longer using not supported language features for certain TFMs. 2024-04-09 21:34:15 +02:00
Marc PiulachsandChristian b763542329 Move "Client is not connected" error to it's own exception (#1954)
* Move "Client is not connected" error to it's own exception

* Update MqttClientNotConnectedException.cs

* Update release notes

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2024-04-09 21:26:59 +02:00
christian d061da6077 Update release notes 2024-04-09 21:24:39 +02:00
Andriy Tolstoy 82a235aef4 remove select method (#1959) 2024-04-09 21:18:09 +02:00
James Thompson fd55982d98 #1957 Invert the logic to improve maintainance (#1958)
#1957 Invert the logic to improve maintaince
2024-04-01 22:13:48 +02:00
aabf180b23 1862 Add subscribe and unsubscribe results event for Managed Mqtt Client. (#1894)
* See the issue #1862

Adding an event when ManagedMqttClient actually subscribe/unsubscribe to topics.
This event has to be used in parallel with connected event to know the exact state.

* Rename SubscriptionsResultAsync to SubscriptionsChangedAsync.

* Rename internal field for event

* Update ReleaseNotes.md

---------

Co-authored-by: Pierre Dufrene <pierre.dufrene@se.com>
Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2024-03-02 09:58:42 +01:00
Christian 1245d8299a Merge branch 'master' of https://github.com/dotnet/MQTTnet 2024-03-02 08:45:03 +01:00
yztandChristian 1ffffaff47 Fix minor bug in MqttV5PacketEncoder.cs (#1939)
* Fix minor bug in MqttV5PacketEncoder.cs

* Update ReleaseNotes.md

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2024-03-02 09:44:14 +01:00
Christian c204f6d8b2 Make packet inspector fully async (#1941)
* Make packet inspector methods async.

* Update release notes
2024-03-02 09:28:56 +01:00
Christian b775fb256b Update version 2024-03-02 08:44:57 +01:00
Christian f82d382f23 Merge remote-tracking branch 'origin/master' 2024-02-14 17:54:04 +01:00
Christian 4214af283a Update ReleaseNotes.md 2024-02-14 17:47:29 +01:00
Christian b32a5c9fa0 Update ReleaseNotes.md 2024-02-14 17:44:16 +01:00
Sean Hanna e7e13a631f implement intercept publish message event on ManagedMqttClient (#1915)
* implement intercept publish message event on ManagedMqttClient

* rename ShouldPublish to ACceptPublish per PR feedback
2024-02-14 17:43:45 +01:00
Christian c12096705f 1908 support unix domain sockets (#1919)
* Add support for custom endpoints

Add overlaods etc. to allow for passing other endpoint implementations

* Extend publich broker test to also probe with different protocol versions

* Fix UWP build

* Update ReleaseNotes.md
2024-02-06 17:37:07 +01:00
Christian eb25500f50 1889 no service for type mqttnetservermqttserver has been registered (#1892)
* Add missing service to service collection

* Update ReleaseNotes.md

* Restore service registrations
2023-12-08 18:01:19 +01:00
Christian 4df06980a1 1883 in a weak network environment the mqtt broker is unable to detect disconnections (#1891)
* Add new setting

* Align keep alive handling with RFC

Only completely sent packets are treated as keep alive

* Update ReleaseNotes.md
2023-12-07 17:49:03 +01:00
Christian f3499013f4 Increase version 2023-12-07 17:48:14 +01:00
Christian 158a7fca46 Reset release notes 2023-12-07 17:47:57 +01:00
kallayjandChristian 09ab30fb0f Adds events for delivered and dropped messages. (#1866)
* Adds events for delivered and dropped messages.

* Rename new events to match other namings

* Update ReleaseNotes.md

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2023-12-06 18:02:48 +01:00
Christian ae84aa43d2 1846 server mqttserverstopasync doesnt indicate correct reason (#1872) 2023-11-25 16:17:16 +01:00
RidoandChristian b431a5d3fe Add ReasonCode to SendExtendedAuthenticationExchangeDataAsync (#1882)
* add reason code to ext auth

* Update ReleaseNotes.md

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2023-11-25 15:45:10 +01:00
Christian b9683c2943 Improve client disconnect (#1873)
Imrpove client disconnect
2023-11-05 15:15:36 +01:00
Christian 1ba8f74555 Update version 2023-11-04 13:40:28 +01:00
Christian ec637f7946 Handle unobserved tasks exceptions (#1871)
* Access exception so that it will not treated as unhandled

* Refactor code

* Improve unit tests

* Fix null reference exception

* Update ReleaseNotes.md
2023-11-04 13:39:16 +01:00
Christian 2599b3dfdc Update settings for tests project so that it will build on linux (#1860)
* Update settings for tests project so that it will build on linux

* Improve unit tests and samples

* Remove no longer required target frameworks for unit tests

* Update ci.yml
2023-11-01 09:34:18 +01:00
Christian d22caa7b70 Update readme (#1870)
* Update ReleaseNotes.md

* Apply project code style
2023-11-01 09:26:18 +01:00
Rido 01c90badf9 Support custom CA chain validation (#1851)
* Add CaFile based on SslStream CustomTrust

* change to cert collection

* do not require to disable revocation checks
2023-11-01 09:22:13 +01:00
Diego2098andChristian e4f605fbd5 Update MqttServer.cs (#1858)
* Update MqttServer.cs

clientID is null => RetainedMessageChangedEventArgs ctor throw new ArgumentNullException(nameof(clientId)

* Update ReleaseNotes.md

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2023-11-01 08:29:19 +01:00
Christian 6fdee9e0db Fix wrong TLS usage (#1833)
* Fix wrong usage of TLS options

* Fix public broker tests

* Update ReleaseNotes.md
2023-09-06 20:08:35 +02:00
Christian cae7206733 Fix NullReferenceException when calling Ping (#1834)
* Check connection status before doing ping

* Fix broken reconnect sample

* Update ReleaseNotes.md
2023-09-06 20:08:13 +02:00
Christian e2e7aacc09 Update version and release notes 2023-09-06 20:07:45 +02:00
Ramon Smits 0d3dd96f2a Samples that show concurrent processing (#1803)
Samples that show concurrent processing with a limit and concurrent processing without auto ACK
2023-09-01 19:01:49 +02:00
Tomáš Jecha e0660ba887 #1810 Close connection after failed connect. (#1811) 2023-09-01 18:58:36 +02:00
Ivan BeňovicandChristian 5965ded488 Add possibility to specify parameter to RPC invocation (#1798)
* Add possibility to specify parameter to RPC invocation which will be accessible in TopicGenerationContext.

* Make parameters optional

* Update ReleaseNotes.md

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2023-09-01 18:57:22 +02:00
Christian fc31c3077c Fix Unit Tests 2023-08-22 20:02:47 +02:00
Christian e604345e65 Update version 2023-08-19 15:23:10 +02:00
ChristianandSean Hanna 111a0d69cf Add support for hot reloading of client certificates (#1783)
* Refactor Unit Tests

* Add new certificate provider interface instead of read only certificates list.

* Update ReleaseNotes.md

* Fix Unit Tests

* Fix build

* unit testing hot swappable certificates (#1787)

* Move test classes to correct namespace

* Apply code style

---------

Co-authored-by: Sean Hanna <hannasm@users.noreply.github.com>
2023-08-19 15:14:05 +02:00
trokyandChristian 1a08ec17ba Added certificate validation callback for .NET framework 4.x (#1806)
* Added certificate validation callback for .NET framework 4.x

* Update ReleaseNotes.md

* Also expose sender to event arguments

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2023-08-19 14:20:01 +02:00
Ramon SmitsandChristian c537d290c3 Only logging "Client will now throw an _MqttConnectingFailedException_." warning when actually throwing the exception (#1801)
* Warning was always logged

Warning was always logged while the text states it would throw a `MqttConnectingFailedException` exception

* Update ReleaseNotes.md

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2023-08-19 13:59:14 +02:00
Cynthia MacLeodandChristian 2180f59725 Address issue #1818 where MqttConnectionContext throws an error when passed a TcpConnection. (#1819)
* Address issue #1818 where MqttConnectionContext throws and error when passed a TcpConnection.

* Update ReleaseNotes.md

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2023-08-19 13:48:01 +02:00
Ramon SmitsandChristian b1dc8607af Moved check on Options.ValidateFeatures below ThrowIf methods to prevent NullReferenceException (#1800)
* Moved check on Options.ValidateFeatures below ThrowIf methods to prevent NullReferenceException

* Add Unit Test

* Update ReleaseNotes.md

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2023-08-13 18:38:37 +02:00
simonthum 101898695e Add will message expiry interval to builder (#1804)
This was missing from builder but not regular options.
2023-08-13 18:06:16 +02:00
Christian 9295626503 [Server] Add initial support for session expiration (#1776) 2023-06-27 19:32:08 +02:00
Christian 18614d4e81 Expose configuration of packet fragmentation in server options. (#1769) 2023-06-15 18:51:43 +02:00
Christian 560e80455f Update samples (#1768) 2023-06-15 18:32:28 +02:00
HansM a97e88be29 Update Client_Subscribe_Samples.cs (#1766)
Fixes https://github.com/dotnet/MQTTnet/issues/1765.
2023-06-15 17:31:01 +02:00
logicaloudandChristian 3b5667c882 Fix #1761: MQTTRetainedMessageManager, return task with NULL result instead of NULL (#1762)
* Return task with NULL result instead of NULL

* move Task.FromResult call out of lock

* Update ReleaseNotes.md

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2023-06-12 21:52:54 +02:00
Nicke BroströmandChristian 0790e54794 Websockets no longer working in Blazor WebAssembly (#1755)
* Fix for websockets not applying properties unless explicitly set

* Added comment indicating why properties can't be set

* Update ReleaseNotes.md

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2023-06-12 21:48:27 +02:00
Christian 94f9fac2bd Update ReleaseNotes.md 2023-05-29 16:48:50 +02:00
Christian 8ad86928f1 1681 misleading signature of mqttclientconnectasync mqttclientconnectresultcode expected but throws exception (#1749) 2023-05-29 16:29:16 +02:00
Christian d8e5936d45 1724 nullreferenceexception on mqttclientconnectasync (#1748)
Update MqttClient.cs
2023-05-29 13:55:36 +02:00
Christian caa717544b 1742 some bug in mqttclientconnectionvalidatorhandle (#1746) 2023-05-29 13:53:42 +02:00
Christian 66b77f8d6d Merge branch 'master' of https://github.com/dotnet/MQTTnet 2023-05-29 13:47:09 +02:00
Christian ab5264c8ca 1738 userproperties in clientconnectedeventargs (#1747) 2023-05-29 13:45:44 +02:00
Christian db12309bae Update ReleaseNotes.md 2023-05-29 12:41:28 +02:00
Christian 2953e0dcc5 Improve payload to string conversion 2023-05-29 12:41:24 +02:00
Ramon Smits 1b18ac9fe3 Resolve ConvertPayloadToString resulting in ArgumentNullException (#1745)
Resolve breaking change where previously ConvertPayloadToString returned null if the payload was null
2023-05-29 12:38:33 +02:00
Christian 2cdad6622a Fix build 2023-05-14 09:14:37 +02:00
Andrei Kurosh 7601d11a7a UseDefaultCredentials options for WebSockets proxy configuration. (#1734) 2023-05-14 08:58:57 +02:00
Christian 0bb4c6ef09 Expose more TLS options (#1737) 2023-05-13 12:08:52 +02:00
Christian 449624fd72 Expose proper connect result in clients Disconnected event (#1728) 2023-05-06 12:49:41 +02:00
Christian 99f4f46062 Add new overloads for packet payload and will payload (#1721) 2023-05-04 22:19:06 +02:00
b08d11c069 replace lock/semaphore by readerwriterlockslim to avoid lock contenti… (#1716)
* replace lock/semaphore by readerwriterlockslim to avoid lock contention while dispatch messages

* Update MqttClientSubscriptionsManager.cs

removed comment out codes

* Update ReleaseNotes.md

---------

Co-authored-by: Zeheng Feng <hf944813@broadcom.com>
Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2023-05-01 13:53:15 +02:00
Christian ac41e838ec Merge branch 'master' of https://github.com/dotnet/MQTTnet 2023-05-01 12:20:26 +02:00
Christian 836ddf3bbc Update version 2023-05-01 12:20:20 +02:00
Christian 0e815c626c Add validation of string lengths (#1718) 2023-05-01 12:03:23 +02:00
Christian 4b7d035e9e Reset release notes 2023-04-29 12:37:36 +02:00
Christian cb3c44f48d Rename InspectPackage method (#1713) 2023-04-23 13:57:59 +02:00
Christian 8b3b9d33de Add overloads for options builder (#1711)
* Add new overload for options builder

* Refactor code

* Update ReleaseNotes.md
2023-04-11 22:11:16 +02:00
scottbrogden-iheartmediaandChristian 59d99509c8 Notify what subscription topics failed as part of the SynchronizingSu… (#1678)
* Notify what subscription topics failed as part of the SynchronizingSubscriptionsFailedAsync callback

* Update ReleaseNotes.md

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2023-04-08 14:03:58 +02:00
RossHNPCandChristian 2933b76237 ClientMessageQueueInterceptor continues with subscription processing. (#1685)
* ClientMessageQueueInterceptor continues with subscription processing.

* Update readme

---------

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2023-04-06 17:55:33 +02:00
ChristianandMichi 36c6d8974e Allow disabling of packet fragmentation (#1709)
* Add compatibility option for AWS

* Fix UWP build

* Fix comment in MqttClientOptions (#1706)

* Refactor naming

* Fix wrong option value

---------

Co-authored-by: Michi <michael@volz.dev>
2023-04-06 17:54:36 +02:00
Christian d6cab76728 Add user properties to event args to interceptors for subscribing and unsubscribing (#1707)
Add user properties to event args
2023-04-06 17:31:42 +02:00
Christian b4f740f338 Update readme 2023-04-05 22:12:58 +02:00
Christian a004de25ac Fix unit test 2023-02-22 21:46:33 +01:00
老九 d0584413ca Add PayloadSegmentable feature (#1585) 2023-02-22 20:53:55 +01:00
Christian ba57537108 Fix running state handling in server (#1680)
Fix running state handling
2023-02-17 21:17:31 +01:00
Christian 6dcb110737 Add InterceptingClientEnqueueAsync event (#1679) 2023-02-17 19:13:06 +01:00
Christian b599a832da Add new method for reading a single retained message (#1676) 2023-02-15 19:46:37 +01:00
Christian 9cbd5dd778 Update ReleaseNotes.md 2023-01-28 13:08:24 +01:00
Christian ed31c51237 Code cleanup 2023-01-28 13:08:21 +01:00
Christian e01707d25e Improve samples 2023-01-28 13:08:08 +01:00
Jeffery MichaelandJeff Scherrer 73f118fe1c Moved the usage of certificate provider into the server listener (#1652)
* Moved the usage of certificate provider into the server listener so that each connection has the posibility of receiving a new SSL cert.

* Removed warning from unused field.

* Reduced changeds on original codebase.

---------

Co-authored-by: Jeff Scherrer <Jeff.Scherrer@vw.com>
2023-01-28 12:18:31 +01:00
Int32Overflow 0234918f30 Performance impact fix (#1661) 2023-01-28 12:12:20 +01:00
Jeffery Michael c90ba7e061 Fixed broken UWP build (#1655)
Added compiler declaritive to check for WINDOWS_UWP on IsAssignableFrom call.
2023-01-28 12:02:22 +01:00
Christian 2aa4219838 Expose server session items (#1638)
* Expose server session items

* Add support for custom session items for injected application messages
2023-01-19 20:15:15 +01:00
Günther Foidl b98417ab39 Avoid some full memory barriers (#1590)
* Avoid some full memory barriers

* Reset in stats itself

* Updated MqttClientStatistics

* Fixed order of members as artifact from merge-conflict
2023-01-19 20:08:51 +01:00
Christian ead58dd606 Update ci.yml 2022-12-28 13:59:05 +01:00
Christian a93e935585 Update ci.yml 2022-12-28 09:37:01 +01:00
Christian aeb07e880e Update ReleaseNotes.md 2022-12-28 09:25:33 +01:00
Jeffery Michael e0ce1f309e dotnet 7 packages (#1636)
* Added dotnet 7 support/builds.

* Added NETCOREAPP_3_1_OR_GREATER where applicable.
2022-12-28 09:20:11 +01:00
Christian d74c81c3d1 Fix unit tests 2022-12-23 20:01:13 +01:00
Christian 2fa7200fb3 1544 add underlying socketoption of tcp keepalive into the server option (#1606)
* Expose TCP keep alive options to options builder

* Update ReleaseNotes.md
2022-12-23 17:15:49 +01:00
Christian 9f7d15e1b1 Update ReleaseNotes.md 2022-12-23 17:13:25 +01:00
Christian fdf00f1b18 More options for disconnect (#1557)
* Expose more options in disconnect options.

* Expose more options in disconnect API.

* Refactor code.

* Expose user properties in disconnected event.

* Expose more disconnect options in server.

* Fix build errors

* Add new samples.

* Fix client cleanup

* Fix merge conflicts
2022-12-23 17:09:02 +01:00
ghord abe7bbda15 Pass correct clientId to Unsubscribe interceptor (#1631) 2022-12-23 17:02:03 +01:00
ChristianandHansM 795139d78f Add feature validations (#1527)
* Add feature validation.

* Update ReleaseNotes.md

* Add validators or subscribe and unsubscribe.

* Add feature validation for disconnect.

* Fix build errors.

* Fix build errors

Co-authored-by: HansM <HansM2013@gmx.de>
2022-12-23 16:56:11 +01:00
Christian c7390ef0d7 Update verison 2022-12-23 16:51:13 +01:00
老九andGünther Foidl 8a926a3db3 Performance optimization of SendPacketAsync (#1624)
* performance optimization of SendPacketAsync

* Update Source/MQTTnet.AspnetCore/MqttConnectionContext.cs

Co-authored-by: Günther Foidl <gue@korporal.at>

Co-authored-by: Günther Foidl <gue@korporal.at>
2022-12-16 17:13:11 +01:00
soyoo 7d5e49b44c A typo in comment. (#1628) 2022-12-16 17:12:46 +01:00
Christian 555c3eac7a Reset release notes 2022-12-13 17:15:43 +01:00
Christian f79649d71b 1612 mqttserver subscription to similar base and subtopic with wildcards fails (#1622) 2022-12-07 20:59:52 +01:00
dependabot[bot] c9c27b9f01 Bump Newtonsoft.Json from 13.0.1 to 13.0.2 in /Source/MQTTnet.TestApp (#1621)
Bumps [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json) from 13.0.1 to 13.0.2.
- [Release notes](https://github.com/JamesNK/Newtonsoft.Json/releases)
- [Commits](https://github.com/JamesNK/Newtonsoft.Json/compare/13.0.1...13.0.2)

---
updated-dependencies:
- dependency-name: Newtonsoft.Json
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-07 20:57:29 +01:00
Christian 0bc47cf853 Improve unit tests 2022-12-07 20:50:34 +01:00
Christian 5649328bc5 Update release notes 2022-12-07 20:44:30 +01:00
Christian 726dd15c5a Cleanup projects 2022-12-07 20:44:23 +01:00
Christian d513c6f85c Refactor code 2022-12-07 19:43:10 +01:00
老九 c1c17ba162 MqttConnectionContext: Adapting mqtt over tcp (#1616)
Adapting mqtt over tcp.
2022-12-07 19:36:13 +01:00
soyoo f8aa686557 A typo in comment. (#1618) 2022-12-07 17:08:15 +01:00
Christian d7eb4bbe6e Allow interception of will messages (#1613) 2022-12-06 20:28:01 +01:00
Christian c17a350796 1595 object disposed exception in unit test handle parallel connection attempts (#1610) 2022-12-05 19:22:18 +01:00
Christian bb106f8c6e Refactor code 2022-12-05 19:21:08 +01:00
老九 09e47fb5eb Avoid a split MqttPacketBuffer transfer caused by triggering PipeWriter.WriteAsync twice. (#1609)
Avoid a split MqttPacketBuffer transfer caused by triggering PipeWriter.FlushAsync twice.
2022-12-05 19:19:31 +01:00
Christian 099209fff2 Update README.md 2022-12-04 14:10:54 +01:00
Christian d572490a67 Use the net452 supporting async task completion source (#1607) 2022-12-04 13:39:50 +01:00
Christian 180e7f79d4 Update ci.yml 2022-12-03 14:50:30 +01:00
Christian d9da7cc92e Refactor code 2022-12-03 14:09:27 +01:00
Christian c2ce2044cc Merge branch 'master' of https://github.com/dotnet/MQTTnet 2022-12-03 13:19:38 +01:00
Christian e400bfb79e Update ci.yml 2022-12-03 13:19:37 +01:00
老九andChristian 3d32faa8f9 Avoid copying buffer from ReadOnlySequence as ReceivedMqttPacket body (#1596)
* Avoid copying buffer from ReadOnlySequence as  ReceivedMqttPacket body

* Use ReadOnlySequence.FirstSpan if possible.

* add ReaderExtensionsBenchmark

* update benchmark

* fix fixedHeader incorrect read

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2022-12-03 13:18:30 +01:00
老九andChristian 862d76471b Implement buffer copy using different policies (#1599)
use Memory-Copy

Co-authored-by: Christian <6939810+chkr1011@users.noreply.github.com>
2022-12-03 13:17:02 +01:00
老九 27f2474876 fix MqttBufferReader #1597 (#1598) 2022-12-03 13:14:07 +01:00
Christian 01a5aeeb58 Refactor benchmarks (#1601) 2022-11-30 18:09:34 +01:00
老九 47df131e7f Avoid to check the type of propertyWriter parameter (#1600)
Refactor code of MqttBufferWriter
2022-11-30 17:56:05 +01:00
Christian 56750adfe4 1592 bug of mqttbufferreader (#1593) 2022-11-29 20:23:20 +01:00
Christian 11e64ef018 Update ReleaseNotes.md 2022-11-28 21:10:46 +01:00
Christian 9b20e0a430 Refactor code 2022-11-28 21:10:42 +01:00
老九 41df2ec5da Optimize SendPacketAsync method for MQTTnet.AspNetCore (#1582)
* Avoid to call MqttPacketBuffer.Join() when SendPacketAsync

* Safely cleanup the PacketFormatterAdapter

* Keep buffer.Join when mqtt over webSocket

* null checking for IHttpContextFeature.HttpContext
2022-11-28 21:02:13 +01:00
Christian e45b207375 Update ReleaseNotes.md 2022-11-26 14:53:03 +01:00
Christian c37866e534 Refactor code and update release notes 2022-11-26 14:51:36 +01:00
老九 bda4ab7025 Set string.Empty as default value for SenderClientId (#1583) 2022-11-26 14:50:08 +01:00
Christian 32cc1ff7b1 Refactor code and update release notes 2022-11-26 14:49:28 +01:00
Dalibor Kundrat b5952a590a Extend server client ResetStatistics() to reset all client statistics not only channel... (#1587)
Extend reset client statistic to reset all stats
2022-11-26 14:47:17 +01:00
Christian 581a024ceb Improve allocations for AsyncSignal. 2022-11-26 14:45:34 +01:00
Mario ZelgerandMario Zelger c45cb8b04e Dispose the AsyncSignalWaiter before setting it to null (#1586)
dispose the AsyncSignalWaiter before setting it to null to prevent memory leak

Co-authored-by: Mario Zelger <mario.zelger@confer.ch>
2022-11-26 14:19:51 +01:00
Christian a5e1a4d6dd Update version 2022-11-26 14:16:37 +01:00
Christian e88b280eb0 Reset release notes 2022-11-12 12:53:54 +01:00
Christian e4b07f2b8c Fix build errors 2022-11-12 09:43:55 +01:00
Christian 4eb6e77eb5 Fix build errors due to merge conflicts 2022-11-11 14:41:28 +01:00
Christian db1fc7625d 1546 possible bug in server repeatedly sending the same message to client subscribed with cleansession=false (#1569) 2022-11-11 08:14:15 +01:00
Christian bfec9dc5ad 802 client isnt being notified if message is not delivered (#1568) 2022-11-09 21:14:53 +01:00
Christian 56f0a2c31c Fix validation of topic in managed client (#1567) 2022-11-09 20:13:59 +01:00
Christian 5ee0bb4b65 1565 high cpu load from asyncsignal (#1566) 2022-11-09 19:56:29 +01:00
Christian 5c74728387 Fix client session takeover 2022-11-06 13:28:41 +01:00
Christian 97c46bea0f Update ReleaseNotes.md 2022-11-06 10:50:32 +01:00
Christian e6c1ab4e4c Fail all waiting tasks when the client connection gets closed (#1563) 2022-11-06 10:50:04 +01:00
Christian 6e1ec266a7 Update ReleaseNotes.md 2022-11-06 10:49:19 +01:00
Christian 3fc6982e9a Fix upgrading and downgrading of retained messages QoS for subscriptions (#1564) 2022-11-06 10:35:59 +01:00
SilverFox 5b1cc7d713 Also cleanup MqttClientSessionsManager._subscriberSessions when session is taken over by a new one with CleanSession=true, fix #1552 (#1553) 2022-11-06 10:35:15 +01:00
Christian 2842f27522 1552 mqttnetservermqttclientsessionsmanager subscribersessions is not proper removed on special case (#1562) 2022-11-06 10:34:20 +01:00
Christian 7ef137e26e No longer fire _ClientAcknowledgedPublishPacketEvent_ for PUBREC packets (#1550) (#1551) 2022-11-06 10:29:49 +01:00
Christian b1a336eb62 Reset release notes, update version 2022-11-06 10:24:58 +01:00
Christian d481e93832 Add new samples. 2022-10-25 17:29:45 +02:00
Christian 8cf5537043 Improve unit tests 2022-10-23 08:45:16 +02:00
Christian d2ce9d607a Fix freezes in _AsyncLock_ (#1549) 2022-10-23 08:16:45 +02:00
Christian 36736914bc Fix Xamarin connect freeze (#1545) 2022-10-23 07:51:19 +02:00
Christian 7823d8342e Update version. 2022-10-23 07:43:31 +02:00
Christian 431142471f Add samples. 2022-10-16 11:12:08 +02:00
Christian a3227a444a Reset release notes. 2022-10-01 16:51:11 +02:00
Christian f74af45fba Add new samples. 2022-10-01 11:32:14 +02:00
Christian e050e2d61e Improve async lock (#1520) 2022-09-25 10:26:18 +02:00
Christian ef85ef676a Update README.md 2022-09-16 08:24:52 +02:00
Christian e977546297 Fix cross access to async events. (#1515)
fix cross access to async events.
2022-09-16 08:20:42 +02:00
Rido ae92b0ed33 Add Extensions.MultiCloud to references (#1517) 2022-09-15 09:21:39 +02:00
Christian 7e686d9aa5 Refactor code. 2022-09-15 09:09:08 +02:00
Christian d23bbf7bf3 Improve PingAsync timeout handling. 2022-09-14 14:17:59 +02:00
Christian d4dad4860a Fix and improve session takeover process handling. 2022-09-14 14:15:35 +02:00
Christian c009cbef76 Update comments, release notes, version. 2022-09-13 09:07:02 +02:00
logicaloud 37e60c73ae Send DISCONNECT packets to MQTT5 clients only (#1506) 2022-09-13 09:00:21 +02:00
Christian 3ab095a568 Set web socket boundaries correctly (#1514) 2022-09-13 08:50:02 +02:00
Christian f5d9b65139 Add samples. 2022-08-23 20:58:46 +02:00
Christian 31e5b40459 Revert "Update ci.yml"
This reverts commit 8fb55d75fe.
2022-08-23 20:49:40 +02:00
Christian 8fb55d75fe Update ci.yml 2022-08-14 13:06:32 +02:00
Christian 420222511b Update ReleaseNotes.md 2022-08-13 12:56:05 +02:00
Stan WijckmansandStan Wijckmans c5cec60809 Apply timeout to automatic ping. (#1495)
Co-authored-by: Stan Wijckmans <stanw@aviobook.aero>
2022-08-13 12:53:55 +02:00
Christian 12dd815421 Fix wrong package references in Benchmark project. 2022-08-13 12:45:02 +02:00
Christian f36f49cb3e Add parameter validations. 2022-08-13 12:38:36 +02:00
Christian 9152fe637e Reset release notes. 2022-08-07 09:56:25 +02:00
Christian b976e9c177 Fix build errors. 2022-08-03 20:44:58 +02:00
Christian 262a4681ad Merge branch '1291-access-client-status-in-client-disconnected-handler' 2022-08-03 20:40:53 +02:00
Christian ad546adafe Fix removal of event handlers from async event. 2022-08-03 20:27:53 +02:00
Christian 29a9941d86 Fix breaking changes. 2022-07-31 11:10:38 +02:00
Christian 5a21939e29 Squashed commit of the following:
commit 469caf656e
Author: Christian <6939810+chkr1011@users.noreply.github.com>
Date:   Sun Jul 31 10:55:40 2022 +0200

    Fix build errors.

commit 42402fba04
Author: Christian <6939810+chkr1011@users.noreply.github.com>
Date:   Sun Jul 31 10:22:23 2022 +0200

    Allow interception of injected application messages.

commit a0dc8ab0d7
Author: William Lee <31092948+william19821101@users.noreply.github.com>
Date:   Sun Jul 31 15:50:14 2022 +0800

    Update Server_Simple_Samples.cs (#1474)

    Change e.UserName to e.Username
2022-07-31 11:09:39 +02:00
Christian 469caf656e Fix build errors. 2022-07-31 10:55:40 +02:00
Christian 42402fba04 Allow interception of injected application messages. 2022-07-31 10:22:23 +02:00
William Lee a0dc8ab0d7 Update Server_Simple_Samples.cs (#1474)
Change e.UserName to e.Username
2022-07-31 09:50:14 +02:00
Christian 02ede5a2d8 Update MqttClient.cs 2022-07-24 10:44:27 +02:00
Christian cef61900df Merge branch 'master' into 1291-access-client-status-in-client-disconnected-handler 2022-07-23 18:09:05 +02:00
Christian 09385b1b36 Pass session item to several more event handers. 2022-07-23 18:07:49 +02:00
Christian cbf413f04e Squashed commit of the following: 1125-expose-http-context-in-validateconnectionasync
commit 353c9671a04a273798b0b3775be5f0764bfd7edf
Author: Christian <6939810+chkr1011@users.noreply.github.com>
Date:   Sat Jul 23 15:33:01 2022 +0200

    Remove usage of obsolete stuff.

commit 1f3c35685c7a65453c37a37e8c54a2ca4305ff6d
Author: Christian <6939810+chkr1011@users.noreply.github.com>
Date:   Sat Jul 23 15:30:54 2022 +0200

    Update ValidatingConnectionEventArgs.cs

commit a5e1b8938974b5b57e95ec41d74634ca130a8ad5
Merge: 8878efee 11249d00
Author: Christian <6939810+chkr1011@users.noreply.github.com>
Date:   Sat Jul 23 15:30:30 2022 +0200

    Merge branch 'master' into 1125-expose-http-context-in-validateconnectionasync

commit 8878efee0da3c67d90bb7fb6946453f62329cd8e
Author: Christian <6939810+chkr1011@users.noreply.github.com>
Date:   Sat Jul 23 15:30:03 2022 +0200

    Expose channel adapter when validating connections.
2022-07-23 15:33:53 +02:00
Christian 11249d006f Add samples. 2022-07-23 15:10:20 +02:00
Christian 0d7b020994 Squashed commit of the following: 487-any-way-to-generate-events-on-receipt-of-puback-or-pubrec-packets
commit 3f2f8d4b0a31b20734eca3fff86c43bd1ac3e3ad
Merge: 34babbf2 d71ff3d6
Author: Christian <6939810+chkr1011@users.noreply.github.com>
Date:   Sat Jul 23 11:06:22 2022 +0200

    Merge branch 'master' into 487-any-way-to-generate-events-on-receipt-of-puback-or-pubrec-packets

commit 34babbf2714b742bc4f3802804a1a07159d38e22
Author: Christian <6939810+chkr1011@users.noreply.github.com>
Date:   Mon Jul 11 22:56:01 2022 +0200

    Fix typo.

commit add6277458f528fc03bf4a1ba228a55c5a8d1a80
Author: Christian <6939810+chkr1011@users.noreply.github.com>
Date:   Sat Jul 2 12:50:13 2022 +0200

    Add new event for client acknowledges.
2022-07-23 11:08:53 +02:00
Christian d71ff3d615 Update ReleaseNotes.md 2022-07-23 11:05:14 +02:00
Christian 57745e8324 Merge branch 'master' into 1311-how-does-mqttclient-specify-the-network-card-to-send-data 2022-07-23 11:03:06 +02:00
Christian a94776eeea Update version information. 2022-07-23 11:02:00 +02:00
Christian d3848d8cb0 Add comments. 2022-07-23 11:00:21 +02:00
Alexander Köpke 6c29ea56fc Add PackageIdentifier to MqttApplicationMessageReceivedEventArgs (#1466)
Provide `PackageIdentifier` as read only property in `MqttApplicationMessageReceivedEventArgs`
2022-07-23 10:37:57 +02:00
Christian ed7c150cc5 Add new options. 2022-07-19 20:47:16 +02:00
Christian 13762eedd4 Update Server_Asp_Net_Samples.cs 2022-07-19 17:33:01 +02:00
Christian e33495010e Update samples. 2022-07-13 15:29:26 +02:00
Christian b0d1fcd161 Refactor code. 2022-07-12 16:37:32 +02:00
Christian f7a739e162 Fix check for skipped application messages. 2022-07-12 12:02:00 +02:00
Christian 422945929e Merge branch 'Fix-high-CPU-usage' 2022-07-12 11:57:03 +02:00
Christian 76e54dc49b Update ReleaseNotes.md 2022-07-12 11:56:50 +02:00
Christian b10a69a0ae Update release notes. 2022-07-01 17:03:33 +02:00
Torstein Lundervold Nesheim 4b1c7cf772 Use IgnoreCertificateChainErrors option in TcpChannel (#1447) 2022-07-01 17:00:13 +02:00
Christian 3f67df007b Remove obsolete files etc. 2022-07-01 16:55:13 +02:00
Christian 36b1ed06f0 Update MqttClient.cs 2022-07-01 16:54:53 +02:00
Christian 4a982ea228 Add Tests. 2022-06-29 18:58:02 +02:00
Christian 9fe5073186 Use TopicFilter instead of QoS only. 2022-06-29 18:17:48 +02:00
Christian 305c552474 Squashed commit of the following:
commit 0cbf50427ca6fb343cfa22ccbcd06aad5ea2b4c2
Author: Christian <6939810+chkr1011@users.noreply.github.com>
Date:   Mon Jun 20 21:02:50 2022 +0200

    Fix firing of _ClientSubscribedTopicAsync_ event.
2022-06-27 20:41:34 +02:00
Christian f632fbb447 Squashed commit of the following:
commit c3ca0ef7da4bcc2103cda2bb175ea3c5a49da2e6
Author: Christian <6939810+chkr1011@users.noreply.github.com>
Date:   Sat Jun 25 22:58:18 2022 +0200

    Update nugets and fix breaking changes.
2022-06-27 20:40:37 +02:00
Christian 8231d62f9f Squashed commit of the following:
commit 9f289152736a682a8c31fbe7720dade37dbb1cb5
Author: Christian <6939810+chkr1011@users.noreply.github.com>
Date:   Sun Jun 26 13:38:35 2022 +0200

    Fix message storage.
2022-06-27 20:39:53 +02:00
Christian a52a717965 Update ReleaseNotes.md 2022-06-26 13:40:21 +02:00
Christian 2b653f2379 Update ReleaseNotes.md 2022-06-25 23:00:16 +02:00
Christian 725cfb643f Set MaximumQoS properly. 2022-06-24 18:52:50 +02:00
Christian 29ec6edbf4 Update Server_Simple_Samples.cs 2022-06-24 18:46:38 +02:00
Christian f3ef2dbf7c Add samples. 2022-06-18 11:56:19 +02:00
Christian 14eb202873 Add new samples. 2022-06-18 11:38:36 +02:00
Christian a3c7f9a22c Fix handling of retained messages with QoS > 0. 2022-06-15 21:56:13 +02:00
Christian 41e0a25fc8 Fix wrong event args types. 2022-06-14 21:10:53 +02:00
Christian 772cd3cd12 Update release notes. 2022-06-10 23:29:52 +02:00
Christian 42cf9f73c2 Merge branch 'master' into 1413-protocol-version-132-mqtt-311-bridge-support 2022-06-10 23:27:00 +02:00
Christian ec2e08668f Add support for MQTT 3.1.1 Bridge flag. 2022-06-10 23:07:00 +02:00
Christian e9e8583d1a Merge branch 'master' of https://github.com/dotnet/MQTTnet 2022-06-10 17:10:14 +02:00
Christian f68b109471 Switch to license expression. (#1408) 2022-06-10 17:09:17 +02:00
Christian dd1e155ff4 Add missing "WithWill..." methods. 2022-06-09 21:52:05 +02:00
Christian cf6369d63f Update version. 2022-06-09 21:27:14 +02:00
Christian 3049fc6608 Update ReleaseNotes.md 2022-06-09 21:27:08 +02:00
Christian b75076a1c5 Skip adding default message expiry interval. 2022-06-09 21:23:34 +02:00
Christian ae8e2ec7c9 Merge branch 'master' of https://github.com/dotnet/MQTTnet 2022-06-09 20:13:19 +02:00
Christian e7e6a080e0 Update copyright information. 2022-06-09 20:13:17 +02:00
SeppPenner dc9afa6c3a Samples, Github template: Fixed small typos. 2022-06-08 09:19:14 +02:00
HansM 02b17f277d Merge pull request #1421 from soyoo/patch-1
Update RcpClient_Samples.cs
2022-06-08 08:58:22 +02:00
soyoo b9d9ea2d4d Update RcpClient_Samples.cs
typo
2022-06-07 21:54:08 +08:00
Christian c9cc6c9c0f Update ReleaseNotes.md 2022-05-08 13:45:00 +02:00
Andres OlivaresandAndres Olivares 967c964111 Added MqttClientTlsOptions to control RevocationMode for clients with limited Internet access (defaults to Online) (#1396)
Co-authored-by: Andres Olivares <andres.olivares@ncr.com>
2022-05-08 14:31:14 +02:00
johannesmeyer 80aaca63f9 Update README.md (#1402) 2022-04-30 10:55:14 +02:00
Christian eeeb479db2 Update ReleaseNotes.md 2022-04-21 21:06:01 +02:00
Tim 9e47a0985b Allow to change cipher suite (#1381)
* Allow to change the used Cipher Suite

* Also added cipher suite to the mqtt client part

* Added ConfigureAwait
2022-04-21 21:02:39 +02:00
Christian 2d9ae0576b Fix wrong value for graceful socket close handling. 2022-04-21 20:49:09 +02:00
Christian fcf276dd1a Improve Server packet management. 2022-04-21 20:48:52 +02:00
Christian 920728e77a Migrate handlers to events in ManagedClient. 2022-04-21 20:47:53 +02:00
Christian 1d4794b071 Configure build warnings. 2022-04-21 20:47:24 +02:00
Christian 626baa7bb5 Update nuget settings
Documentation is now also part of the nuget packages.
2022-04-09 10:53:27 +02:00
Gui.H 810746b56b Update MQTTnet.csproj (#1385) 2022-04-09 10:49:03 +02:00
Christian 7cf454952f Restore interfaces. 2022-04-05 20:00:49 +02:00
Christian cf2974cd34 Update Subscribe_Tests.cs 2022-03-20 15:25:38 +01:00
Christian 7d95c238c3 Code cleanup. 2022-03-06 12:47:48 +01:00
Christian 9a94b0465d Add Unit Tests. 2022-03-06 11:32:05 +01:00
Christian 1d8b6e387d Update README.md 2022-02-23 18:59:57 +01:00
Christian 73d681bc1f Update README.md 2022-02-20 21:32:01 +01:00
Christian 2ce9b94ec9 v4.0.0 (#1357) 2022-02-20 21:10:46 +01:00
HansM 47e674e4d3 Adjusted default value for the supported Net frameworks versions where "None" is incompatible. (#1348) 2022-02-17 20:00:57 +01:00
Christian d5691346a9 Update MQTTnet.nuspec 2022-01-27 20:22:51 +01:00
HansM 0730f21d29 Merge pull request #1338 from alvin1221/public_broker_test
Thank you, this is indeed a bug.
2022-01-12 17:57:33 +01:00
alvin1221 6dfa7f0769 Fix incorrect TLS port of broker.emqx.io 2022-01-12 11:29:15 +08:00
Christian 27592f1643 Update MQTTnet.nuspec 2022-01-08 15:36:35 +01:00
Christian c6f4b59438 Increase delay for Keep Alive checks to decrease CPU load. 2022-01-08 15:35:47 +01:00
Christian b362b2afc2 Make logger parameters generic. 2022-01-08 14:35:25 +01:00
Christian 7a72a8d562 Update MQTTnet.nuspec 2022-01-08 14:07:57 +01:00
Günther Foidl bd40e10a66 Elide repeated Action-delegate allocation by caching it (#1324)
* Elide repeated Action-delegate allocation by caching it

Here C# compiler has too little knowledge about the usage of the delegate, we know better so cache it on our own to avoid the repeated allocation.

* Use conditional compilation
2022-01-08 14:00:39 +01:00
Christian 4b44a2b2b1 Remove appveyor. 2022-01-07 18:01:03 +01:00
Christian 215f24a95b Create CODE-OF-CONDUCT.md 2022-01-07 17:52:16 +01:00
Christian 72f9acdc20 Update CI 2022-01-06 20:55:20 +01:00
Christian 1e5390679f Update ci.yml 2022-01-06 20:41:18 +01:00
Christian 5cafce4345 Update ci.yml 2022-01-06 20:40:06 +01:00
Christian dfaf3dc31f Update ci.yml 2022-01-06 20:37:24 +01:00
Christian 3a9397c793 Update CI. 2022-01-06 20:36:12 +01:00
Christian 1cf4a7d6be Update ci.yml 2022-01-06 20:26:11 +01:00
Christian 180588c3a4 Update ci.yml 2022-01-06 20:18:04 +01:00
Christian bc4c86bebd Update ci.yml 2022-01-06 20:13:11 +01:00
Christian ea88a8c0de Update CI. 2022-01-06 20:10:42 +01:00
Günther Foidl d98129481a Fixed latent bug in MqttApplicationMessageBuilder.WithPayload stream overload (#1322) 2022-01-04 19:25:26 +01:00
Christian 5e5818d7df Merge branch 'master' of https://github.com/chkr1011/MQTTnet 2021-11-28 14:45:27 +01:00
Christian 72c7a8959c Update MQTTnet.nuspec 2021-11-28 12:57:22 +01:00
patagona 39e637795e improve exception message when handling connection errors (#1302) 2021-11-28 12:56:32 +01:00
logicaloud 731c89d2e9 Fix MQTT5 'IsPersisted' session flag handling (#1300) 2021-11-28 12:51:29 +01:00
Michi 25ddfc83a8 MqttRpcClient now adds ResponseTopic to MqttApplicationMessage when using MQTT v5 (#1295)
* MqttRpcClient now adds ResponseTopic to MqttApplicationMessage when using MQTT v5

* No need for conditional protocol check (ResponseTopic property won't be added by PacketFormatter in <MQTT v5)

* Cleanup: Remove using
2021-11-28 12:41:56 +01:00
Christian 2d94abdde3 Update MQTTnet.nuspec
Update docs.
2021-11-13 10:09:59 +01:00
logicaloud f0ea13c07f Fix MQTT 3.1.1 session persistence when CleanSession=1 (#1294) 2021-11-13 10:05:54 +01:00
Volker Milbrandt 47cd5aa3cd test ResultCode for invalid credentials (no userName but password) (#1270)
fix order of parameters in exceptions AreEqual(expected, actual)
2021-11-13 10:02:55 +01:00
HansM 258df6bb14 Removed IDisposable from MqttClientConnection class. (#1288) 2021-11-11 20:10:35 +01:00
SeppPenner 85c3c0b352 MQTTnet.noUWP.sln: Removed no longer present MQTTnet.Server project. 2021-11-08 08:50:59 +01:00
Christian 8020e66f41 Fix UWP build errors. 2021-11-01 12:28:39 +01:00
Christian bd004ec327 Update docs. 2021-10-30 10:21:50 +02:00
logicaloud 1e68c2e815 Fixes #1276 timestamp check in server keep-alive monitor (#1277)
* Fix timestamp check in server keep-alive monitor

* Retain the original client statistics property name
- add comments to clarify meaning
- add separate public "received" timestamp property

* fix comment
2021-10-30 10:12:57 +02:00
Christian d7e1c89d62 Update docs. 2021-10-27 22:20:55 +02:00
patagona b779d04636 let the OS choose the supported TLS ptotocols when connecting to a MQTT broker (#1271) 2021-10-23 10:31:44 +02:00
logicaloud 623d8cafaa Fix #1263 - Set IsSessionPresent in CONNACK if client session exists (#1268)
* Set IsSessionPresent in CONNACK if client session exists

* Set IsSessionPresent in CONNACK if client session exists;
- restore white space differences to make comparison easier
2021-10-23 10:28:08 +02:00
Christian 0920c86d37 Refactor logger. (#1247) 2021-09-26 11:05:00 +02:00
Christian c756a4092f Feature/mqttv5 subscriptions server (#1246)
* Add support for RetainHandling.

* Add support for No Local.

* Add support for _SubscriptionIdentifier_.

* Add more Unit Tests.

* Update docs.
2021-09-23 20:30:43 +02:00
Christian feb53e78c6 Update docs. 2021-09-19 13:02:15 +02:00
Ablfzl Edgelolliandablfzl dd0aba0640 Process all queued message before server stops (#1234)
* process all queued message befor server stops

* fix an issue

Co-authored-by: ablfzl <ablfzl21@outlook.com>
2021-09-19 13:01:47 +02:00
Christian 68f1043ef5 Refactor sub/unsub management in managed client. 2021-09-19 12:59:32 +02:00
scottbrogden-iheartmedia d01d859227 Added option for how many subscriptions to send in a single call to t… (#1209)
* Added option for how many subscriptions to send in a single call to the server.  aws iotcore limits this to 8

* Split subscription messages up to 8 at a time when reconnecting
2021-09-19 12:41:33 +02:00
Marc Sallin fcab0d5cf0 Add Silverback to references in readme (#1238) 2021-09-19 12:35:19 +02:00
HansM b66a18f8dd Merge pull request #1241 from soyoo/master
Update README.md
2021-09-15 19:33:13 +02:00
zhengshuyuan 8e1e93c00f Update README.md
fix typo
2021-09-15 21:10:49 +08:00
Christian cd8940f9b7 Improve internal server connection management. (#1232) 2021-09-08 18:01:56 +02:00
Jacky Jiang 9d9077f17c Update MqttApplicationMessageBuilder.cs (#1230)
update function WithMessageExpiryInterval description
2021-09-08 15:45:18 +02:00
Christian fa6859d68a Merge branch 'master' of https://github.com/chkr1011/MQTTnet 2021-09-05 13:32:50 +02:00
Christian 4f14373117 Add Unit Tests. 2021-09-05 13:32:46 +02:00
Christian 90ec39f2a4 Refactor code. 2021-09-05 13:31:36 +02:00
Christian 2aa4d1b77a Add low level client to test environment. 2021-09-05 13:31:23 +02:00
Christian aa9f8d8ef3 Update release notes. 2021-09-05 13:30:39 +02:00
Nikita Senkov 50381637af Updated _ReconnectAsync_ extension methods to retrieve authentication result (#1202) 2021-09-05 11:49:52 +02:00
Harry Kakoulidis 8905b612c9 Updated tests with public servers. (#1223)
* Updated tests with public servers.

* Separated tests with TLS12 and TLS13.
2021-09-05 11:45:30 +02:00
HansM 3cdf6d1261 [MQTTnet, MQTTnet.Extensions.ManagedClient] Fixed bug that allowed invalid subscriptions (Thanks to @marcelwinh). (#1226) 2021-09-05 11:42:42 +02:00
Christian d1c883ebae Move MQTTnet.Server to dedicated repo. 2021-06-29 20:18:20 +02:00
Christian ed5e6ee897 Update project files. 2021-06-28 20:39:10 +02:00
Christian 2e019f372c Update docs. 2021-06-27 17:02:04 +02:00
Christian cc9bc2d3a0 Merge remote-tracking branch 'origin/master' 2021-06-27 16:53:54 +02:00
Christian 306bce5a58 Refactor code. 2021-06-27 16:53:44 +02:00
Ramon Smits 6fe7ce7a0c FIxed MqttNetLogLevel.Verbose incorrectly mapped to LogLevel.Debug (#1170)
Based on https://github.com/chkr1011/MQTTnet/issues/1138#issuecomment-846649937
2021-05-30 22:01:38 +02:00
Christian 8f1d4e3c22 Remove client disconnected handler from wrong implementation location. 2021-04-11 20:34:35 +02:00
Christian 77338527b4 Refactor code. 2021-04-05 12:50:42 +02:00
Christian 962622a9f7 Merge pull request #1134 from yyjdelete/issue996
Disallow to call MqttClient.ConnectAsync while Disconnect is pending.
2021-04-05 11:19:20 +02:00
SilverFox 899ed7b1da Rename MqttClient.ConnectState to MqttClientConnectionStatus 2021-04-03 13:19:50 +08:00
Christian 10f7d809f2 Merge pull request #1132 from qzwzqty/master
Passes the Endpoint of the client before it disconnected
2021-04-02 16:18:15 +02:00
Christian 324fb7e48c Merge pull request #1136 from yyjdelete/framework
Fix UWP support broken in #1135
2021-04-02 16:17:13 +02:00
SilverFox d913d4402e Convert MqttClient._connectState to enum 2021-04-02 21:01:49 +08:00
SilverFox df262b5588 Fix UWP support broken in #1135 2021-04-02 19:58:03 +08:00
Christian 27daf37ba4 Update MQTTnet.nuspec 2021-04-02 12:49:31 +02:00
Christian e5e10eee6d Merge pull request #1135 from yyjdelete/framework
Add more checks for NET5_0
2021-04-02 12:48:43 +02:00
SilverFox e174546b5a Add more checks for NET5_0 2021-04-02 18:03:44 +08:00
SilverFox f99daee4d1 Fix Session_Tests.Manage_Session_MaxParallel 2021-04-02 17:54:41 +08:00
SilverFox 9b10eadb24 Fix broken tests 2021-04-02 17:54:41 +08:00
SilverFox c39da42ef2 Disallow to call MqttClient.ConnectAsync while Disconnect is pending.
Fix #996
Fix #1010
2021-04-01 22:00:01 +08:00
Wang Chunlong 85b339e6f0 rename 2021-03-31 11:56:58 +08:00
Christian fbb5cd45a0 Refactor deferred ACK of publish packets. 2021-03-30 21:06:44 +02:00
Christian d430ca0250 Merge pull request #1075 from tkurucsai/feature/pending-appmsg-acknowledge
Feature/pending appmsg acknowledge
2021-03-30 14:34:43 +02:00
Wang Chunlong cf8ea872d3 Disconnected Endpoint 2021-03-29 16:00:37 +08:00
Christian d4440f3be1 Merge remote-tracking branch 'origin/master' 2021-03-21 20:42:25 +01:00
Christian b97d01b78b Fix wrong data validation (#342). 2021-03-21 20:42:09 +01:00
Christian 375ee5c4ac Merge pull request #1121 from asymetrixs/master
Added workflow to  build debian/ubuntu packages
2021-03-21 20:29:02 +01:00
tamas.kurucsai 90b37a1e2d reimplemented delayed acknowledgement using a property to switch off automatic acknowledgement and a new method Acknowledge() in the event handler 2021-03-20 10:36:44 +01:00
Damian 0978f6cc75 Merge pull request #7 from asymetrixs/deb-packaging
Deb packaging
2021-03-12 18:04:25 +01:00
Damian Wolgast e7c51e8dbc Extraction of Version from project file. 2021-03-12 18:03:32 +01:00
Damian Wolgast aab4448980 Debugging 2021-03-12 18:01:31 +01:00
Damian Wolgast 52139c6a99 Debugging 2021-03-12 17:56:34 +01:00
Damian Wolgast f3d121120b Debugging 2021-03-12 17:51:18 +01:00
Damian Wolgast 413c68de44 Debugging 2021-03-12 17:47:53 +01:00
Damian Wolgast f0919487f2 Debugging 2021-03-12 17:44:26 +01:00
Damian ffa7c51899 Merge pull request #6 from asymetrixs/deb-packaging
Deb packaging
2021-03-12 17:38:07 +01:00
Damian Wolgast 493cad087f Fixed syntax 2021-03-12 17:36:41 +01:00
Damian Wolgast 4d94e1a318 Debugging 2021-03-12 17:32:03 +01:00
Damian 28ff08ceb9 Merge pull request #5 from asymetrixs/deb-packaging
Read version from MQTTnet.Server project file
2021-03-12 17:28:03 +01:00
Damian Wolgast 0f3d461c37 Read version from MQTTnet.Server project file 2021-03-12 17:27:18 +01:00
Damian 4285169108 Merge pull request #4 from asymetrixs/deb-packaging
Added dependency to libssl
2021-03-12 15:44:58 +01:00
Damian Wolgast 1b1f2db1e6 Added dependency to libssl 2021-03-12 15:44:22 +01:00
Damian d7248c0f64 Merge pull request #3 from asymetrixs/deb-packaging
Added check for availability of setcap
2021-03-12 15:20:08 +01:00
Damian Wolgast d2e1b12186 Added check for availability of setcap 2021-03-12 15:18:13 +01:00
Damian dafcfb47d2 Merge pull request #2 from asymetrixs/deb-packaging
Docker support
2021-03-12 14:41:38 +01:00
Damian Wolgast 897f0f36d1 Fixed spelling 2021-03-12 14:40:21 +01:00
Damian Wolgast 9cb12ac2ce Docker, check if systemctl exists before using it 2021-03-12 14:39:51 +01:00
Damian 312fb2bb3c Merge pull request #1 from asymetrixs/deb-packaging
Fixed user creation to not copy skel-files
2021-03-12 14:19:24 +01:00
Damian Wolgast 3ee785c781 Fixed user creation to not copy skel-files 2021-03-12 14:17:38 +01:00
Damian Wolgast 0ea4ae7501 Fix, forgot to rename file. 2021-03-12 12:40:02 +01:00
Damian Wolgast 7e764c7f0f Added revision (assuming 1) and architecture 2021-03-12 12:36:14 +01:00
Damian Wolgast 5c2879029b Added command to stop service before uninstalling 2021-03-12 12:26:04 +01:00
Damian Wolgast 6cbb8d42e3 Added prerm to revoke service permissions 2021-03-12 12:15:49 +01:00
Damian Wolgast d8d50f6dcb Added workflow to build debian/ubuntu packages 2021-03-11 18:19:25 +01:00
Christian a01dc9fef8 Add new overload for server options builder. 2021-03-05 13:01:14 +01:00
tamas.kurucsai 3427d82efc Merge branch 'master' of https://github.com/chkr1011/MQTTnet into feature/pending-appmsg-acknowledge
# Conflicts:
#	Source/MQTTnet/Client/MqttClient.cs
2021-03-05 12:10:01 +01:00
Christian 5915285522 Fix TLS parameter options builder (#1104). 2021-03-02 10:00:34 +01:00
Christian 12f346115f Improve RPC client handling. 2021-02-26 10:55:26 +01:00
Christian 05827341d4 Update codeql-analysis.yml 2021-02-23 12:05:24 +01:00
Christian 1e88d6a05b Merge remote-tracking branch 'origin/master' 2021-02-23 11:46:38 +01:00
Christian 8261ba9dc1 Update docs. 2021-02-23 11:46:16 +01:00
Christian b766c1bebb Refactor keep alive message handling in order to fix issues with sudden disconnects. 2021-02-23 11:45:22 +01:00
Christian 6c188899fb Create codeql-analysis.yml 2021-02-21 11:33:51 +01:00
tamas.kurucsai 23c5270c3f Merge branch 'master' of https://github.com/chkr1011/MQTTnet into feature/pending-appmsg-acknowledge
# Conflicts:
#	Source/MQTTnet/Client/MqttClient.cs
#	Source/MQTTnet/MqttApplicationMessageReceivedEventArgs.cs
2021-02-20 12:55:28 +01:00
Christian 2d4ea8ee9b Improve nuget packages. 2021-02-19 21:52:42 +01:00
Christian 15d3761843 Merge pull request #1097 from yyjdelete/nuspec
Update nuspecs
2021-02-19 21:50:49 +01:00
Christian ed520455d0 Use the data converter only when creating packets. 2021-02-19 21:45:23 +01:00
Christian cfc4ebe6a3 Expose Dup flag in application messages (#1096). 2021-02-19 21:39:23 +01:00
Christian 120b7fb7d1 Fix RPC issue #1093 by calling both message handlers. 2021-02-18 18:56:15 +01:00
SilverFox 8b164a4846 Update nuspecs
Manually sync with the file generated by `msbuild /t:pack` or `dotnet pack`, and remove some unnessary dependencies
2021-02-18 11:26:54 +08:00
Christian fda4272611 Update docs. 2021-02-11 12:31:13 +01:00
Christian 88cc79d52f Fix issues in nuspecs. 2021-02-11 12:25:58 +01:00
Christian 8ba960343c Fix exception handling issues (#1082). 2021-02-08 13:29:15 +01:00
Christian 0976fa682a Merge pull request #1083 from milbrandt/bugfix/noUsername
Test for Regression: No exception on ConnectAsync(null, password) [MQTT-3.1.2-22]
2021-02-06 13:38:04 +01:00
Christian 18cc454842 Fix build script for .net5.0. 2021-02-06 13:36:23 +01:00
Volker Milbrandt e342a51d50 Merge branch 'master' 2021-02-04 21:23:02 +01:00
Volker Milbrandt 57652c76cf tests with MqttClient.ConnectAsync with credentials
for all four combinations of null/non-null for username and password
2021-02-04 21:09:36 +01:00
HansM bb52159e49 Added reference to SparkplugNet. 2021-01-31 17:35:39 +01:00
HansM 109acccd19 Update MQTTnet.nuspec
Added code documentation hint.
2021-01-31 11:34:27 +01:00
HansM deb2c3dec6 Merge pull request #1055 from chkr1011/add-code-doc
Added client documentation.
2021-01-31 11:33:13 +01:00
HansM 63ca6086d5 Added missing changelog entry.
Missing changelog change from https://github.com/chkr1011/MQTTnet/pull/1076.
2021-01-30 15:39:04 +01:00
Christian 3f92f2ca2b Remove UWP test app because it gets replaced by MQTTnet.App in a separate repository. 2021-01-30 13:24:24 +01:00
Christian a13874d8a5 Add missing overloads for client disconnect.
Add timeout for disconnect in managed client.
2021-01-30 13:17:03 +01:00
Christian c91a1f8572 Update solution settings. 2021-01-30 13:12:41 +01:00
Christian b103718bd9 Add Unit Tests. 2021-01-29 23:17:16 +01:00
Christian b88924bce5 Fixed wrong buffer size calculation. 2021-01-29 23:10:40 +01:00
Christian f3f1d81b52 Update docs. 2021-01-29 22:44:18 +01:00
Christian 031b60878d Merge pull request #1071 from muneebmajeed/master
Allow to respond with a reason code in PUBACK/PUBREC
2021-01-29 22:27:09 +01:00
HansM 1fbf20a569 Merge pull request #1076 from dagophil/bug/topic-filter-comparer-edge-case
The topic filter comparer now checks for e.g. "foo/" matching "foo/#".
2021-01-29 18:24:37 +01:00
Philip Schill b1bf7698aa The topic filter comparer now checks for e.g. "foo/" matching "foo/#". 2021-01-29 17:37:47 +01:00
tamas.kurucsai fbf7d9bb5c corrected thread safety of ping timers after adding delayed acknowledgement 2021-01-29 07:03:56 +01:00
tamas.kurucsai 822f582e41 added test for delayed message acknowledgement 2021-01-29 07:03:19 +01:00
Muneeb Majeed f8eaf02516 Allow to respond with a reason code in PUBACK/PUBREC 2021-01-26 17:18:52 -05:00
Christian df45540d6b Update docs. 2021-01-25 22:28:01 +01:00
Christian 2abcf6d8bc Update docs. 2021-01-25 22:27:45 +01:00
Christian c1001db450 Add packet inspector API. 2021-01-24 20:58:15 +01:00
tamas.kurucsai fcbe2e32f6 corrected name of response sender method 2021-01-18 17:58:49 +01:00
tamas.kurucsai f955b4a3e6 implemented delayed message acknowledgement 2021-01-18 10:47:21 +01:00
SeppPenner 3d8d06f9b3 Hopefully completely reset the IManagedMqttClient file. 2021-01-15 20:43:57 +01:00
SeppPenner d804b805c1 Smaller changes on the comments. 2021-01-15 20:41:47 +01:00
SeppPenner bba04e2b5d Updated all code comments, should be ok now. 2021-01-15 20:34:33 +01:00
SeppPenner 5eab337e13 Removed not needed comments on client side (Server side is still missing). 2021-01-15 19:41:45 +01:00
Christian e1d39a3fef Fix build of MQTTnet Server. 2021-01-10 12:55:38 +01:00
Christian 3f5d627e9e Fix issues in QoS 2 handling. 2021-01-07 23:22:45 +01:00
SeppPenner 2047f44554 Added client documentation. 2021-01-03 21:46:53 +01:00
Christian 75845d6416 Fix cancellation issues when connecting. 2021-01-01 15:56:38 +01:00
Christian 74e952bb03 Merge remote-tracking branch 'origin/master' 2020-12-23 21:38:14 +01:00
Christian 3773048bc5 Update docs. 2020-12-23 21:38:08 +01:00
Christian f9aec0c067 Merge pull request #1048 from tobiasfrick/bugfix/cleandisconnect
Only set _cleanDisconnectInitiated if no disconnect is pending
2020-12-23 17:21:04 +01:00
Tobias Frick 91c8a15f65 Only set _cleanDisconnectInitiated if no disconnect is pending 2020-12-21 13:26:59 +01:00
Christian b95d6b08bc Update docs. 2020-12-19 13:45:13 +01:00
Christian a44ea74739 Merge pull request #1027 from StefanOssendorf/feature/Add-net5-tfm
.Net5.0 TFMs added
2020-12-19 13:02:11 +01:00
JanEggers 02e65bca67 fixed .net 5 build 2020-12-16 14:45:15 +01:00
Stefan Ossendorf 37b783908a .Net5.0 TFMs added
.Net5.0 TFMs added and related nuget packages updated.
2020-12-16 14:45:15 +01:00
Christian 72211ae85a Improve packet writer performance. 2020-12-14 21:17:22 +01:00
Christian 1f78a92c4d Remove timeout from send method. 2020-12-14 21:17:11 +01:00
Christian f92cfcd293 Add new multi threaded application message handler for server. 2020-12-13 11:36:31 +01:00
Christian 86256d1b10 Update README.md 2020-12-09 22:42:07 +01:00
Christian c3e65390ab Improve performance test. 2020-12-08 21:08:05 +01:00
Christian b0699003e2 Refactor code. 2020-12-08 21:07:58 +01:00
Christian 1214b15260 Update docs. 2020-11-29 11:43:29 +01:00
Christian 322067466b Fix wrong usage of client session items for undelivered messages. 2020-11-25 21:31:26 +01:00
Christian ef2ed1c897 Remove _WithoutAutoReconnect_ from managed client. 2020-11-25 21:18:36 +01:00
Christian 9fddfb3e77 Add UnitTests 2020-11-25 21:08:01 +01:00
Christian ec015e7620 Refactor naming for background tasks. 2020-11-25 21:07:50 +01:00
Christian 7738c5faa1 Refactor platform detection for unsupported features. 2020-11-21 15:43:32 +01:00
Christian 01bb09ff4b Remove obsolete files. 2020-11-17 22:23:08 +01:00
Christian e1494c1004 Update nuget packages. 2020-11-17 22:06:20 +01:00
Christian 1e2231c461 Improve Unit Tests. 2020-11-16 21:03:18 +01:00
Christian de0f5dc1f0 Update docs. 2020-11-16 20:57:31 +01:00
Christian a93f44217b Align different formats of log messages. 2020-11-16 20:47:44 +01:00
Christian f9c3014e52 Fix Unit Tests. 2020-11-15 14:34:59 +01:00
Christian 483c2d8b10 Fix Unit Tests. 2020-11-15 14:21:11 +01:00
Christian 02ab0e4903 Fix Unit Tests. 2020-11-15 14:17:18 +01:00
Christian 0bc25571e0 Fix Unit Tests 2020-11-15 12:46:10 +01:00
Christian Kratky 5b29b8cfd8 Fix Unit Tests. 2020-11-14 16:06:43 +01:00
Christian Kratky dd9dc054e8 Merge remote-tracking branch 'origin/master' 2020-11-14 15:31:06 +01:00
Christian Kratky b7c178b85c Fix Unit Tests. 2020-11-14 15:30:57 +01:00
Christian f8e29f8dc0 Update appveyor.yml 2020-11-14 15:24:49 +01:00
Christian 3d68951f68 Update MQTTnet.nuspec 2020-11-14 11:40:58 +01:00
Christian 7eb6d2d1e3 Merge pull request #1019 from chkr1011/feature/Single_Connection_Monitoring_Task
Feature/single connection monitoring task
2020-11-14 10:36:18 +01:00
Christian Kratky 0446635ed6 Add comments. 2020-11-14 10:35:08 +01:00
Christian Kratky 4514348821 Fix Unit Tests. 2020-11-13 23:24:45 +01:00
Christian Kratky 7b32abe625 Fix Unit Tests. 2020-11-13 23:11:01 +01:00
Christian Kratky 0febc12b3d Merge branch 'master' into feature/Single_Connection_Monitoring_Task 2020-11-13 20:36:51 +01:00
Christian Kratky d0a848c8b4 Improve performance. 2020-11-13 20:33:47 +01:00
Christian fe69f5a633 Merge pull request #1029 from mmuecke/patch-1
Added reference to Rx Wrapper for Managed Client
2020-11-12 11:26:22 +01:00
mmuecke ca95754fc3 Added reference to Rx Wrapper for Managed Client 2020-11-12 00:24:01 +00:00
Christian Kratky cc405c3e90 Update settings. 2020-11-11 21:12:37 +01:00
Christian Kratky 315206f05e Update settings. 2020-11-11 21:12:15 +01:00
Christian Kratky f252374437 Extend support for topic alias. 2020-11-11 21:12:04 +01:00
Christian Kratky 38d3531db6 Refactor code. 2020-11-11 21:11:49 +01:00
Christian Kratky da5a172504 Refactor code. 2020-11-09 21:30:36 +01:00
Christian Kratky f894622884 Merge branch 'master' into feature/Single_Connection_Monitoring_Task 2020-11-09 21:29:38 +01:00
Christian 88b0af9b21 Merge pull request #1023 from StefanOssendorf/fix/compile-error
Fix: Compile error, cancellation token removed since the method does not support it
2020-11-09 21:11:48 +01:00
Christian Kratky e1bf9de347 Add support for topic alias. 2020-11-09 21:10:05 +01:00
Christian Kratky 6c15693456 Add support for TopicAlias in application message builder. 2020-11-09 17:22:32 +01:00
Stefan Ossendorf 4608930a37 Cancellation token removed since the method does not support it
Cancellation token removed because the SendAsync() method does not support it.
2020-11-08 14:31:01 +01:00
Christian Kratky eaf1195f95 Cleanup Unit Tests. 2020-11-06 21:00:25 +01:00
Christian Kratky a35dee9352 Update docs. 2020-11-06 20:03:33 +01:00
Christian 6cef746ed9 Merge pull request #1021 from nayato/max-qos
Add support for Maximum QoS property on CONNACK
2020-11-06 20:00:09 +01:00
Max Gortman 344cf674e6 PR fixes 2020-11-05 16:55:50 -08:00
Christian Kratky 26af205ab0 Update docs. 2020-11-04 21:29:26 +01:00
Christian Kratky 06c9d27c87 Fixed bug in PubRel packet generation (MQTTv5 only). 2020-11-04 21:28:40 +01:00
Max Gortman 14224e4180 Add support for Maximum QoS property on CONNACK 2020-11-03 12:19:38 -08:00
Christian Kratky b954c9512e Fix swagger configuration. 2020-11-02 22:03:47 +01:00
Christian Kratky fb2be79673 Remove not used timeout for receiving. 2020-11-02 21:45:23 +01:00
Christian Kratky 44b7133a1c Improve keep alive tests. 2020-11-02 21:17:31 +01:00
Christian Kratky 2f0513212e Merge branch 'master' into feature/Single_Connection_Monitoring_Task 2020-11-01 12:35:59 +01:00
Christian Kratky 1a9460776b Update docs. 2020-11-01 12:03:19 +01:00
Christian Kratky 2716db04e3 Move the RPC topic validation to the topic generation strategy. 2020-11-01 12:00:12 +01:00
Christian Kratky 3e4f4a59a8 Improve Unit Tests. 2020-11-01 11:58:43 +01:00
Christian Kratky 24f0ea01f5 Improve session takeover and keep alive handling. 2020-10-31 20:59:41 +01:00
Christian Kratky 1625aadae9 Improve disconnect reason transfer to client (especially for session take over). 2020-10-31 11:43:14 +01:00
Christian Kratky e800901b4c Merge branch 'master' into feature/Single_Connection_Monitoring_Task 2020-10-31 11:33:54 +01:00
Christian Kratky 34ae54d542 Improve Unit Tests. 2020-10-31 11:33:44 +01:00
Christian Kratky 838d50c1d3 Remove file which is not part of the solution. 2020-10-31 11:27:46 +01:00
Christian Kratky 558d281a33 Refactor TLS 1.3 support. 2020-10-31 11:23:14 +01:00
Christian Kratky f8c956a9e2 Merge remote-tracking branch 'origin/master' 2020-10-31 11:14:07 +01:00
Christian 9a6823597e Merge pull request #1020 from Dvergatal/master
Added support for Tls1.3
2020-10-31 11:13:50 +01:00
Christian Kratky 42c1155bee Fix nullref exception in connection handler. 2020-10-30 23:51:11 +01:00
Christian Kratky f773257c86 Improve exception handling in AsyncQueue. 2020-10-30 20:43:39 +01:00
Christian Kratky 4e9df98817 Improve test environment. 2020-10-30 20:43:02 +01:00
Christian Kratky 3208045baa Extend application message builder. 2020-10-30 20:42:52 +01:00
Piotr Łobacz 7274f4390c added support for Tls1.3 protocol 2020-10-30 12:45:57 +01:00
Dvergatal 11c8abfd54 Merge pull request #1 from chkr1011/master
Merging with mainline.
2020-10-30 11:16:09 +01:00
Christian Kratky f606a5996b Merge remote-tracking branch 'origin/master' 2020-10-30 00:26:40 +01:00
Christian Kratky 58ad599783 Improve disconnect code of client. 2020-10-30 00:23:45 +01:00
Christian Kratky ccd102a59f Refactor code. 2020-10-30 00:21:08 +01:00
Christian Kratky 05101f0e0e Improve exception handling of AsyncLock. 2020-10-30 00:19:57 +01:00
Christian Kratky f9630ef347 Improve internal session/connection management and connection takeover. 2020-10-30 00:19:30 +01:00
Christian Kratky c5b7735a2c Improve cancellation token handling for client connections (Server). 2020-10-29 20:02:03 +01:00
HansM 12fca2f05a Merge pull request #1015 from Jay424/patch-1
Fixed evaluation of IgnoreCertificateRevocationErrors to correctly se…
2020-10-29 11:34:23 +01:00
Christian Kratky b7fb0c1002 Refactor package object model. 2020-10-28 23:11:12 +01:00
Jay424 3ea281ff84 Updated release notes 2020-10-28 17:58:48 +01:00
Jay424 c778cd7a0f Fixed evaluation of IgnoreCertificateRevocationErrors to correctly set SslClientAuthenticationOptions.CertificateRevocationCheckMode
The if was just flipped.
2020-10-28 17:14:09 +01:00
Christian Kratky adce5662eb Prepare docs for next release. 2020-10-24 12:22:03 +02:00
Christian Kratky a26b641284 Fix broken connection takeover. 2020-10-15 01:01:35 +02:00
Christian Kratky 7be3685850 Merge remote-tracking branch 'origin/master' 2020-10-14 23:10:40 +02:00
Christian Kratky 1a6be47144 Update docs. 2020-10-14 23:10:13 +02:00
Christian 5d73de2a86 Merge pull request #1004 from JanEggers/fix#990
improved behavior when multiple connections fight over a session
2020-10-14 21:18:36 +02:00
JanEggers 2eaebe0e6a removed todo 2020-10-13 15:59:39 +02:00
JanEggers d7b552fce2 renaming and added cast 2020-10-13 15:57:21 +02:00
Christian bea6d75251 Merge pull request #993 from chkr1011/client-disconnected-handler
Tried to add a MqttServerOptions fluent method for the client disconn…
2020-10-12 20:38:15 +02:00
JanEggers f7db00c08e improved behavior when multiple connections fight over a session 2020-10-11 16:41:13 +02:00
Christian Kratky f259bbcc9b ManagedClient: Expose internal client. 2020-10-07 19:38:42 +02:00
SeppPenner 252772007b Changed MqttServerClientDisconnectedHandlerDelegate back again. 2020-09-27 17:43:06 +02:00
SeppPenner 21a9974e5d Tried to add a MqttServerOptions fluent method for the client disconnected handler. 2020-09-21 18:23:11 +02:00
Christian Kratky d63143bdc9 ManagedClient: Add new option for disabling auto reconnect. 2020-09-14 23:49:27 +02:00
Christian Kratky aad9eac361 Refactor AWS integration. 2020-09-14 22:01:07 +02:00
Christian Kratky e8a683b936 Merge remote-tracking branch 'origin/master' 2020-09-14 21:47:38 +02:00
Christian Kratky e475e36ce7 Update docs. 2020-09-14 21:47:36 +02:00
Christian 611c230da2 Merge pull request #981 from henning-krause/master
Added ApplicationProtocols support to the TLS options to support AWS MQTT on port 443
2020-09-14 21:46:18 +02:00
Krause, Henning 18839de083 Removed -prelease switch from build 2020-09-14 19:14:39 +02:00
Krause, Henning 194664bc9c Reverted bogus change 2020-09-14 19:13:49 +02:00
Krause, Henning 10a33fd153 Removed -prelease switch from build 2020-09-14 19:12:30 +02:00
Christian Kratky 868aa7d89a Merge remote-tracking branch 'origin/master' 2020-09-14 10:02:40 +02:00
Christian Kratky 1f8792cf87 Update docs. 2020-09-14 09:59:19 +02:00
Christian 7bb99c8b37 Merge pull request #979 from msallin/bugfix/978/ClientMessageQueueInterceptor
Bugfix/978/client message queue interceptor
2020-09-14 09:48:13 +02:00
Marc Sallin 7f5504b01b Fix wrong QoS when using MqttClientMessageQueueInterceptor #978 2020-09-04 09:53:34 +02:00
Marc Sallin fd789417e7 Extend MqttClientMessageQueueInterceptorContext to expose SubscriptionQualityOfServiceLevel 2020-09-04 09:53:34 +02:00
Marc Sallin f1f9924bce Expose WithClientMessageQueueInterceptor 2020-09-04 09:53:34 +02:00
Marc Sallin b0c603082b Rename "QualityOfServiceLevel" to SubscriptionQualityOfServiceLevel where appropriated to make the difference between the two different QoS fields more clear 2020-09-04 09:53:34 +02:00
Krause, Henning f3f10e9f65 Added missing nuget instructions for the build 2020-09-01 19:44:52 +02:00
Krause, Henning beb228cc05 Fixed issues from code review 2020-08-29 13:51:16 +02:00
Krause, Henning 7a7f0640ba Reverted solution file 2020-08-28 19:12:30 +02:00
Krause, Henning 55d009ce6b Reverted solution file 2020-08-28 19:11:37 +02:00
Krause, Henning e23ac4f703 Removed test program 2020-08-28 19:08:45 +02:00
Krause, Henning fc367ddb64 Added support to set TLS Application Protocols 2020-08-28 19:07:31 +02:00
Christian Kratky cf217034fa Fix broken ClientWasConnected detection. 2020-08-22 20:44:24 +02:00
Christian Kratky 6b6627f823 Fix null ref exception in low level client. 2020-08-05 20:49:11 +02:00
Christian Kratky 4f51a238b3 Fix UnitTests 2020-07-26 20:07:52 +02:00
Christian Kratky 733c587e45 Fix Unit Tests. 2020-07-26 12:01:33 +02:00
Christian Kratky 3260920828 Fix UnitTests 2020-07-25 23:47:29 +02:00
Christian Kratky 4e6aeb91a4 Fix server adapter memory leak and UnitTests 2020-07-25 23:34:30 +02:00
Christian Kratky 5056843611 Fix UnitTests. 2020-07-25 14:21:09 +02:00
Christian Kratky a65c015a58 Refactor exception message. 2020-07-25 13:43:26 +02:00
Christian e63f26789f Merge pull request #959 from Mephistofeles/ManagedMqttClientExtensions
Modified ManagedMqttClientExtensions to work on less specific interfaces
2020-07-25 13:32:31 +02:00
Christian 9a598892a7 Merge pull request #954 from JanEggers/fix#788
improve exceptions in case of corrupt packages
2020-07-25 13:30:54 +02:00
Paweł Słowik 857ab005be Modified IManagedMqttClient extension methods to work on less specific interfaces (IApplicationMessagePublisher and IApplicationMessageReceiver) 2020-07-18 18:25:16 +02:00
JanEggers 33e4ec1943 improve exceptions in case of corrupt packages close pipes after exception occoured to avoid lingering connections should fix #788 2020-07-09 21:19:00 +02:00
Christian Kratky 6a564a0c72 Align nuget dependency versions and project references. 2020-07-04 17:04:36 +02:00
Christian 3a4dce5080 Update MQTTnet.nuspec 2020-06-28 00:17:30 +02:00
Christian 4e6118d324 Merge pull request #946 from JTOne123/master
[PR] The proj files have been updated to enable SourceLink
2020-06-27 23:10:39 +02:00
Pavlo Datsiuk 269bfa09ac [COMMIT] The proj files have been updated to enable SourceLink [MQTTnet.AspNetCore.csproj] 2020-06-25 12:53:00 +03:00
Pavlo Datsiuk 59dd6b98a3 [COMMIT] The proj files have been updated to enable SourceLink [MQTTnet.csproj] 2020-06-25 12:52:58 +03:00
Pavlo Datsiuk 9f37306f20 [COMMIT] The proj files have been updated to enable SourceLink [MQTTnet.Extensions.WebSocket4Net.csproj] 2020-06-25 12:52:55 +03:00
Pavlo Datsiuk 85b000c6b7 [COMMIT] The proj files have been updated to enable SourceLink [MQTTnet.Extensions.Rpc.csproj] 2020-06-25 12:52:52 +03:00
Pavlo Datsiuk 5a919ce5d2 [COMMIT] The proj files have been updated to enable SourceLink [MQTTnet.Extensions.ManagedClient.csproj] 2020-06-25 12:52:49 +03:00
Christian 57ab8e5abc Merge pull request #941 from chkr1011/disconnect-reason-codes
Added missing disconnect reason codes.
2020-06-18 20:25:16 +02:00
SeppPenner 8f6d48be81 Adjusted ImplementationSpecificError to be UnspecifiedError reason code in the MqttClient. 2020-06-18 10:03:44 +02:00
Christian 38cfa15cc3 Merge pull request #938 from chkr1011/interceptor-undelivered
Added interceptor for undelivered messages.
2020-06-15 23:13:06 +02:00
SeppPenner 6adf7096ec Updated client sessions manager to handle the delivery count for the handler correctly. 2020-06-12 20:25:51 +02:00
SeppPenner df149eb0b3 Added reason code to MqttClientDisconnectedEventArgs and use it. 2020-06-12 20:21:23 +02:00
Christian Kratky 63c9329190 Merge remote-tracking branch 'origin/master' 2020-06-12 11:19:36 +02:00
Christian Kratky 246a10649a Minor refactorings. 2020-06-12 11:19:29 +02:00
SeppPenner 0a76ac15c6 Added missing disconnect reason codes. 2020-06-11 18:06:24 +02:00
HansM d801af5616 Merge branch 'master' into interceptor-undelivered 2020-06-11 12:46:02 +02:00
SeppPenner 257211fc7a Moved undeliveredMessageInterceptor to local variable to avoid threading issues. 2020-06-11 12:41:48 +02:00
SeppPenner a407fc381b Made deliveryCount a local variable. 2020-06-11 12:39:56 +02:00
Christian 4fa275bf2b Merge pull request #937 from chkr1011/fix-writeasync-nre
Added checks for null references in the MqttTcpChannel.
2020-06-10 21:09:48 +02:00
SeppPenner 7cf12dc751 Made delivery count internal. 2020-06-10 18:45:15 +02:00
SeppPenner 40aefd0ad3 Added local variable to avoid that the solution is not threadsafe. 2020-06-10 12:00:34 +02:00
SeppPenner c20142671f MQTTnet: Adjusted UndeliveredMessageInterceptor handler to return if it's null instead of throwing an exception. 2020-06-10 11:52:55 +02:00
SeppPenner 75dfe68a94 Added interceptor for undelivered messages. 2020-06-09 20:54:42 +02:00
Christian 92518fc4ec Merge pull request #935 from JanEggers/fixedParallelWrites
fixed parallel writes #932
2020-05-27 21:44:26 +02:00
JanEggers 16180e83ba fixed parallel writes #932 2020-05-27 20:38:34 +02:00
Christian Kratky c779b394f1 Add abstraction layer for server certificate. 2020-05-26 23:46:43 +02:00
Christian Kratky e60a732b61 Merge remote-tracking branch 'origin/master' 2020-05-26 23:17:10 +02:00
Christian Kratky 7ea9415c63 Add proper state checks for server API. 2020-05-26 23:17:06 +02:00
Christian 13c399bc9a Merge pull request #895 from borigas/x509Cert
Add an x509 certificate parameter
2020-05-26 23:14:23 +02:00
Christian Kratky 4565c3990a Fix Blazor projects. 2020-05-25 22:33:05 +02:00
Christian Kratky 2bd2648b48 Merge remote-tracking branch 'origin/master' 2020-05-25 22:31:11 +02:00
Christian Kratky 1b56155f1c Add Blazor test app. 2020-05-25 22:31:07 +02:00
Christian 626930cfae Update README.md 2020-05-24 16:37:02 +02:00
Christian 6cf9cb0af2 Update README.md 2020-05-24 16:36:54 +02:00
Christian Kratky 60941c04e5 Add new factory overloads. 2020-05-22 22:02:05 +02:00
Christian Kratky ba68b1274b Merge remote-tracking branch 'origin/master' 2020-05-21 12:40:56 +02:00
Christian Kratky dbe12b9c48 General code refactoring. 2020-05-21 12:40:51 +02:00
Christian 52b79a140b Merge pull request #930 from prime167/patch-1
Update MqttTopicFilterBuilder.cs
2020-05-21 12:38:17 +02:00
Jeff Zhou c270225e9e Update MqttTopicFilterBuilder.cs
Fix TopicFilterBuilder obsolete message
2020-05-21 09:35:07 +08:00
Christian Kratky 3f5d4e9825 Added MQTT JS examples for MQTTnet.Server. 2020-05-16 20:59:54 +02:00
Christian Kratky e80d19ba9b Update docs. 2020-05-16 13:01:50 +02:00
Christian Kratky 48837529a2 Fix web socket sub protocol negotiation. 2020-05-16 13:01:41 +02:00
Christian Kratky 43e3ad4c00 Add support for static files. 2020-05-16 13:01:12 +02:00
Christian Kratky 08c9ecb011 Fix wrong keep alive delay calculation. 2020-05-16 10:32:50 +02:00
Christian Kratky 763f0e7934 Update nuspec. 2020-05-14 21:01:39 +02:00
Christian Kratky 9d381c2cf9 Update nuspec. 2020-05-14 00:40:14 +02:00
Christian Kratky 17ceb20169 Add dummy method to allow safe downgrade. 2020-05-14 00:18:50 +02:00
Christian Kratky 683bb43486 Fix performance issue in logger. 2020-05-14 00:05:52 +02:00
Christian Kratky d25b51740b Merge remote-tracking branch 'origin/master' 2020-05-12 21:55:17 +02:00
Christian Kratky a58ab607ad Improve logger performance. 2020-05-12 21:55:15 +02:00
Christian 0a7d450f3b Merge pull request #920 from mseyock/change-icon
Remove shadow from icon
2020-05-08 16:37:31 +02:00
ms 999fa7a468 Remove shadow from icon 2020-05-08 15:21:50 +02:00
Christian Kratky f0a1f9ca93 Add support for user properties in client connect. 2020-05-04 23:15:38 +02:00
Christian Kratky 89e9cb224f Update nuspec. 2020-05-02 21:20:22 +02:00
Christian Kratky fe48c9c837 Update nuspecs. 2020-05-01 23:39:17 +02:00
Christian Kratky 2a421d1d42 Refactor code. 2020-05-01 21:47:25 +02:00
Christian Kratky 48d0344a40 Fix WebSocket4Net extension nuspec. 2020-04-30 23:15:28 +02:00
Christian Kratky db5ed594f7 Merge remote-tracking branch 'origin/master' 2020-04-30 23:02:09 +02:00
Christian Kratky f85bc9b956 Dispose socket when TCP connect failed. 2020-04-30 23:02:05 +02:00
Christian eec46dd9bc Update LICENSE 2020-04-30 22:07:50 +02:00
Christian 9c9e2293c8 Update README.md 2020-04-29 18:04:17 +02:00
Christian 856861e1b1 Merge pull request #909 from JanEggers/nuget
removed unused dependecies
2020-04-27 21:24:24 +02:00
JanEggers 4b481b4833 removed unused dependecies 2020-04-27 17:09:54 +02:00
Christian c05f11a495 Update README.md 2020-04-25 14:44:07 +02:00
Christian Kratky e798c91ff3 Fix exception handling when using invalid host names upon connect. 2020-04-24 19:29:03 +02:00
Christian Kratky 5df4fc3d5d Update docs. 2020-04-22 21:10:55 +02:00
Christian Kratky c6236c0865 Remove nuget config. 2020-04-22 21:09:48 +02:00
Christian Kratky 85c0cb3bcc Remove nuget config because it breaks the CI. 2020-04-22 12:32:57 +02:00
Christian Kratky 9810e52bcb Fix build. 2020-04-22 12:30:11 +02:00
Christian Kratky 948a5eaae3 Merge remote-tracking branch 'origin/master' 2020-04-22 12:05:11 +02:00
Christian Kratky 31df8247fa Try to fix CI build. 2020-04-22 12:05:05 +02:00
Christian 229418100c Merge pull request #904 from JanEggers/nuget
fixed netcoreapp3.1 build #903
2020-04-22 12:04:02 +02:00
JanEggers 93d8679bbc fixed netcoreapp3.1 build 2020-04-21 21:19:49 +02:00
Christian 6cec126862 Update README.md 2020-04-19 01:11:15 +02:00
Christian Kratky 9749f790ea Try to fix CI builds. 2020-04-18 20:35:39 +02:00
Christian Kratky fbbc638c75 Try to fix CI builds. 2020-04-18 20:28:46 +02:00
Christian Kratky bf679adb6b Try to fix CI builds. 2020-04-18 19:43:28 +02:00
Christian Kratky cf7e59a774 Improve unit tests. 2020-04-18 16:55:37 +02:00
Christian e9724c0202 Merge pull request #882 from xljiulang/master
Use IConnectionEndPointFeature to get IMqttChannelAdapter.Endpoint in aspnetcore31
2020-04-18 13:49:45 +02:00
Christian Kratky 7931af7487 Add support for certificate validation callback for Web Socket connections. 2020-04-18 13:46:20 +02:00
Christian Kratky bb5f023b74 Update docs. 2020-04-18 01:38:53 +02:00
Christian Kratky c2ac4fffaf Expose PING method for clients. 2020-04-18 01:38:48 +02:00
Christian Kratky 4b78710705 Refactor topic filter naming. 2020-04-18 01:38:20 +02:00
Christian Kratky 2e69f8be78 Merge remote-tracking branch 'origin/master' 2020-04-16 12:48:31 +02:00
Christian Kratky 2d6c44e45b MQTTnet.Server: Fix version detection. 2020-04-16 12:48:26 +02:00
Ben Origas fc3965f5a3 Also Wrap certificate namespace in a !UWP compiler directive in options builder 2020-04-15 10:00:25 -05:00
Ben Origas 1d553c5ece Wrap certificate namespace in a !UWP compiler directive 2020-04-15 09:57:06 -05:00
Ben Origas 07ad9fc557 Add exception if both Certificate and X509Certificate are set 2020-04-15 09:55:23 -05:00
Christian f001d7aecc Merge pull request #898 from xgstation/master
Fix hanging issue under UWP.
2020-04-14 22:21:31 +02:00
JanEggers d49a4384c0 use the RemoteEndpoint property from the ConnectionContext and added test 2020-04-14 19:16:32 +02:00
Gen 4e6658e014 Fix typo. 2020-04-14 09:36:02 -07:00
Gen 2b2b30912c Configure context. 2020-04-14 07:37:23 -07:00
Gen 79d95c8516 Fix hanging issue under UWP. 2020-04-13 03:04:44 -07:00
Ben Origas 88e8691ce0 Move server x509 certs into non-uwp compiler flags 2020-04-10 17:16:42 -05:00
Ben Origas 28641892f5 Add an x509 certificate parameter 2020-04-10 17:16:42 -05:00
Christian Kratky 4b08bb41f5 Refactor code. 2020-04-10 10:53:17 +02:00
Christian Kratky c89918a890 Update python runtime for MQTTnet.Server. 2020-04-08 22:01:20 +02:00
Christian 6546175ea2 Update README.md 2020-04-07 12:22:16 +02:00
Christian Kratky b9e9fe64ac Refactor adapter handling. 2020-04-05 15:43:16 +02:00
Christian 9fd7c7bc1e Merge pull request #891 from PSanetra/async-message-processing
Introduce asynchronous message processing
2020-04-04 23:36:58 +02:00
PSanetra fcd6b7ff52 Process messages async
This commit fixes issues which were caused by processing messages synchronously in the packet receiver loop. This blocked KeepAlive and Ack packets from being processed while a message was processed.

Fixes #648
Fixes #587
Fixes #829
2020-04-04 22:40:16 +02:00
Christian Kratky 54870adc64 Fix build warnings and errors. 2020-04-04 19:40:09 +02:00
PSanetra 892e4842ed Fix MQTTnet.Tests/Server_Tests/Same_Client_Id_Connect_Disconnect_Event_Order
This failing test was caused by a raise condition in the MqttClientSessionsManager
The test failed as the value of `flow` in the assertion `Assert.AreEqual("cdc", flow);` was "ccd"
2020-04-04 15:03:15 +02:00
Christian Kratky fc358f9015 Fix build errors. 2020-04-04 13:08:29 +02:00
Christian Kratky b93cd5b673 Refactor code. 2020-04-04 13:07:10 +02:00
Christian aafc99f39e Merge pull request #884 from chkr1011/feature-isconnected
Added check if the server is started or not.
2020-04-04 13:05:58 +02:00
Christian b14d7affe5 Merge branch 'master' into feature-isconnected 2020-04-04 13:05:45 +02:00
Christian Kratky 67d56644b2 Expose custom session items in session status. 2020-04-04 12:54:33 +02:00
Christian Kratky 6e0d3ec0fb Update nuget packages. 2020-04-04 12:15:51 +02:00
Christian Kratky 2c6613a7b7 Merge branch 'feature/low_level_client' 2020-04-04 01:09:48 +02:00
Christian Kratky d464bfb7c5 Fix connect and disconnect event flow. 2020-04-04 01:01:37 +02:00
Christian Kratky 7a24970035 Fix UnitTests. 2020-04-03 23:08:54 +02:00
Christian Kratky db906eca24 Merge branch 'master' into feature/low_level_client 2020-04-03 22:53:22 +02:00
Christian Kratky ad128c7889 Improve socket handling. 2020-04-03 22:52:55 +02:00
Christian 3e096bc353 Merge pull request #886 from PMExtra/feature-userproperties
GetUserProperty extension.
2020-04-03 22:50:52 +02:00
HansM f0be8404cf Merge branch 'master' into feature-userproperties 2020-04-03 18:49:39 +02:00
Christian 6de28d32e4 Merge pull request #889 from PMExtra/feature-with-uri
Support MqttClientOptionsBuilder.WithConnectionUri()
2020-04-03 14:32:11 +02:00
PM Extra 2ede7df38a Merge branch 'master' into feature-userproperties 2020-04-03 18:04:00 +08:00
PM Extra 2a35108a73 Merge branch 'master' into feature-with-uri 2020-04-03 18:03:11 +08:00
PMExtra 774d49a908 Fix exception message and add test cases. 2020-04-03 15:03:10 +08:00
PMExtra c83bec6e81 Fix for Nullable. 2020-04-03 14:44:04 +08:00
PMExtra 763d9778bb Check parameters and add friendly exceptions. 2020-04-02 17:29:24 +08:00
PMExtra 9368eebfd5 Update nuspec. 2020-04-02 16:07:21 +08:00
Christian Kratky 81b547f386 Fix logging issues. 2020-04-01 23:15:08 +02:00
Christian e33c5ccb4c Merge pull request #885 from chkr1011/fix-userproperties
Removed checks for user properties in MQTT v3 and instead ignore them.
2020-04-01 23:02:08 +02:00
Christian Kratky 0ca4c88e69 Merge branch 'master' into feature/low_level_client 2020-04-01 23:01:03 +02:00
Christian Kratky 04ccdcd562 Add low level client. 2020-04-01 20:43:00 +02:00
PMExtra aafd4ea658 Fix. 2020-04-01 15:30:24 +08:00
PMExtra 4eb65fc3d2 Support MqttClientOptionsBuilder.WithConnectionUri() 2020-03-31 16:42:04 +08:00
PMExtra f7f00f4e06 Update nuspec. 2020-03-31 12:03:00 +08:00
HansM af0b98eace Merge pull request #888 from chkr1011/fix-copyright-date
Adjusted copyright information in the nuget package specifications.
2020-03-30 19:47:46 +02:00
SeppPenner 0da2ab9de6 Adjusted copyright information in the nuget package specifications. 2020-03-30 19:46:18 +02:00
SeppPenner ea22ef4164 Adjusted .nuspec file, added property to interface as well. 2020-03-30 19:44:15 +02:00
SeppPenner cb5a0cf38b Updated nuget package description. 2020-03-30 19:38:44 +02:00
PMExtra 55dc940abb GetUserProperty extension. 2020-03-30 17:10:04 +08:00
SeppPenner c40e3c64aa Removed checks for user properties in MQTT v3 and instead ignore them. 2020-03-29 17:26:40 +02:00
SeppPenner 87c4fa14ee Added check if the server is started or not. 2020-03-29 16:48:19 +02:00
Christian Kratky 0653b89701 Fix broken unit tests. 2020-03-26 22:33:30 +01:00
Christian Kratky 561474c572 Fix broken unit tests. 2020-03-26 15:35:14 +01:00
陈国伟 c10145f743 Use IConnectionEndPointFeature to get IMqttChannelAdapter.Endpoint in aspnetcore31 2020-03-26 12:32:09 +08:00
Christian dca2af47d8 Merge pull request #880 from xljiulang/master
Reduce the performance cost of Memory<T>.getSpan()
2020-03-25 21:33:34 +01:00
xljiulang 9ed80daf83 Reduce the performance cost of Memory<T>.getSpan() 2020-03-25 21:32:43 +08:00
Christian 0d39bbbc0c Merge pull request #870 from JanEggers/aspnetcore3bugfixes
Aspnetcore3bugfixes
2020-03-17 10:17:12 +01:00
JanEggers 52faf6d76a updated releasenotes 2020-03-15 14:47:50 +01:00
JanEggers 20eda96921 fixed core 3.1 startup and verified it still works with 2.1 and net461 2020-03-15 14:43:59 +01:00
Christian Kratky f6a814c6d7 Update build script. 2020-03-14 23:52:07 +01:00
Christian Kratky 8e0bce7734 Remove obsolete references. 2020-03-14 23:49:26 +01:00
Christian Kratky 72fa13ca5b Fix build errors. 2020-03-14 22:59:17 +01:00
Christian Kratky 45e3455e6c Merge remote-tracking branch 'origin/master' 2020-03-14 22:46:23 +01:00
Christian 160da00f55 Merge pull request #873 from andrei-m-code/bugfix/mqttnet-client-semaphore-dispose
DIspose semaphore in MqttChannelAdapter
2020-03-14 22:39:46 +01:00
Christian Kratky 6b4b829cf6 Merge branch 'develop' 2020-03-14 22:38:36 +01:00
Andrei Mikhalevich e7fa465616 DIspose semaphore in MqttChannelAdapter 2020-03-12 11:07:30 -04:00
Christian 799005803e Merge pull request #869 from dominikviererbe/feature/MqttClientUnsubscribeOptionsBuilder
Added MqttClientUnsubscribeOptionsBuilder
2020-03-10 09:55:57 +01:00
Dominik Viererbe a20c845a5a Update MQTTnet.nuspec 2020-03-09 18:27:35 +01:00
Dominik Viererbe 5f59aca62c Added MqttClientUnsubscribeOptionsBuilder analogous to MqttClientSubscribeOptionsBuilder 2020-02-25 16:30:08 +01:00
HansM 76ddf8c503 Merge pull request #852 from cdobler/check-"Keep-Alive"-while-other-messages-are-sent-#851
Added receiveTracker to detect whether messages are received from broker.
2020-02-24 17:02:42 +01:00
Christoph 122034296c Merge branch 'develop' into check-"Keep-Alive"-while-other-messages-are-sent-#851 2020-02-24 08:20:25 +01:00
Christian 6f71aaf1ce Merge pull request #868 from wazzamatazz/master
Add .NET 3.1 target
2020-02-22 19:32:12 +01:00
Graham Watts fd8caed9af Add .NET 3.1 target
Add .NET Core 3.1 target that uses ASP.NET Core framework reference instead of NuGet package references
2020-02-22 11:25:01 +02:00
Christoph 313f90a526 Added receiveTracker to detect whether messages are received from broker. 2020-01-28 14:36:19 +01:00
Christian Kratky 4d27f42e72 Merge remote-tracking branch 'origin/develop' into develop 2020-01-25 23:34:53 +01:00
Christian 8ae318fd5c Merge pull request #838 from jimsch/connectErrors
Allow access to full packet on failed connect
2020-01-12 22:11:28 +01:00
Jim Schaad 7dde2f1f4c Change variable name per review request
Change the name of the variable from requestCode to request
2020-01-12 12:31:09 -08:00
Christian Kratky 49c5278ba0 Merge branch 'master' into develop 2020-01-10 22:18:48 +01:00
Christian Kratky ce51d12a03 Update SDK versions. 2020-01-10 22:16:31 +01:00
Jim Schaad b1559a8fa5 Correct to print right result
Lost a change while moving from my developement branch to here.
2020-01-08 11:11:41 -08:00
Jim Schaad 457143c840 Merge branch 'develop' into connectErrors 2020-01-08 11:10:58 -08:00
Christian c60bf51b1e Merge pull request #839 from JanEggers/develop
bugfixes
2020-01-08 19:14:08 +01:00
JanEggers 630400da53 avoid task.run on newer platforms 2020-01-04 11:55:12 +01:00
JanEggers a152066ed3 fixed managed client so it does not send disconnect packet when disposed 2020-01-04 11:54:41 +01:00
JanEggers 138cd16c8d fixed compilation 2020-01-04 11:53:15 +01:00
JanEggers 27a61819d3 removed unused code 2020-01-04 11:52:43 +01:00
Jim Schaad 9c378fb088 Provide the full ACK on a connection failure
There are some systems that return information on a failed exception and thus the client wants access to the full set of ACK information.  Specifically the user properties.
2019-12-31 14:44:25 -08:00
Jim Schaad d4088420cf Return correct set of user properties
Return the response not the request set of user properties
2019-12-31 14:33:31 -08:00
Christian 2e7d074174 Merge pull request #833 from JanEggers/bugfixes
Bugfixes
2019-12-28 20:28:38 +01:00
JanEggers 328ffc734f dont allow publish before the client is started and adjusted testclient accordingly 2019-12-28 15:55:35 +01:00
Christian 8ecf658059 Update MQTTnet.nuspec 2019-12-28 14:05:24 +01:00
Christian 7b25c6f274 Merge pull request #836 from PMExtra/develop
Support existing session with ManagedMqttClient.
2019-12-28 14:04:27 +01:00
PMExtra 069c19aab9 Support existing session with ManagedMqttClient. 2019-12-23 20:38:29 +08:00
Christian 35e729bd7b Merge pull request #826 from fogzot/develop-iretainedmesagesmanager
Added IMqttRetainedMessagesManager
2019-12-22 16:50:37 +01:00
JanEggers ac06a001e2 fixed some warnings 2019-12-21 10:42:18 +01:00
JanEggers a77e0b8dde spread dispose pattern 2019-12-21 09:09:03 +01:00
JanEggers 698f0b66d2 fixed object disposed exception on netfx fixing #803 #733 #728 #486 #158 2019-12-20 15:37:42 +01:00
JanEggers 14419e4d63 fixed clients overlapping from one test to another by:
- adding client and server wrappers to verify the clientid starts with the testname
- adding disposable baseclass
- clear disconnect handler from client so it does not try to reconnect after it is disposed
- moved code from dispose to cleanup in case it is called in a stop method as dispose may only be called once while start / stop may be called multiple times
2019-12-20 15:37:23 +01:00
Federico Di Gregorio 3600ebbc62 Create default MqttRetainedMessagesManager in options 2019-12-18 10:25:24 +01:00
Federico Di Gregorio 55676965d9 Use IList in IMqttRetainedMessagesManager return values 2019-12-17 12:39:57 +01:00
Federico Di Gregorio f949d54aef Added IMqttRetainedMessagesManager
* Added interface IMqttRetainedMessagesManager to allow for different
retained messages manager implementations. The interface copies almost
exactly the current MqttRetainedMessagesManager implementation.

* Added IMqttRetainedMessagesManager.Start() to configure the provided
IMqttRetainedMessagesManager outside the constructor. This method returns
Task because some implementations that use external storage may be slow on
initialization (e.g., connect to a database).

* Modified MqttRetainedMessagesManager to implement new interface.
2019-12-17 11:57:17 +01:00
Christian Kratky 624fafc662 Update nugets. 2019-12-08 20:10:46 +01:00
Christian 23e93212a4 Merge pull request #800 from stepkillah/develop
Replace raw bytes with x509 certificate to allow specify passwords and flags #2
2019-11-27 21:33:21 +01:00
Anton Yaroshenko f9b2c91ddb merged 2019-11-18 11:32:00 +02:00
Anton Yaroshenko 9fb1cc3320 added UWP compiler flags 2019-11-18 11:16:34 +02:00
Christian Kratky 1c89a8bc75 Update docs. 2019-11-17 21:25:30 +01:00
Christian Kratky 8be9ce8024 Merge remote-tracking branch 'origin/develop' into develop 2019-11-17 21:25:05 +01:00
Christian 002ba27fd3 Merge pull request #799 from chkr1011/revert-798-master
Revert "Replace raw bytes with x509 certificate to allow specify passwords and flags"
2019-11-17 21:24:47 +01:00
Christian 9aaa94e821 Revert "Replace raw bytes with x509 certificate to allow specify passwords and flags" 2019-11-17 21:24:30 +01:00
Anton Yaroshenko e8ff48bfd3 Revert "blind uwp fix"
This reverts commit ac326babdf.
2019-11-17 21:23:20 +01:00
Anton Yaroshenko 5db05f186f Revert "replace raw byte with x509 certificate to allow specify passwords"
This reverts commit a38623cb5a.
2019-11-17 21:23:16 +01:00
Christian b2c2209b4f Update MQTTnet.nuspec 2019-11-17 21:06:37 +01:00
Christian c490e83c91 Merge pull request #798 from stepkillah/master
Replace raw bytes with x509 certificate to allow specify passwords and flags
2019-11-17 21:05:05 +01:00
Anton Yaroshenko ac326babdf blind uwp fix 2019-11-17 20:12:03 +02:00
Anton Yaroshenko a38623cb5a replace raw byte with x509 certificate to allow specify passwords 2019-11-17 19:42:23 +02:00
Christian Kratky a63489fa5e Update docs. 2019-11-14 20:52:35 +01:00
Christian Kratky 4b7409240b Merge remote-tracking branch 'origin/develop' into develop 2019-11-14 20:47:36 +01:00
Christian Kratky 896e9ed0aa Add interceptor for unsubscriptions. 2019-11-14 20:47:33 +01:00
Christian 0950dfbb8b Merge pull request #786 from llrosa/debugFixClientId
Fix for #785 - Skip client disconnection process if unauthorized
2019-11-03 13:23:23 +01:00
Lucas Rosa 4105beb7e6 Some more cleaning up: 2019-10-29 12:55:57 -03:00
Lucas Rosa 5c25905510 Clean up 2019-10-29 12:48:04 -03:00
Lucas Rosa e3f6b579b2 Working PoC 2019-10-29 12:32:20 -03:00
Lucas Rosa c467c9c818 Debugging duplicated client id issue 2019-10-29 11:44:41 -03:00
Christian Kratky 78b57531b6 Update docs. 2019-10-24 20:09:11 +02:00
Christian 84d9f533bd Merge pull request #782 from cstichlberger/develop
Reduce subscription publishing loglevel in ManagedMqttClient
2019-10-24 20:06:47 +02:00
Christoph Stichlberger 7479e320ee Turn subscription publishing loglevel down
- the Info level for publishing subscriptions is quite noisy
 - previously this wasn't a problem because subscription processing was buffered, now the message is logged for nearly every single un/subscription that is made
 - all other frequently recurring log events are also on level Verbose
2019-10-23 17:01:44 +02:00
Christian Kratky 152303dfbd Update docs. 2019-10-18 19:31:40 +02:00
Christian a495668f2b Merge pull request #776 from cstichlberger/branches/fix_managed_client_subscription_issues
Separate current and reconnect subscriptions in managed client
2019-10-18 19:29:09 +02:00
HansM 82b714d4c7 Merge pull request #777 from cstichlberger/develop
Adapt test assembly paths in buildscript
2019-10-18 11:39:06 +02:00
Christoph Stichlberger 44d71b884c Adapt test assembly paths in buildscript 2019-10-17 06:45:46 +02:00
Christoph Stichlberger 781c5d4d7d Separate current and reconnect subscsriptions in managed client
This change kills several birds with one stone:
 - by performing the re-publishing of all subscriptions only at reconnect it fixes issue https://github.com/chkr1011/MQTTnet/issues/569 (retained messages are received again with every new subscription that is added)
 - not sending the subscriptions again with every (un)subscription is also a performance improvement if subscriptions are modified on a regular basis, because only the updated subscriptions are sent to the broker (previously, if you had 100 subscriptions and added a new one, 100 suscriptions were re-sent to the broker along with the new one, causing a significant delay)
 -until now subscriptions were sent to the broker only every ConnectionCheckInterval which caused unnecessary delays, and for request-response patterns could cause reponse messages to be missed due to the subscription delay. Now (un)subscriptions are published immediately

Subscriptions are now cleaned up at logout (after the connection stops being maintained). This is in line with the clearing of the _messageQueue in StopAsync

Explanatory note: the _subscriptionsQueuedSignal could ideally be a ManualResetEvent(Slim) but those do not offer an awaitable Wait method, so a SemaphoreSlim is used. This possibly causes a few empty loops in PublishSubscriptionsAsync due to the semaphore being incremented with every SubscribeAsync call but all subscriptions getting processed in one sweep, but those empty loops shouldn't be a problem
2019-10-15 15:26:05 +02:00
Christian Kratky b175119008 Refactoring and doc updates. 2019-10-04 20:01:51 +02:00
Christian Kratky cfcb858423 Update libs. 2019-10-04 19:51:35 +02:00
Christian Kratky 5fa12649bf Merge remote-tracking branch 'origin/develop' into develop 2019-10-04 19:51:13 +02:00
Christian a9a09f4ecd Merge pull request #754 from jltjohanlindqvist/branches/fixUnhandledTaskCrash
Remove if clause that stopped handling of tasks with exceptions
2019-10-04 19:50:56 +02:00
Christian Kratky 3ff5806dbb Dispose queue in managed client. 2019-10-03 15:26:33 +02:00
Christian Kratky 0ec78cf5cc Merge remote-tracking branch 'origin/develop' into develop 2019-10-03 15:25:02 +02:00
Christian c3193c568a Merge pull request #763 from zawodskoj/master
Fix for #762 - thread pool leak
2019-10-03 15:24:56 +02:00
Christian Kratky a1f02284e9 Merge branch 'master' into develop 2019-10-03 15:23:52 +02:00
Christian Kratky 851db2e808 Merge remote-tracking branch 'origin/master' 2019-10-03 15:23:42 +02:00
Christian Kratky 073cd5243f Update docs. Add UnitTests. 2019-10-03 15:23:35 +02:00
Jimmy Rosenskog 699558e47a Added exception handling to make sure all tasks are observed to avoid UnobservedTaskException. 2019-10-03 09:46:40 +02:00
Бессонов Дмитрий 15ff03c136 use C#7.0 for default arguments 2019-09-30 16:10:30 +03:00
Бессонов Дмитрий b12e3bc611 fix for #762 2019-09-30 16:05:23 +03:00
Johan x Lindqvist 61c3e02242 Updated exception message to be in line with other exception messages. 2019-09-19 13:31:57 +02:00
Johan x Lindqvist 5618c4c1f7 Always access the exception property on the task if it has status IsFaulted.
By checking the Exception property it will consider the task exception as handled which means the finalizer won't throw an unhandled task exception.
2019-09-18 13:49:59 +02:00
Johan x Lindqvist ba9ceed7ce Use Task.WhenAll to handle errors in both tasks.
Previously if there was an exception in the first task that is awaited the second task would not be awaited.
2019-09-16 11:33:37 +02:00
Johan x Lindqvist ad1c198e43 Remove if clause that stopped handling of tasks with exceptions.
Now the task is always awaited and thus the exception in the task is handled.
2019-09-12 09:05:08 +02:00
SeppPenner 2918be18c6 Added automatic labels to the issue templates. 2019-09-05 10:37:55 +02:00
Christian 248e2a5bdd Merge pull request #746 from bcrosnier/pr/mqtt5-assigned-client-id
Better handling of AssignedClientIdentifier - chkr1011/MQTTnet#745
2019-08-25 22:12:57 +02:00
Benjamin Crosnier 1a41415dd1 Allow AssignedClientIdentifier in ClientConnected, ClientDisconnected and ConnectedHandler - Fixes chkr1011/MQTTnet#745 2019-08-19 10:41:28 +02:00
Christian Kratky 9302e80d73 Merge branch 'develop' 2019-08-18 21:00:40 +02:00
Christian Kratky cf6f0ece0e Add test execution in build script. 2019-08-18 20:56:26 +02:00
Christian Kratky 50d65f2fed Update nugets. 2019-08-14 23:06:45 +02:00
Christian Kratky 4614df7fa5 Update docs. 2019-08-14 22:57:17 +02:00
Christian 22aedcba09 Merge pull request #744 from JanEggers/pr/fix#743
fixed #743
2019-08-14 22:53:55 +02:00
Christian Kratky 2767d897a4 Fix serialization issue of MQTTv5 PubRec packet. 2019-08-14 22:45:15 +02:00
JanEggers a4420063c0 fixed #743 2019-08-14 22:29:51 +02:00
Christian Kratky 2320352124 Update docs. 2019-08-13 20:09:21 +02:00
Christian Kratky c0b4155ab4 Update docs. 2019-08-13 20:07:14 +02:00
Christian Kratky b09f31d654 Fix TCP server adpater when using empty password. 2019-08-13 20:07:10 +02:00
Christian Kratky 30c33d46f9 Merge remote-tracking branch 'origin/develop' into develop 2019-08-13 19:56:36 +02:00
Christian 651b79a124 Merge pull request #740 from cslutgen/chain
Fix Client SslStream CRL verification
2019-08-13 19:56:26 +02:00
Christian Kratky 2e3cf54f11 Add support for different strategies when generating RPC topics. 2019-08-13 19:53:55 +02:00
Craig Lutgen d7948afd98 Fix client SslStream certificate chain CRL validation. The logic was inverse and CRLs were never checked.
Add a missing dispose in managed client.
2019-08-12 17:34:05 -05:00
cslutgen 4cefa1dfa9 Merge pull request #2 from chkr1011/develop
Develop
2019-08-12 17:28:31 -05:00
Christian Kratky 0cfb8b4020 Remove not async task handling. 2019-08-11 22:25:05 +02:00
Christian Kratky 9ac726b271 Revert "Remove dedicated UWP builds and code."
This reverts commit 6d0e2c2022.
2019-08-11 22:19:49 +02:00
Christian Kratky 232605304e Revert "Update nugets."
This reverts commit 6c53677e7d.
2019-08-11 22:19:29 +02:00
Christian Kratky 6c53677e7d Update nugets. 2019-08-11 22:10:49 +02:00
Christian Kratky 6d0e2c2022 Remove dedicated UWP builds and code. 2019-08-11 22:07:57 +02:00
Christian Kratky 8ad1fb2871 Refactor server certificate classes (breaking change). 2019-08-11 21:46:13 +02:00
Christian Kratky 4a7ff9e9ed Add TLS certificate password support for MQTTnet.Server. 2019-08-11 21:45:41 +02:00
Christian Kratky f54598c201 Merge branch 'develop' 2019-08-11 16:33:40 +02:00
Christian Kratky 2300e68fff Add UnitTests for RPC. 2019-08-11 10:41:36 +02:00
Christian Kratky 6996824157 Merge branch 'master' into develop 2019-08-11 10:17:51 +02:00
Christian Kratky 524f695829 Update docs. 2019-08-09 22:21:42 +02:00
Christian 72faa067cc Merge pull request #729 from cslutgen/clientcerts
Add Server certificate password and client certificate builders
2019-08-09 22:07:26 +02:00
SeppPenner 01aa75471c Updated description of issue templates. 2019-08-09 11:20:28 +02:00
HansM 048206eb1e Fixed my spelling mistake from before. 2019-08-09 11:14:52 +02:00
HansM ad5b0caa4d Fixed spelling issue in feature request issue template. 2019-08-09 11:13:40 +02:00
HansM 0f14ddcf79 Updated bug report issue template. 2019-08-09 11:13:06 +02:00
Craig Lutgen 59d2a8e551 Changed server crentials property name from password to certificateCredentials 2019-08-08 13:35:14 -05:00
HansM 8607ceb3b7 Fixed feature request issue template. 2019-08-02 08:47:09 +02:00
HansM b82e5a48a4 Fixed custom issue template. 2019-08-02 08:46:35 +02:00
HansM 30c5147c62 Fixed bug reports issue template. 2019-08-02 08:46:12 +02:00
Craig Lutgen 9d63500f95 Fix build issue with UWP 2019-07-31 13:27:33 -05:00
Craig Lutgen a03bdc7616 Expose server certificate password and client certificate options to MqttServerOptionsBuilder 2019-07-31 13:04:03 -05:00
Christian Kratky 413daee551 Merge branch 'master' into develop 2019-07-30 20:35:48 +02:00
Christian Kratky f3ea7008e5 Merge remote-tracking branch 'origin/develop' into develop 2019-07-30 20:35:39 +02:00
Christian Kratky 8bfbbd2b29 Refactoring. 2019-07-30 20:35:33 +02:00
Christian Kratky ab8c7df0b9 Add unit Tests. 2019-07-30 20:35:22 +02:00
Christian Kratky 975eb60e90 Fix memory leak when SSL is not working properly. 2019-07-30 20:02:46 +02:00
Christian Kratky 6076151222 Update docs. 2019-07-30 20:01:57 +02:00
Christian Kratky 9cc96f1888 Refactor log messages. 2019-07-30 20:01:45 +02:00
HansM 7aa4d5159c Fixed styling in feature request template. 2019-07-30 09:56:00 +02:00
Christian 9b021c4093 Update README.md 2019-07-27 09:57:36 +02:00
Christian 54c303369e Update README.md 2019-07-27 09:56:59 +02:00
Christian 8f30042e49 Update README.md 2019-07-27 09:56:46 +02:00
Christian 4c33270d26 Merge pull request #718 from PaulFake/patch-3
Fixed AsyncLock::WaitAsync cancellation bug
2019-07-26 21:23:29 +02:00
Paul Fake 5c40577bec Fixed AsyncLock::WaitAsync cancellation bug
There isn't any code in MQTTnet that actually uses a cancellation token in WaitAsync, so this is more of a preventative thing than a bug fix.  The original code just checks if the task was completed, not whether it was cancelled.  If the process is cancelled immediately before the call to WaitAsync, it'll return as normal (https://referencesource.microsoft.com/#mscorlib/system/threading/SemaphoreSlim.cs,612) rather than throw a cancellation exception.  This change will ensure we only return the releaser if the wait actually ran to completion rather than exited early due to cancellation.  I've tested this, and it properly throws a cancellation exception later on.
2019-07-23 16:20:36 -04:00
Christian Kratky 3d404f9755 Fixed build. 2019-07-23 22:08:51 +02:00
Christian Kratky 1b5e0197e4 Update docs. 2019-07-23 21:56:14 +02:00
Christian 1dab729d84 Merge pull request #717 from PaulFake/patch-2
Storage queue drain test
2019-07-23 21:54:48 +02:00
Christian 3eac5bcaf3 Merge pull request #709 from PaulFake/patch-1
Fixed storage queue race condition
2019-07-23 21:54:21 +02:00
Paul Fake 8eb23f0f1d Storage queue drain test
It's a unit test to ensure the storage queue is drained.
2019-07-23 15:45:50 -04:00
Christian 1fd1a12fce Merge pull request #715 from mseyock/change-icon
Remove shadow and made text bold
2019-07-23 19:59:32 +02:00
Matthias Seyock 349d506b37 Remove shadow and made text bold 2019-07-23 16:03:18 +02:00
Christian a981b05aa7 Merge pull request #712 from mseyock/change-icon
fix typo in icon
2019-07-19 22:12:59 +02:00
Matthias Seyock 654f06d20d fix typo in icon 2019-07-19 20:34:39 +02:00
Christian c92cd10499 Merge pull request #711 from mseyock/change-icon
Replace icon
2019-07-19 19:33:32 +02:00
Christian Kratky ed06ea6bc9 Add version information to MQTTnet.Server. 2019-07-19 19:32:33 +02:00
Matthias Seyock 3d531151c6 Replace icon 2019-07-19 16:52:58 +02:00
Paul Fake e1590fc0c8 Fixed storage queue race condition
Sometimes, TryPublishQueuedMessageAsync would try to remove a message from the storage queue before PublishAsync added it to the storage queue, resulting in a message being stuck in the storage queue forever.  Switched the message queue lock to an async lock and synchronized the storage queue updates with the message queue updates.
2019-07-17 16:55:56 -04:00
Christian Kratky dbb227406b Added UnitTests. 2019-07-17 21:58:37 +02:00
Christian b891e1d1f4 Update issue templates 2019-07-17 19:45:08 +02:00
Christian 1d697e3b87 Merge pull request #702 from rudacs/clientCertificate-is-null
X509Certificate convert to X509Certificate2 in ClientCertificate
2019-07-15 19:18:03 +02:00
Rudá Cunha 128484c55a X509Certificate convert to X509Certificate2 in ClientCertificate 2019-07-15 10:46:45 -03:00
Christian Kratky ff22c34bb2 Add first classes for persisted session support. 2019-07-12 20:36:46 +02:00
Christian Kratky e7ba3f76dc Add options builder methods for remote certificate validation callback. 2019-07-11 23:03:56 +02:00
Christian 1ae3324581 Merge pull request #697 from rudacs/add-server-remove-validation-callback
Add remote certificate validation callback on server
2019-07-11 22:56:36 +02:00
Rudá Cunha ba8ce15ab4 Add remote certificate validation callback on server 2019-07-11 16:28:09 -03:00
Christian Kratky 87b4ce5185 Extend build and upload script to publish symbols as well. 2019-07-11 21:28:07 +02:00
Christian Kratky 4eb2b77138 Fix wrong NoDelay usage in server implementation. 2019-07-11 21:11:11 +02:00
Christian Kratky 70ee49f3c6 Merge remote-tracking branch 'origin/develop' into develop 2019-07-09 22:42:50 +02:00
Christian Kratky f223a26748 Update docs. 2019-07-09 22:42:44 +02:00
Christian 4574fdc951 Merge pull request #693 from JanEggers/pr/fix691
fixed #691
2019-07-09 22:39:48 +02:00
Jan Eggers 4f66614cdd fixed #691 2019-07-09 14:15:46 +02:00
Christian Kratky 6608172719 MQTTnet.Server: Extend messages API. 2019-07-07 21:26:07 +02:00
Christian Kratky 6c8db47e25 Remove dedicated values from contexts and only provide session items. 2019-07-05 18:28:18 +02:00
Christian Kratky 3eb5e82d10 Expose connect packet in application message interceptor and subscription interceptor. 2019-07-04 23:06:37 +02:00
Christian Kratky 8563230f9c Update docs. 2019-07-04 20:38:01 +02:00
Christian Kratky 019f428f0a MQTTnet.Server: Add HTTP API for publishing of messages. 2019-07-04 20:27:48 +02:00
Christian Kratky 1847af13d2 Merge branch 'develop' 2019-06-28 10:20:51 +02:00
Christian Kratky 8916df8d7b Move ReuseAddress to server options. 2019-06-27 15:20:27 +02:00
Christian Kratky f66da92299 Merge branch 'develop' 2019-06-27 10:02:59 +02:00
Christian Kratky 979df5f17e Fix broken nuget builds. 2019-06-27 10:02:47 +02:00
Christian Kratky d50c8153b2 Merge branch 'master' into develop 2019-06-26 11:42:44 +02:00
Christian Kratky b3ab7a1069 Set socket options to allow reusing address. 2019-06-24 13:46:51 +02:00
Christian Kratky 6af58ad90d Fix MQTTnet.Server startup colors. 2019-06-24 13:46:27 +02:00
Christian 5c36a2d402 Merge pull request #671 from SeppPenner/patch-1
Added dependents and MIT license badge to the readme.
2019-06-24 13:40:26 +02:00
HansM 6df70cc5ed Added dependents and MIT license badge to the readme. 2019-06-24 11:21:24 +02:00
Christian Kratky d5b0893e90 Merge branch 'master' into develop 2019-06-23 21:50:42 +02:00
Christian Kratky 2ed8e55394 Fix upload script. 2019-06-23 21:46:06 +02:00
Christian Kratky c5b6ca204d Merge branch 'develop' 2019-06-23 21:37:35 +02:00
Christian Kratky 7a767c7d2f Improve logging and exception handling when stopping the server. 2019-06-23 15:58:21 +02:00
Christian Kratky dd96cf98a8 Make storage update for managed client async. 2019-06-23 15:57:48 +02:00
Christian Kratky 6ee3d1640f Improve logging. 2019-06-23 15:57:12 +02:00
Christian Kratky 6f8272210c Fix MQTTnet.Server app settings to allow external connections. 2019-06-23 15:39:50 +02:00
Christian Kratky ce05cc9936 Fix MQTTnet.Server connection validation. 2019-06-23 15:39:07 +02:00
Christian Kratky 985c3084a8 Performance refactoring. 2019-06-23 12:37:55 +02:00
Christian Kratky 7b3be3a64f Update docs. 2019-06-23 12:37:41 +02:00
Christian Kratky c50fb740fc Add UnitTests. 2019-06-23 12:37:33 +02:00
Christian Kratky 5895a73f85 Merge remote-tracking branch 'origin/develop' into develop 2019-06-23 11:32:11 +02:00
Christian Kratky 961a497798 Performance refactoring. 2019-06-23 11:32:09 +02:00
Christian 6a90864c44 Merge pull request #666 from vbBerni/develop
fix Managed Client removes failed messages from message queue but not from storage manager
2019-06-23 11:30:31 +02:00
vbBerni a9017b8795 handle storage manager null 2019-06-22 22:31:48 +02:00
vbBerni f76e130283 fix for failed publishing messages get removed from the message queue but not from the storage manager 2019-06-19 16:33:54 +02:00
Christian Kratky 5a48b146b4 Merge branch 'master' into develop 2019-06-14 20:53:24 +02:00
Christian Kratky 1d1def3275 Remove nuget binary from repo. 2019-06-14 20:52:56 +02:00
Christian Kratky bd75a2440e Merge branch 'master' into develop 2019-06-14 20:43:33 +02:00
Christian Kratky 7a642802ed Merge branch 'develop' 2019-06-14 20:43:18 +02:00
Christian Kratky a8f8601bc5 Update docs. 2019-06-14 20:38:44 +02:00
Christian Kratky 0c7a5a992b Expose more properties of the connection validator context in MQTTnet.Server. Migrate return code to reason code. 2019-06-14 20:38:07 +02:00
Christian Kratky bd665c3d56 Expose more properties to connection validator context. 2019-06-14 20:37:06 +02:00
Christian Kratky 7e7b36aadf Update docs. 2019-06-14 20:35:45 +02:00
Christian Kratky a79c2484b3 Add MQTTnet.Server build for ARM. 2019-06-14 20:35:33 +02:00
Christian Kratky e4e46f0094 Add comments. 2019-06-11 20:51:23 +02:00
Christian Kratky 5a4c735b85 Refactor code. 2019-06-11 20:50:11 +02:00
Christian Kratky 42516942ac Update docs. 2019-06-09 14:14:40 +02:00
Christian Kratky 591ccfec29 Update authentication. 2019-06-09 14:13:50 +02:00
Christian Kratky ffc1d950da Add authorization for MQTTnet.Server 2019-06-09 00:10:26 +02:00
Christian Kratky 1c004ead6d Add support for altering the TopicFilter in subscription interceptor. 2019-06-07 20:40:24 +02:00
Christian Kratky b0ad6bda70 Add support for reset of connection statistics. Refactor keep alive monitor. 2019-06-06 21:12:32 +02:00
Christian Kratky 6262a16504 Add version to MQTTnet.Server. 2019-06-06 21:11:47 +02:00
Christian Kratky 0de683979d Fix versions in build script. 2019-06-06 21:11:20 +02:00
Christian Kratky 0a6f564446 Add self contained builds in build script. 2019-06-06 20:26:41 +02:00
Christian Kratky f0be3ef0cf Add UnitTests. 2019-06-06 20:26:21 +02:00
Christian Kratky f79eebdf64 Update docs. 2019-06-06 19:32:06 +02:00
Christian Kratky c3c0dcf313 Execute disconnected handler in new task. 2019-06-06 19:32:00 +02:00
Christian Kratky 60c6074953 Expose client certificate at MQTT connection validator. Make DualMode optional. 2019-06-06 19:31:43 +02:00
Christian Kratky 2b9b22def6 Expose new options in server TLS options. 2019-06-06 19:27:25 +02:00
Christian Kratky 5cfb092449 Add UnitTests. 2019-06-06 19:26:43 +02:00
Christian Kratky a450fc4e01 Add UnitTests. 2019-05-31 09:55:23 +02:00
Christian Kratky ffe9c57ae8 Add overload for setting message payload. 2019-05-27 22:45:56 +02:00
Christian Kratky 0257e31910 Add UnitTests. 2019-05-27 20:06:51 +02:00
Christian Kratky 7fe5f521dc Update docs. 2019-05-27 20:02:30 +02:00
Christian Kratky 2d03c267e4 Expose binary password to MqttConnectionValidatorContext. 2019-05-27 19:57:36 +02:00
Christian Kratky ccfe67e6a6 Fix wrong password handling (string -> byte[]) 2019-05-27 00:21:55 +02:00
Christian Kratky 98e17903ea Merge remote-tracking branch 'origin/develop' into develop 2019-05-26 23:53:19 +02:00
Christian c7d56a78f3 Merge pull request #628 from hezlog/develop
Fixed MQTTnet.noUWP.sln build issue.
2019-05-26 23:53:07 +02:00
Christian Kratky b491c74228 Merge remote-tracking branch 'origin/develop' into develop 2019-05-26 23:45:02 +02:00
Christian Kratky a2414f48ca Update Wiki samples. 2019-05-26 23:44:50 +02:00
Christian Kratky 396e0e1697 Add connected timestamp to connection status API. 2019-05-26 23:44:50 +02:00
Christian Kratky 01f6c959e1 Update publish profile. 2019-05-26 23:44:50 +02:00
Christian Kratky f425d87562 Add publish profiles. 2019-05-26 23:44:50 +02:00
Christian Kratky 6614b23ab8 Add extension library for WebSocket4Net usage. 2019-05-26 23:44:50 +02:00
Christian Kratky 02c9133a1c Update splash screen for MQTTnet.Server. 2019-05-26 23:44:50 +02:00
Christian Kratky 913afa3977 Add connack properties to authenticate result. 2019-05-26 23:44:50 +02:00
Christian Kratky e068286f15 Add subscribe options builder. 2019-05-26 23:44:50 +02:00
Christian Kratky 373fe8c72c Add connack properties to connect result. 2019-05-26 23:44:50 +02:00
Christian Kratky 396f040aae Add support for extended authentication exchange. 2019-05-26 23:44:50 +02:00
Christian Kratky c90b5f6fb2 Update UnitTests. 2019-05-26 23:44:50 +02:00
Christian Kratky 744b1b302b Create MQTTnet.Server package from publish output instead build files. 2019-05-26 23:44:50 +02:00
Christian Kratky 78e504dc2c Update Wiki samples. 2019-05-26 23:44:42 +02:00
Christian 79518d4a35 Merge pull request #634 from gitter-badger/gitter-badge
Add a Gitter chat badge to README.md
2019-05-23 19:04:55 +02:00
The Gitter Badger a50fb2a320 Add Gitter badge 2019-05-22 08:19:32 +00:00
hezlog 9fa9d22097 Fixed MQTTnet.noUWP.sln build issue. 2019-05-20 23:17:32 +08:00
Christian Kratky e4351b73bd Add connected timestamp to connection status API. 2019-05-19 22:23:10 +02:00
Christian Kratky 2d3fdd4faf Update publish profile. 2019-05-18 20:51:19 +02:00
Christian Kratky 0a509fd685 Add publish profiles. 2019-05-18 20:50:29 +02:00
Christian Kratky d1a17314ef Add extension library for WebSocket4Net usage. 2019-05-18 09:48:44 +02:00
Christian Kratky e96b66e9f8 Update splash screen for MQTTnet.Server. 2019-05-17 20:57:56 +02:00
Christian Kratky 80b05a8944 Add connack properties to authenticate result. 2019-05-17 20:57:40 +02:00
Christian Kratky ab3df2ba65 Add subscribe options builder. 2019-05-17 20:57:15 +02:00
Christian Kratky f169aaa79b Add connack properties to connect result. 2019-05-17 20:56:58 +02:00
Christian Kratky 231001850a Add support for extended authentication exchange. 2019-05-14 20:45:45 +02:00
Christian Kratky 6839970d41 Update UnitTests. 2019-05-14 20:40:58 +02:00
Christian Kratky 4df29be155 Create MQTTnet.Server package from publish output instead build files. 2019-05-14 20:40:44 +02:00
Christian Kratky c5cfede231 Merge branch 'master' into develop 2019-05-13 07:25:56 +02:00
Christian Kratky c22b6033e3 Accept multiple SubscriptionIdentifiers for PUBLISH packets. 2019-05-12 17:26:36 +02:00
Christian Kratky 27476a9194 Merge remote-tracking branch 'origin/master' 2019-05-12 00:18:54 +02:00
Christian Kratky 12973a4179 Fix issues in MQTTv5 packet encoding and decoding. 2019-05-12 00:18:48 +02:00
Christian 01b437dc08 Set theme jekyll-theme-hacker 2019-05-11 09:50:41 +02:00
Christian Kratky ac88f0a05a Merge branch 'develop' 2019-05-11 09:47:31 +02:00
Christian Kratky b02f30844c Add new options for _MqttClientOptionsBuilder_. 2019-05-10 21:55:46 +02:00
Christian Kratky 1a8bcae47c Add authentication result to disconnected handler. 2019-05-09 22:08:56 +02:00
Christian Kratky 664549ab93 Fix message encoding bugs. 2019-05-08 00:12:27 +02:00
Christian 914d2b641f Update appveyor.yml 2019-05-06 21:14:51 +02:00
Christian 0cc0fcf5d9 Update appveyor.yml 2019-05-06 21:07:46 +02:00
Christian Kratky 5980cbd944 Fix build scripts to use 4.6 binaries. 2019-05-06 20:27:33 +02:00
Christian Kratky 3ef7f60a18 Fix wrong IsSessionPresent flag. 2019-05-06 20:27:24 +02:00
801 changed files with 42004 additions and 26331 deletions
-3
View File
@@ -1,3 +0,0 @@
component_depth: 2
languages:
- csharp
+83
View File
@@ -0,0 +1,83 @@
[*.cs]
# CA1031: Do not catch general exception types
# Microsoft .NET properties
csharp_new_line_before_members_in_object_initializers = false
csharp_preferred_modifier_order = public, private, protected, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion
csharp_style_var_elsewhere = true:suggestion
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
dotnet_naming_rule.constants_rule.severity = warning
dotnet_naming_rule.constants_rule.style = upper_camel_case_style
dotnet_naming_rule.constants_rule.symbols = constants_symbols
dotnet_naming_rule.public_fields_rule.severity = warning
dotnet_naming_rule.public_fields_rule.style = lower_camel_case_style
dotnet_naming_rule.public_fields_rule.symbols = public_fields_symbols
dotnet_naming_rule.static_readonly_rule.severity = warning
dotnet_naming_rule.static_readonly_rule.style = upper_camel_case_style
dotnet_naming_rule.static_readonly_rule.symbols = static_readonly_symbols
dotnet_naming_style.lower_camel_case_style.capitalization = camel_case
dotnet_naming_style.lower_camel_case_style.required_prefix = _
dotnet_naming_style.upper_camel_case_style.capitalization = pascal_case
dotnet_naming_symbols.constants_symbols.applicable_accessibilities = public, internal, protected, protected_internal, private_protected
dotnet_naming_symbols.constants_symbols.applicable_kinds = field
dotnet_naming_symbols.constants_symbols.required_modifiers = const
dotnet_naming_symbols.public_fields_symbols.applicable_accessibilities = public, internal, protected, protected_internal, private_protected
dotnet_naming_symbols.public_fields_symbols.applicable_kinds = field
dotnet_naming_symbols.static_readonly_symbols.applicable_accessibilities = public, internal, protected, protected_internal, private_protected
dotnet_naming_symbols.static_readonly_symbols.applicable_kinds = field
dotnet_naming_symbols.static_readonly_symbols.required_modifiers = static, readonly
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
dotnet_style_qualification_for_event = false:suggestion
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
# ReSharper properties
resharper_default_private_modifier = implicit
resharper_place_accessorholder_attribute_on_same_line = false
resharper_use_indent_from_vs = false
# ReSharper inspection severities
resharper_arrange_redundant_parentheses_highlighting = hint
resharper_arrange_this_qualifier_highlighting = hint
resharper_built_in_type_reference_style_for_member_access_highlighting = hint
resharper_built_in_type_reference_style_highlighting = hint
resharper_redundant_base_qualifier_highlighting = warning
resharper_suggest_var_or_type_built_in_types_highlighting = hint
resharper_suggest_var_or_type_elsewhere_highlighting = hint
resharper_suggest_var_or_type_simple_types_highlighting = hint
resharper_web_config_module_not_resolved_highlighting = warning
resharper_web_config_type_not_resolved_highlighting = warning
resharper_web_config_wrong_module_highlighting = warning
[*]
charset = utf-8
end_of_line = crlf
trim_trailing_whitespace = true
insert_final_newline = false
indent_style = space
indent_size = 4
[{*.har,*.inputactions,*.jsb2,*.jsb3,*.json,.babelrc,.eslintrc,.stylelintrc,bowerrc,jest.config}]
indent_style = space
indent_size = 2
[{*.yaml,*.yml}]
indent_style = space
indent_size = 2
[{tsconfig.app.json,tsconfig.e2e.json,tsconfig.json,tsconfig.lib.json,tsconfig.spec.json}]
indent_style = space
indent_size = 2
[*.{appxmanifest,asax,ascx,aspx,axaml,build,cg,cginc,compute,cs,cshtml,dtd,hlsl,hlsli,hlslinc,master,nuspec,paml,razor,resw,resx,shader,skin,usf,ush,vb,xaml,xamlx,xoml,xsd}]
indent_style = space
indent_size = 4
tab_width = 4
+1 -63
View File
@@ -1,63 +1 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
* text=auto
+57
View File
@@ -0,0 +1,57 @@
---
name: Bug report
about: Create a report to help us improve.
title: ''
labels: 'bug'
assignees: ''
---
### Verification
Before opening a bug make sure that the following conditions are met.
<!-- Remove this chapter when all conditions are met. -->
1. Performance issues are also appearing in RELEASE mode of your application.
2. An increased memory consumption or high CPU load also happens when your application runs in RELEASE mode AND logging is DISABLED.
3. Client issues with not received messages, connection drops etc. can be reproduced via another client application like "MQTTnetApp" (https://github.com/chkr1011/MQTTnetApp) or similar.
4. The bug also appears in the VERY LATEST version of this library. There is no support for older version (due to limited resources) but pull requests for older versions are welcome.
### Describe the bug
A clear and concise description of what the bug is.
### Which component is your bug related to?
<!-- Remove the items which don't apply from the following list. -->
- Client
- ManagedClient
- RpcClient
- Server
### To Reproduce
Steps to reproduce the behavior:
1. Using this version of MQTTnet '...'.
2. Run this code '....'.
3. With these arguments '....'.
4. See error.
### Expected behavior
A clear and concise description of what you expected to happen.
### Screenshots
If applicable, add screenshots to help explain your problem.
### Additional context / logging
Add any other context about the problem here.
Include debugging or logging information here:
```batch
\\ Put your logging output here.
```
### Code example
Please provide full code examples below where possible to make it easier for the developers to check your issues.
**Ideally a Unit Test (which shows the error) is provided so that the behavior can be reproduced easily.**
```csharp
\\ Put your code here.
```
+18
View File
@@ -0,0 +1,18 @@
---
name: Custom issue template
about: Do you have a question related to the project? Use this template.
title: ''
labels: 'question'
assignees: ''
---
### Describe your question
A clear and concise description of what you want to know.
### Which project is your question related to?
<!-- Remove the items which don't apply from the following list -->
- Client
- ManagedClient
- Server
- Generic
+28
View File
@@ -0,0 +1,28 @@
---
name: Feature request
about: Suggest an idea for this project.
title: ''
labels: 'feature-request'
assignees: ''
---
### Describe the feature request
Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Example. I'm am trying to do [...] but [...]
### Which project is your feature request related to?
<!-- Remove the items which don't apply from the following list -->
- Client
- ManagedClient
- Server
- Generic
### Describe the solution you'd like
A clear and concise description of what you want to happen.
### Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
### Additional context
Add any other context or screenshots about the feature request here.
+130
View File
@@ -0,0 +1,130 @@
name: CI
on: [push, pull_request]
env:
VERSION: "5.1.0.${{github.run_number}}"
PACKAGE_SUFFIX: ""
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x
- name: Checkout code
uses: actions/checkout@v4
- name: Load strong name certificate
run: |
echo "$SNC_BASE64" | base64 --decode > "${{ github.workspace }}/certificate.snk"
shell: bash
env:
SNC_BASE64: ${{ secrets.SNC_BASE64 }}
- name: Build package
run: dotnet build MQTTnet.sln --configuration Release /p:FileVersion=${{ env.VERSION }} /p:AssemblyVersion=${{ env.VERSION }} /p:PackageVersion=${{ env.VERSION }}${{ env.PACKAGE_SUFFIX }} /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=${{ github.workspace }}/certificate.snk
- name: Upload nuget packages
uses: actions/upload-artifact@v4
with:
name: nugets
path: |
${{ github.workspace }}/Source/**/*.nupkg
${{ github.workspace }}/Source/**/*.snupkg
test:
runs-on: ubuntu-latest
steps:
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
8.0.x
- name: Checkout code
uses: actions/checkout@v4
- name: Execute tests
run: dotnet test --framework net8.0 --configuration Release Source/MQTTnet.Tests/MQTTnet.Tests.csproj
sign:
needs: build
runs-on: windows-latest # Code signing must run on a Windows agent for Authenticode signing (dll/exe)
if: github.repository == 'dotnet/MQTTnet'
steps:
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.0.x
- name: Download nuget packages
uses: actions/download-artifact@v4
with:
name: nugets
path: nugets
- name: Install sign CLI tool
run: dotnet tool install --tool-path . sign --version 0.9.0-beta.23127.3
- name: Sign nugets
shell: pwsh
run: >
./sign code azure-key-vault `
"**/*.nupkg" `
--base-directory "${{ github.workspace }}\nugets" `
--publisher-name "MQTTnet" `
--description "MQTTnet" `
--description-url "https://github.com/dotnet/MQTTnet" `
--azure-key-vault-tenant-id "${{ secrets.AZURE_TENANT_ID }}" `
--azure-key-vault-client-id "${{ secrets.AZURE_CLIENT_ID }}" `
--azure-key-vault-client-secret "${{ secrets.AZURE_CLIENT_SECRET }}" `
--azure-key-vault-certificate "${{ secrets.KEY_VAULT_CERTIFICATE_ID }}" `
--azure-key-vault-url "${{ secrets.KEY_VAULT_URL }}"
- name: Upload signed nuget packages
uses: actions/upload-artifact@v4
with:
name: signed-nugets
path: |
${{ github.workspace }}\nugets\**\*.nupkg
${{ github.workspace }}\nugets\**\*.snupkg
publish-myget:
if: ${{ github.event_name == 'push' }}
needs: sign
runs-on: ubuntu-latest
steps:
- name: Download signed nuget packages
uses: actions/download-artifact@v4
with:
name: signed-nugets
path: nugets
- name: Publish myget.com nugets
run: dotnet nuget push ${{ github.workspace }}/nugets/**/*.nupkg -k ${{ secrets.MYGET_API_KEY }} -s https://www.myget.org/F/mqttnet/api/v3/index.json --skip-duplicate
publish-nuget:
# Tag schema is 'v5.0.0-rc' etc.
if: startsWith(github.ref, 'refs/tags/v')
needs: [sign, test]
runs-on: ubuntu-latest
steps:
- name: Download signed nuget packages
uses: actions/download-artifact@v4
with:
name: signed-nugets
path: nugets
- name: Publish nuget.org nugets
run: dotnet nuget push ${{ github.workspace }}/nugets/**/*.nupkg -k ${{ secrets.NUGET_API_KEY }} -s https://api.nuget.org/v3/index.json --skip-duplicate
+4
View File
@@ -292,3 +292,7 @@ __pycache__/
*.map
/Tests/MQTTnet.TestApp.NetCore/RetainedMessages.json
Build/NuGet/
Build/nuget.exe
-33
View File
@@ -1,33 +0,0 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>MQTTnet.AspNetCore</id>
<version>0.0.0</version>
<authors>Christian Kratky</authors>
<owners>Christian Kratky</owners>
<license type="file">LICENSE</license>
<projectUrl>https://github.com/chkr1011/MQTTnet</projectUrl>
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>This is a support library to integrate MQTTnet into AspNetCore.</description>
<releaseNotes>For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/).</releaseNotes>
<copyright>Copyright Christian Kratky 2016-2019</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>
<dependencies>
<dependency id="MQTTnet" version="$nugetVersion" />
<dependency id="Microsoft.AspNetCore.Connections.Abstractions" version="2.1.3" />
<dependency id="Microsoft.AspNetCore.Http.Connections" version="1.0.3" />
<dependency id="Microsoft.AspNetCore.WebSockets" version="2.1.1" />
<dependency id="Microsoft.Extensions.Hosting.Abstractions" version="2.1.1" />
</dependencies>
</metadata>
<files>
<!-- License -->
<file src="..\LICENSE" />
<!-- .NET Standard 2.0 -->
<file src="..\Source\MQTTnet.AspNetCore\bin\Release\netstandard2.0\MQTTnet.AspNetCore.*" target="lib\netstandard2.0\"/>
</files>
</package>
@@ -1,43 +0,0 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>MQTTnet.Extensions.ManagedClient</id>
<version>0.0.0</version>
<authors>Christian Kratky</authors>
<owners>Christian Kratky</owners>
<license type="file">LICENSE</license>
<projectUrl>https://github.com/chkr1011/MQTTnet</projectUrl>
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>This is an extension library which provides a managed MQTT client with additional features using MQTTnet.</description>
<releaseNotes>For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/).</releaseNotes>
<copyright>Copyright Christian Kratky 2016-2019</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>
<dependencies>
<dependency id="MQTTnet" version="$nugetVersion" />
</dependencies>
</metadata>
<files>
<!-- License -->
<file src="..\LICENSE" />
<!-- .NET Standard 1.3 -->
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\netstandard1.3\MQTTnet.Extensions.ManagedClient.*" target="lib\netstandard1.3\"/>
<!-- .NET Standard 2.0 -->
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\netstandard2.0\MQTTnet.Extensions.ManagedClient.*" target="lib\netstandard2.0\"/>
<!-- Universal Windows -->
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\uap10.0\MQTTnet.Extensions.ManagedClient.*" target="lib\uap10.0\"/>
<!-- .NET Framework -->
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\net452\MQTTnet.Extensions.ManagedClient.*" target="lib\net452\"/>
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\netstandard2.0\MQTTnet.Extensions.ManagedClient.*" target="lib\net461\"/>
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\netstandard2.0\MQTTnet.Extensions.ManagedClient.*" target="lib\net462\"/>
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\netstandard2.0\MQTTnet.Extensions.ManagedClient.*" target="lib\net470\"/>
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\netstandard2.0\MQTTnet.Extensions.ManagedClient.*" target="lib\net471\"/>
<file src="..\Source\MQTTnet.Extensions.ManagedClient\bin\Release\netstandard2.0\MQTTnet.Extensions.ManagedClient.*" target="lib\net472\"/>
</files>
</package>
-43
View File
@@ -1,43 +0,0 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>MQTTnet.Extensions.Rpc</id>
<version>0.0.0</version>
<authors>Christian Kratky</authors>
<owners>Christian Kratky</owners>
<license type="file">LICENSE</license>
<projectUrl>https://github.com/chkr1011/MQTTnet</projectUrl>
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>This is an extension library which allows executing synchronous device calls including a response using MQTTnet.</description>
<releaseNotes>For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/).</releaseNotes>
<copyright>Copyright Christian Kratky 2016-2019</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>
<dependencies>
<dependency id="MQTTnet" version="$nugetVersion" />
</dependencies>
</metadata>
<files>
<!-- License -->
<file src="..\LICENSE" />
<!-- .NET Standard 1.3 -->
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\netstandard1.3\MQTTnet.Extensions.Rpc.*" target="lib\netstandard1.3\"/>
<!-- .NET Standard 2.0 -->
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\netstandard2.0\MQTTnet.Extensions.Rpc.*" target="lib\netstandard2.0\"/>
<!-- Universal Windows -->
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\uap10.0\MQTTnet.Extensions.Rpc.*" target="lib\uap10.0\"/>
<!-- .NET Framework -->
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\net452\MQTTnet.Extensions.Rpc.*" target="lib\net452\"/>
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\netstandard2.0\MQTTnet.Extensions.Rpc.*" target="lib\net461\"/>
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\netstandard2.0\MQTTnet.Extensions.Rpc.*" target="lib\net462\"/>
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\netstandard2.0\MQTTnet.Extensions.Rpc.*" target="lib\net470\"/>
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\netstandard2.0\MQTTnet.Extensions.Rpc.*" target="lib\net471\"/>
<file src="..\Source\MQTTnet.Extensions.Rpc\bin\Release\netstandard2.0\MQTTnet.Extensions.Rpc.*" target="lib\net472\"/>
</files>
</package>
-42
View File
@@ -1,42 +0,0 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>MQTTnet.NETStandard</id>
<version>0.0.0</version>
<authors>Christian Kratky</authors>
<owners>Christian Kratky</owners>
<license type="file">LICENSE</license>
<projectUrl>https://github.com/chkr1011/MQTTnet</projectUrl>
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker). This package contains the .NET Standard version of the library only.</description>
<releaseNotes>For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/).</releaseNotes>
<copyright>Copyright Christian Kratky 2016-2019</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>
<dependencies>
<group targetFramework="netstandard1.3">
<dependency id="NETStandard.Library" version="1.3.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="netstandard2.0">
<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>
</dependencies>
</metadata>
<files>
<!-- License -->
<file src="..\LICENSE" />
<!-- .NET Standard 1.3 -->
<file src="..\Source\MQTTnet\bin\Release\netstandard1.3\MQTTnet.*" target="lib\netstandard1.3\"/>
<!-- .NET Standard 2.0 -->
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\netstandard2.0\"/>
</files>
</package>
-92
View File
@@ -1,92 +0,0 @@
<?xml version="1.0"?>
<package >
<metadata>
<id>MQTTnet</id>
<version>0.0.0</version>
<authors>Christian Kratky</authors>
<owners>Christian Kratky</owners>
<license type="file">LICENSE</license>
<projectUrl>https://github.com/chkr1011/MQTTnet</projectUrl>
<iconUrl>https://raw.githubusercontent.com/chkr1011/MQTTnet/master/Images/Logo_128x128.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker).</description>
<releaseNotes>
* [Core] Added support for MQTTv5 packages.
* [Core] Performance improvements.
* [Core] Removed obsolete methods.
* [Core] Fixed a memory leak when processing lots of messages (thanks to @tschanko)
* [Core] Added more overloads for MQTT factory.
* [Core] The client password is now hidden from the logs (replaced with **** if set).
* [Core] Fixed a memory leak when using SSL connections (thanks to @biovoid).
* [Client] Added validation of topics before publishing.
* [Client] Added new MQTTv5 features to options builder.
* [Client] Added uniform API across all supported MQTT versions (BREAKING CHANGE!)
* [Client] The client will now avoid sending an ACK if an exception has been thrown in message handler (thanks to @ramonsmits).
* [Client] Fixed issues in QoS 2 handling which leads to message loss.
* [Client] Replaced all events with proper async compatible handlers (BREAKING CHANGE!).
* [Client] Added more configuration values to TCP endpoint options.
* [Client] Added used PacketIdentifier to publish result.
* [ManagedClient] Replaced all events with proper async compatible handlers (BREAKING CHANGE!).
* [ManagedClient] The log ID is now propagated to the internal client (thanks to @vbBerni).
* [ManagedClient] Added validation of topics before publishing.
* [ManagedClient] The internal MQTT client is now closed properly (thanks to @vbBerni).
* [Server] Added support for MQTTv5 clients. The server will still return _success_ for all cases at the moment even if more granular codes are available.
* [Server] Fixed issues in QoS 2 handling which leads to message loss.
* [Server] Replaced all events with proper async compatible handlers (BREAKING CHANGE!).
* [Server] The used logger instance is now propagated to the WebSocket server adapter.
* [Server] Added the flag "IsSecureConnection" which is set to true when the connection is encrypted.
* [Server] Fixed wrong will message behavior when stopping server (thanks to @JohBa)
* [Server] Added validation of topics before publishing.
* [Server] Added more configuration values to TCP endpoint options.
* [MQTTnet Server] Added as first Alpha version of standalone cross platform MQTT server.
* [Note] Due to MQTTv5 a lot of new classes were introduced. This required adding new namespaces as well. Most classes are backward compatible but new namespaces must be added.
</releaseNotes>
<copyright>Copyright Christian Kratky 2016-2019</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>
<dependencies>
<group targetFramework="netstandard1.3">
<dependency id="NETStandard.Library" version="1.3.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="netstandard2.0">
<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.8" />
</group>
<group targetFramework="net452">
</group>
<group targetFramework="net461">
</group>
</dependencies>
</metadata>
<files>
<!-- License -->
<file src="..\LICENSE" />
<!-- .NET Standard 1.3 -->
<file src="..\Source\MQTTnet\bin\Release\netstandard1.3\MQTTnet.*" target="lib\netstandard1.3\"/>
<!-- .NET Standard 2.0 -->
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\netstandard2.0\"/>
<!-- Universal Windows -->
<file src="..\Source\MQTTnet\bin\Release\uap10.0\MQTTnet.*" target="lib\uap10.0\"/>
<!-- .NET Framework -->
<file src="..\Source\MQTTnet\bin\Release\net452\MQTTnet.*" target="lib\net452\"/>
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\net461\"/>
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\net462\"/>
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\net470\"/>
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\net471\"/>
<file src="..\Source\MQTTnet\bin\Release\netstandard2.0\MQTTnet.*" target="lib\net472\"/>
</files>
</package>
-68
View File
@@ -1,68 +0,0 @@
param([string]$assemblyVersion, [string]$nugetVersion)
if ([string]::IsNullOrEmpty($assemblyVersion)) {$assemblyVersion = "0.0.1"}
if ([string]::IsNullOrEmpty($nugetVersion)) {$nugetVersion = "0.0.1"}
$vswhere = ${Env:\ProgramFiles(x86)} + '\Microsoft Visual Studio\Installer\vswhere'
$msbuild = &$vswhere -products * -requires Microsoft.Component.MSBuild -latest -find MSBuild\**\Bin\MSBuild.exe
Write-Host
Write-Host "Assembly version = $assemblyVersion"
Write-Host "Nuget version = $nugetVersion"
Write-Host "MSBuild path = $msbuild"
Write-Host
# Build the core library
&$msbuild ..\Source\MQTTnet\MQTTnet.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /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="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="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
&$msbuild ..\Source\MQTTnet.AspNetCore\MQTTnet.AspNetCore.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"
# Build the RPC extension
&$msbuild ..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /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="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="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
# Build the Managed Client extension
&$msbuild ..\Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="net452" /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="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="uap10.0" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
# Build MQTTnet.Server
Remove-Item ..\Source\MQTTnet.Server\bin\Release\netcoreapp2.2 -Recurse -Force -ErrorAction SilentlyContinue
&$msbuild ..\Source\MQTTnet.Server\MQTTnet.Server.csproj /t:Build /p:Configuration="Release" /p:TargetFramework="netcoreapp2.2" /p:FileVersion=$assemblyVersion /p:AssemblyVersion=$assemblyVersion /verbosity:m /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=".\..\..\Build\codeSigningKey.pfx"
$source = "..\Source\MQTTnet.Server\bin\Release\netcoreapp2.2"
$destination = "..\Source\MQTTnet.Server\bin\MQTTnet.Server-Portable-v$nugetVersion.zip"
If(Test-path $destination) {Remove-item $destination}
Add-Type -assembly "system.io.compression.filesystem"
[io.compression.zipfile]::CreateFromDirectory($source, $destination)
# Create NuGet packages.
Remove-Item .\NuGet -Force -Recurse -ErrorAction SilentlyContinue
Copy-Item MQTTnet.AspNetCore.nuspec -Destination MQTTnet.AspNetCore.nuspec.old -Force
(Get-Content MQTTnet.AspNetCore.nuspec) -replace '\$nugetVersion', $nugetVersion | Set-Content MQTTnet.AspNetCore.nuspec
Copy-Item MQTTnet.Extensions.Rpc.nuspec -Destination MQTTnet.Extensions.Rpc.nuspec.old -Force
(Get-Content MQTTnet.Extensions.Rpc.nuspec) -replace '\$nugetVersion', $nugetVersion | Set-Content MQTTnet.Extensions.Rpc.nuspec
Copy-Item MQTTnet.Extensions.ManagedClient.nuspec -Destination MQTTnet.Extensions.ManagedClient.nuspec.old -Force
(Get-Content MQTTnet.Extensions.ManagedClient.nuspec) -replace '\$nugetVersion', $nugetVersion | Set-Content MQTTnet.Extensions.ManagedClient.nuspec
New-Item -ItemType Directory -Force -Path .\NuGet
.\nuget.exe pack MQTTnet.nuspec -Verbosity detailed -Symbols -OutputDir "NuGet" -Version $nugetVersion
.\nuget.exe pack MQTTnet.NETStandard.nuspec -Verbosity detailed -Symbols -OutputDir "NuGet" -Version $nugetVersion
.\nuget.exe pack MQTTnet.AspNetCore.nuspec -Verbosity detailed -Symbols -OutputDir "NuGet" -Version $nugetVersion
.\nuget.exe pack MQTTnet.Extensions.Rpc.nuspec -Verbosity detailed -Symbols -OutputDir "NuGet" -Version $nugetVersion
.\nuget.exe pack MQTTnet.Extensions.ManagedClient.nuspec -Verbosity detailed -Symbols -OutputDir "NuGet" -Version $nugetVersion
Move-Item MQTTnet.AspNetCore.nuspec.old -Destination MQTTnet.AspNetCore.nuspec -Force
Move-Item MQTTnet.Extensions.Rpc.nuspec.old -Destination MQTTnet.Extensions.Rpc.nuspec -Force
Move-Item MQTTnet.Extensions.ManagedClient.nuspec.old -Destination MQTTnet.Extensions.ManagedClient.nuspec -Force
Binary file not shown.
BIN
View File
Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
param([string]$apiKey)
$files = Get-ChildItem -Path ".\NuGet" -Filter "*.nupkg"
foreach ($file in $files)
{
Write-Host "Uploading: " $file
.\nuget.exe push $file.Fullname $apiKey -NoSymbols -Source https://api.nuget.org/v3/index.json
}
+6
View File
@@ -0,0 +1,6 @@
# Code of Conduct
This project has adopted the code of conduct defined by the Contributor Covenant
to clarify expected behavior in our community.
For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
+9
View File
@@ -0,0 +1,9 @@
<Project>
<PropertyGroup>
<TestingPlatformShowTestsFailure>true</TestingPlatformShowTestsFailure>
<TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
<EnableMSTestRunner>true</EnableMSTestRunner>
</PropertyGroup>
</Project>
-9
View File
@@ -1,9 +0,0 @@
# Import codeSigningKey.pfx
In order to import the key for code signing on a new developer machine use the following command within the VS developer command line:
> sn –i codeSigningKey.pfx VS_KEY_EFCA4C5B6DFD4B4F
The container name may be different.
# Check if the assembly has a strong name
> sn -vf MQTTnet.dll
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

+239
View File
@@ -0,0 +1,239 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg8"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="MQTT.svg">
<defs
id="defs2">
<filter
inkscape:label="Blur Double"
inkscape:menu="Blurs"
inkscape:menu-tooltip="Overlays two copies with different blur amounts and modifiable blend and composite"
style="color-interpolation-filters:sRGB;"
id="filter3801">
<feGaussianBlur
stdDeviation="5"
result="fbSourceGraphic"
id="feGaussianBlur3793" />
<feGaussianBlur
stdDeviation="0.01"
in="SourceGraphic"
result="result1"
id="feGaussianBlur3795" />
<feComposite
in2="result1"
operator="arithmetic"
in="fbSourceGraphic"
k2="0.5"
k3="0.5"
result="result2"
id="feComposite3797" />
<feBlend
in2="fbSourceGraphic"
mode="normal"
result="result3"
id="feBlend3799" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.24748737"
inkscape:cx="955.72999"
inkscape:cy="295.38958"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="3840"
inkscape:window-height="2066"
inkscape:window-x="2989"
inkscape:window-y="-11"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
ry="50"
rx="50"
style="fill:#000000;stroke-width:0.26458332;filter:url(#filter3801)"
y="92.501205"
x="56.367012"
height="512"
width="512"
id="rect3791"
inkscape:export-xdpi="2.6500001"
inkscape:export-ydpi="2.6500001" />
<rect
id="rect3713"
width="512"
height="512"
x="53.721176"
y="88.797035"
style="fill:#aa0000;stroke-width:0.26458332"
rx="50"
ry="50"
inkscape:export-xdpi="2.6500001"
inkscape:export-ydpi="2.6500001" />
<rect
style="fill:#ce0000;fill-opacity:0.60591131;stroke-width:0.28100395"
id="rect3806"
width="143.25298"
height="9.0714283"
x="270.81995"
y="554.02386"
inkscape:export-xdpi="2.6500001"
inkscape:export-ydpi="2.6500001" />
<path
inkscape:connector-curvature="0"
id="path4638"
d="m 494.14104,142.00092 -5.35736,41.28822 67.77684,374.38977 a 263.46279,229.17651 36.835702 0 1 4.98278,-0.4605 263.46279,229.17651 36.835702 0 1 7.77403,0.0471 z"
style="fill:#ce0000;fill-opacity:0.60591131;stroke-width:0.59952348"
inkscape:transform-center-x="-28.818481"
inkscape:transform-center-y="146.97441"
inkscape:export-xdpi="2.6500001"
inkscape:export-ydpi="2.6500001" />
<path
style="fill:#d40000;stroke-width:1.76103246"
d="m 2138.1582,1411.377 a 995.76488,866.17897 0 0 0 -842.3984,854.3418 995.76488,866.17897 0 0 0 0.2988,5.0097 h 653.123 c 104.693,0 188.9766,-84.2836 188.9766,-188.9765 z"
transform="scale(0.26458333)"
id="path3715-5-8"
inkscape:connector-curvature="0"
inkscape:export-xdpi="2.6500001"
inkscape:export-ydpi="2.6500001" />
<ellipse
style="fill:#d40000;stroke-width:0.06901014"
id="path3715-5"
cx="492.58557"
cy="170.58017"
rx="39.021355"
ry="33.94323"
inkscape:export-xdpi="2.6500001"
inkscape:export-ydpi="2.6500001" />
<path
style="fill:#ce0000;fill-opacity:0.60591131;stroke-width:2.26591563"
d="M 464.66602,532.89453 542.01562,669.92969 1595.373,1648.873 a 995.76487,866.17896 0 0 1 14.0293,-12.6835 995.76487,866.17896 0 0 1 23.6231,-17.4727 z"
id="rect3806-2"
inkscape:connector-curvature="0"
transform="scale(0.26458333)"
inkscape:export-xdpi="2.6500001"
inkscape:export-ydpi="2.6500001" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="102.34985"
y="320.75201"
id="text3774"
inkscape:export-xdpi="2.6500001"
inkscape:export-ydpi="2.6500001"><tspan
sodipodi:role="line"
id="tspan3772"
x="102.34985"
y="320.75201"
style="font-size:141.1111145px;fill:#ffffff;stroke-width:0.26458332">MQTT</tspan></text>
<ellipse
ry="33.94323"
rx="39.021355"
cy="148.56271"
cx="124.47787"
id="ellipse3768"
style="fill:#d40000;stroke-width:0.06901014"
inkscape:export-xdpi="2.6500001"
inkscape:export-ydpi="2.6500001" />
<ellipse
style="fill:#d40000;stroke-width:0.06901014"
id="ellipse3770"
cx="234.9953"
cy="556.91571"
rx="39.021355"
ry="33.94323"
inkscape:export-xdpi="2.6500001"
inkscape:export-ydpi="2.6500001" />
<text
id="text3778"
y="474.73837"
x="194.57605"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"
inkscape:export-xdpi="2.6500001"
inkscape:export-ydpi="2.6500001"><tspan
style="font-size:141.1111145px;fill:#ffffff;stroke-width:0.26458332"
y="474.73837"
x="194.57605"
id="tspan3776"
sodipodi:role="line">net</tspan></text>
<rect
ry="50"
rx="50"
style="fill:#aa0000;stroke-width:0.26458332"
y="97.349655"
x="-672.18286"
height="512"
width="512"
id="rect4642"
inkscape:export-xdpi="6.3499999"
inkscape:export-ydpi="6.3499999" />
<path
inkscape:connector-curvature="0"
id="path4648"
d="m -160.18302,381.97945 a 263.46279,229.17652 0 0 0 -222.88457,226.0446 263.46279,229.17652 0 0 0 0.0791,1.32549 h 172.80546 c 27.70002,0 50.00005,-22.30004 50.00005,-50.00004 z"
style="fill:#d40000;stroke-width:0.46593982"
inkscape:export-xdpi="6.3499999"
inkscape:export-ydpi="6.3499999" />
<text
id="text4656"
y="329.30466"
x="-639.42944"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"
inkscape:export-xdpi="6.3499999"
inkscape:export-ydpi="6.3499999"><tspan
style="font-weight:bold;font-size:141.1111145px;fill:#ffffff;stroke-width:0.26458332"
y="329.30466"
x="-639.42944"
id="tspan4654"
sodipodi:role="line">MQTT</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="-550.90747"
y="482.23267"
id="text4664"
inkscape:export-xdpi="6.3499999"
inkscape:export-ydpi="6.3499999"><tspan
sodipodi:role="line"
id="tspan4662"
x="-550.90747"
y="482.23267"
style="font-weight:bold;font-size:141.1111145px;fill:#ffffff;stroke-width:0.26458332">net</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

+3 -2
View File
@@ -1,6 +1,7 @@
MIT License
The MIT License (MIT)
MQTTnet Copyright (c) 2016-2019 Christian Kratky
Copyright (c) .NET Foundation and Contributors
All Rights Reserved
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
-241
View File
@@ -1,241 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2010
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{9248C2E1-B9D6-40BF-81EC-86004D7765B4}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{32A630A7-2598-41D7-B625-204CD906F5FB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet", "Source\MQTTnet\MQTTnet.csproj", "{3587E506-55A2-4EB3-99C7-DC01E42D25D2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{67C28AC1-BC3A-420A-BE9C-FA2401431CF9}"
ProjectSection(SolutionItems) = preProject
Build\build.ps1 = Build\build.ps1
Build\MQTTnet.AspNetCore.nuspec = Build\MQTTnet.AspNetCore.nuspec
Build\MQTTnet.Extensions.ManagedClient.nuspec = Build\MQTTnet.Extensions.ManagedClient.nuspec
Build\MQTTnet.Extensions.Rpc.nuspec = Build\MQTTnet.Extensions.Rpc.nuspec
Build\MQTTnet.nuspec = Build\MQTTnet.nuspec
Build\upload.ps1 = Build\upload.ps1
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B3F60ECB-45BA-4C66-8903-8BB89CA67998}"
ProjectSection(SolutionItems) = preProject
.bettercodehub.yml = .bettercodehub.yml
appveyor.yml = appveyor.yml
LICENSE = LICENSE
README.md = README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.TestApp.NetCore", "Tests\MQTTnet.TestApp.NetCore\MQTTnet.TestApp.NetCore.csproj", "{3D283AAD-AAA8-4339-8394-52F80B6304DB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.TestApp.AspNetCore2", "Tests\MQTTnet.TestApp.AspNetCore2\MQTTnet.TestApp.AspNetCore2.csproj", "{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.AspNetCore", "Source\MQTTnet.AspnetCore\MQTTnet.AspNetCore.csproj", "{F10C4060-F7EE-4A83-919F-FF723E72F94A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{12816BCC-AF9E-44A9-9AE5-C246AF2A0587}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.Rpc", "Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj", "{C444E9C8-95FA-430E-9126-274129DE16CD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Benchmarks", "Tests\MQTTnet.Benchmarks\MQTTnet.Benchmarks.csproj", "{998D04DD-7CB0-45F5-A393-E2495C16399E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.ManagedClient", "Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj", "{C400533A-8EBA-4F0B-BF4D-295C3708604B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.AspNetCore.Tests", "Tests\MQTTnet.AspNetCore.Tests\MQTTnet.AspNetCore.Tests.csproj", "{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Tests", "Tests\MQTTnet.Core.Tests\MQTTnet.Tests.csproj", "{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Server", "Source\MQTTnet.Server\MQTTnet.Server.csproj", "{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|ARM.ActiveCfg = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|ARM.Build.0 = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x64.ActiveCfg = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x64.Build.0 = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x86.ActiveCfg = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x86.Build.0 = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|Any CPU.Build.0 = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|ARM.ActiveCfg = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|ARM.Build.0 = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x64.ActiveCfg = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x64.Build.0 = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x86.ActiveCfg = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x86.Build.0 = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|ARM.ActiveCfg = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|ARM.Build.0 = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x64.ActiveCfg = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x64.Build.0 = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x86.ActiveCfg = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x86.Build.0 = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|Any CPU.Build.0 = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|ARM.ActiveCfg = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|ARM.Build.0 = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x64.ActiveCfg = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x64.Build.0 = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x86.ActiveCfg = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x86.Build.0 = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|ARM.Build.0 = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x64.ActiveCfg = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x64.Build.0 = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x86.ActiveCfg = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x86.Build.0 = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|Any CPU.Build.0 = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|ARM.ActiveCfg = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|ARM.Build.0 = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x64.ActiveCfg = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x64.Build.0 = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x86.ActiveCfg = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x86.Build.0 = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|ARM.ActiveCfg = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|ARM.Build.0 = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x64.ActiveCfg = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x64.Build.0 = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x86.ActiveCfg = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x86.Build.0 = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|Any CPU.Build.0 = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|ARM.ActiveCfg = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|ARM.Build.0 = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x64.ActiveCfg = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x64.Build.0 = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x86.ActiveCfg = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x86.Build.0 = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|ARM.Build.0 = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x64.ActiveCfg = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x64.Build.0 = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x86.ActiveCfg = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x86.Build.0 = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|Any CPU.Build.0 = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|ARM.ActiveCfg = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|ARM.Build.0 = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x64.ActiveCfg = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x64.Build.0 = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x86.ActiveCfg = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x86.Build.0 = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|ARM.Build.0 = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x64.ActiveCfg = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x64.Build.0 = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x86.ActiveCfg = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x86.Build.0 = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|Any CPU.Build.0 = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|ARM.ActiveCfg = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|ARM.Build.0 = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x64.ActiveCfg = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x64.Build.0 = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x86.ActiveCfg = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x86.Build.0 = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|ARM.Build.0 = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x64.ActiveCfg = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x64.Build.0 = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x86.ActiveCfg = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x86.Build.0 = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|Any CPU.Build.0 = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|ARM.ActiveCfg = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|ARM.Build.0 = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x64.ActiveCfg = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x64.Build.0 = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x86.ActiveCfg = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x86.Build.0 = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|ARM.Build.0 = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x64.ActiveCfg = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x64.Build.0 = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x86.ActiveCfg = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x86.Build.0 = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|Any CPU.Build.0 = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|ARM.ActiveCfg = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|ARM.Build.0 = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x64.ActiveCfg = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x64.Build.0 = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x86.ActiveCfg = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x86.Build.0 = Release|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|ARM.ActiveCfg = Debug|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|ARM.Build.0 = Debug|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x64.ActiveCfg = Debug|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x64.Build.0 = Debug|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x86.ActiveCfg = Debug|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Debug|x86.Build.0 = Debug|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|Any CPU.Build.0 = Release|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|ARM.ActiveCfg = Release|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|ARM.Build.0 = Release|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x64.ActiveCfg = Release|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x64.Build.0 = Release|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x86.ActiveCfg = Release|Any CPU
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41}.Release|x86.Build.0 = Release|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|ARM.ActiveCfg = Debug|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|ARM.Build.0 = Debug|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x64.ActiveCfg = Debug|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x64.Build.0 = Debug|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x86.ActiveCfg = Debug|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Debug|x86.Build.0 = Debug|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|Any CPU.Build.0 = Release|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|ARM.ActiveCfg = Release|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|ARM.Build.0 = Release|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x64.ActiveCfg = Release|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x64.Build.0 = Release|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x86.ActiveCfg = Release|Any CPU
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{3587E506-55A2-4EB3-99C7-DC01E42D25D2} = {32A630A7-2598-41D7-B625-204CD906F5FB}
{3D283AAD-AAA8-4339-8394-52F80B6304DB} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
{F10C4060-F7EE-4A83-919F-FF723E72F94A} = {32A630A7-2598-41D7-B625-204CD906F5FB}
{C444E9C8-95FA-430E-9126-274129DE16CD} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587}
{998D04DD-7CB0-45F5-A393-E2495C16399E} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
{C400533A-8EBA-4F0B-BF4D-295C3708604B} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587}
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
{9C7106CA-96B8-4ABE-B3B4-9357AB8ACB41} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
{DADEA836-5CC3-474C-A2D8-4D0F31118CD7} = {32A630A7-2598-41D7-B625-204CD906F5FB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {07536672-5CBC-4BE3-ACE0-708A431A7894}
EndGlobalSection
EndGlobal
+45 -223
View File
@@ -1,268 +1,90 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28729.10
# Visual Studio Version 17
VisualStudioVersion = 17.0.31919.166
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Tests", "Tests\MQTTnet.Core.Tests\MQTTnet.Tests.csproj", "{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{9248C2E1-B9D6-40BF-81EC-86004D7765B4}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{32A630A7-2598-41D7-B625-204CD906F5FB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MQTTnet.TestApp.UniversalWindows", "Tests\MQTTnet.TestApp.UniversalWindows\MQTTnet.TestApp.UniversalWindows.csproj", "{FF1F72D6-9524-4422-9497-3CC0002216ED}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet", "Source\MQTTnet\MQTTnet.csproj", "{3587E506-55A2-4EB3-99C7-DC01E42D25D2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{67C28AC1-BC3A-420A-BE9C-FA2401431CF9}"
ProjectSection(SolutionItems) = preProject
Build\build.ps1 = Build\build.ps1
Build\MQTTnet.AspNetCore.nuspec = Build\MQTTnet.AspNetCore.nuspec
Build\MQTTnet.Extensions.ManagedClient.nuspec = Build\MQTTnet.Extensions.ManagedClient.nuspec
Build\MQTTnet.Extensions.Rpc.nuspec = Build\MQTTnet.Extensions.Rpc.nuspec
Build\MQTTnet.NETStandard.nuspec = Build\MQTTnet.NETStandard.nuspec
Build\MQTTnet.nuspec = Build\MQTTnet.nuspec
Build\upload.ps1 = Build\upload.ps1
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B3F60ECB-45BA-4C66-8903-8BB89CA67998}"
ProjectSection(SolutionItems) = preProject
.bettercodehub.yml = .bettercodehub.yml
appveyor.yml = appveyor.yml
CODE-OF-CONDUCT.md = CODE-OF-CONDUCT.md
LICENSE = LICENSE
README.md = README.md
Source\ReleaseNotes.md = Source\ReleaseNotes.md
.github\workflows\ci.yml = .github\workflows\ci.yml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.TestApp.NetCore", "Tests\MQTTnet.TestApp.NetCore\MQTTnet.TestApp.NetCore.csproj", "{3D283AAD-AAA8-4339-8394-52F80B6304DB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.TestApp.AspNetCore2", "Tests\MQTTnet.TestApp.AspNetCore2\MQTTnet.TestApp.AspNetCore2.csproj", "{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.AspNetCore", "Source\MQTTnet.AspnetCore\MQTTnet.AspNetCore.csproj", "{F10C4060-F7EE-4A83-919F-FF723E72F94A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{12816BCC-AF9E-44A9-9AE5-C246AF2A0587}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.Rpc", "Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj", "{C444E9C8-95FA-430E-9126-274129DE16CD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Benchmarks", "Tests\MQTTnet.Benchmarks\MQTTnet.Benchmarks.csproj", "{998D04DD-7CB0-45F5-A393-E2495C16399E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Samples", "Samples\MQTTnet.Samples.csproj", "{71CF35F5-3327-4A91-AAF4-5340F6701771}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.ManagedClient", "Source\MQTTnet.Extensions.ManagedClient\MQTTnet.Extensions.ManagedClient.csproj", "{C400533A-8EBA-4F0B-BF4D-295C3708604B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Tests", "Source\MQTTnet.Tests\MQTTnet.Tests.csproj", "{B270F32A-9F3E-42EE-A989-813E35E29ADB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.AspNetCore.Tests", "Tests\MQTTnet.AspNetCore.Tests\MQTTnet.AspNetCore.Tests.csproj", "{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Benchmarks", "Source\MQTTnet.Benchmarks\MQTTnet.Benchmarks.csproj", "{2F516E76-AAC4-4219-B7D1-34CDD3CFF381}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Server", "Source\MQTTnet.Server\MQTTnet.Server.csproj", "{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.TestApp", "Source\MQTTnet.TestApp\MQTTnet.TestApp.csproj", "{175D5340-CC5B-4542-939D-4E7D15A0BC8D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.AspTestApp", "Source\MQTTnet.AspTestApp\MQTTnet.AspTestApp.csproj", "{72867E4C-4E15-4E8E-8FAB-AE9253286BBC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MQTTnet.Extensions.TopicTemplate", "Source\MQTTnet.Extensions.TopicTemplate\MQTTnet.Extensions.TopicTemplate.csproj", "{374D5861-F7A6-42A2-8CBE-040846000EF9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MQTTnet.Server", "Source\MQTTnet.Server\MQTTnet.Server.csproj", "{C876EFFD-C5AD-4E26-BD9F-4C48252C02BC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Debug|ARM.ActiveCfg = Debug|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Debug|ARM.Build.0 = Debug|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Debug|x64.ActiveCfg = Debug|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Debug|x64.Build.0 = Debug|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Debug|x86.ActiveCfg = Debug|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Debug|x86.Build.0 = Debug|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Release|Any CPU.Build.0 = Release|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Release|ARM.ActiveCfg = Release|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Release|ARM.Build.0 = Release|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Release|x64.ActiveCfg = Release|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Release|x64.Build.0 = Release|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Release|x86.ActiveCfg = Release|Any CPU
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC}.Release|x86.Build.0 = Release|Any CPU
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Debug|ARM.ActiveCfg = Debug|ARM
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Debug|ARM.Build.0 = Debug|ARM
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Debug|ARM.Deploy.0 = Debug|ARM
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Debug|x64.ActiveCfg = Debug|x64
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Debug|x64.Build.0 = Debug|x64
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Debug|x64.Deploy.0 = Debug|x64
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Debug|x86.ActiveCfg = Debug|x86
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Debug|x86.Build.0 = Debug|x86
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Debug|x86.Deploy.0 = Debug|x86
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Release|Any CPU.Build.0 = Release|Any CPU
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Release|ARM.ActiveCfg = Release|ARM
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Release|ARM.Build.0 = Release|ARM
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Release|ARM.Deploy.0 = Release|ARM
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Release|x64.ActiveCfg = Release|x64
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Release|x64.Build.0 = Release|x64
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Release|x64.Deploy.0 = Release|x64
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Release|x86.ActiveCfg = Release|x86
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Release|x86.Build.0 = Release|x86
{FF1F72D6-9524-4422-9497-3CC0002216ED}.Release|x86.Deploy.0 = Release|x86
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|ARM.ActiveCfg = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|ARM.Build.0 = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x64.ActiveCfg = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x64.Build.0 = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x86.ActiveCfg = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Debug|x86.Build.0 = Debug|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|Any CPU.Build.0 = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|ARM.ActiveCfg = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|ARM.Build.0 = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x64.ActiveCfg = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x64.Build.0 = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x86.ActiveCfg = Release|Any CPU
{3587E506-55A2-4EB3-99C7-DC01E42D25D2}.Release|x86.Build.0 = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|ARM.ActiveCfg = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|ARM.Build.0 = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x64.ActiveCfg = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x64.Build.0 = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x86.ActiveCfg = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Debug|x86.Build.0 = Debug|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|Any CPU.Build.0 = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|ARM.ActiveCfg = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|ARM.Build.0 = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x64.ActiveCfg = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x64.Build.0 = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x86.ActiveCfg = Release|Any CPU
{3D283AAD-AAA8-4339-8394-52F80B6304DB}.Release|x86.Build.0 = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|ARM.Build.0 = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x64.ActiveCfg = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x64.Build.0 = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x86.ActiveCfg = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Debug|x86.Build.0 = Debug|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|Any CPU.Build.0 = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|ARM.ActiveCfg = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|ARM.Build.0 = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x64.ActiveCfg = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x64.Build.0 = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x86.ActiveCfg = Release|Any CPU
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9}.Release|x86.Build.0 = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|ARM.ActiveCfg = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|ARM.Build.0 = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x64.ActiveCfg = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x64.Build.0 = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x86.ActiveCfg = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Debug|x86.Build.0 = Debug|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|Any CPU.Build.0 = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|ARM.ActiveCfg = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|ARM.Build.0 = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x64.ActiveCfg = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x64.Build.0 = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x86.ActiveCfg = Release|Any CPU
{F10C4060-F7EE-4A83-919F-FF723E72F94A}.Release|x86.Build.0 = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|ARM.Build.0 = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x64.ActiveCfg = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x64.Build.0 = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x86.ActiveCfg = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Debug|x86.Build.0 = Debug|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|Any CPU.Build.0 = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|ARM.ActiveCfg = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|ARM.Build.0 = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x64.ActiveCfg = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x64.Build.0 = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x86.ActiveCfg = Release|Any CPU
{C444E9C8-95FA-430E-9126-274129DE16CD}.Release|x86.Build.0 = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|ARM.Build.0 = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x64.ActiveCfg = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x64.Build.0 = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x86.ActiveCfg = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Debug|x86.Build.0 = Debug|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|Any CPU.Build.0 = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|ARM.ActiveCfg = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|ARM.Build.0 = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x64.ActiveCfg = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x64.Build.0 = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x86.ActiveCfg = Release|Any CPU
{998D04DD-7CB0-45F5-A393-E2495C16399E}.Release|x86.Build.0 = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|ARM.Build.0 = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x64.ActiveCfg = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x64.Build.0 = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x86.ActiveCfg = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Debug|x86.Build.0 = Debug|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|Any CPU.Build.0 = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|ARM.ActiveCfg = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|ARM.Build.0 = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x64.ActiveCfg = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x64.Build.0 = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x86.ActiveCfg = Release|Any CPU
{C400533A-8EBA-4F0B-BF4D-295C3708604B}.Release|x86.Build.0 = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|ARM.Build.0 = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x64.ActiveCfg = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x64.Build.0 = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x86.ActiveCfg = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Debug|x86.Build.0 = Debug|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|Any CPU.Build.0 = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|ARM.ActiveCfg = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|ARM.Build.0 = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x64.ActiveCfg = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x64.Build.0 = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x86.ActiveCfg = Release|Any CPU
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E}.Release|x86.Build.0 = Release|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Debug|ARM.ActiveCfg = Debug|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Debug|ARM.Build.0 = Debug|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Debug|x64.ActiveCfg = Debug|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Debug|x64.Build.0 = Debug|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Debug|x86.ActiveCfg = Debug|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Debug|x86.Build.0 = Debug|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Release|Any CPU.Build.0 = Release|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Release|ARM.ActiveCfg = Release|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Release|ARM.Build.0 = Release|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Release|x64.ActiveCfg = Release|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Release|x64.Build.0 = Release|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Release|x86.ActiveCfg = Release|Any CPU
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B}.Release|x86.Build.0 = Release|Any CPU
{71CF35F5-3327-4A91-AAF4-5340F6701771}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{71CF35F5-3327-4A91-AAF4-5340F6701771}.Debug|Any CPU.Build.0 = Debug|Any CPU
{71CF35F5-3327-4A91-AAF4-5340F6701771}.Release|Any CPU.ActiveCfg = Release|Any CPU
{71CF35F5-3327-4A91-AAF4-5340F6701771}.Release|Any CPU.Build.0 = Release|Any CPU
{B270F32A-9F3E-42EE-A989-813E35E29ADB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B270F32A-9F3E-42EE-A989-813E35E29ADB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B270F32A-9F3E-42EE-A989-813E35E29ADB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B270F32A-9F3E-42EE-A989-813E35E29ADB}.Release|Any CPU.Build.0 = Release|Any CPU
{2F516E76-AAC4-4219-B7D1-34CDD3CFF381}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F516E76-AAC4-4219-B7D1-34CDD3CFF381}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F516E76-AAC4-4219-B7D1-34CDD3CFF381}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F516E76-AAC4-4219-B7D1-34CDD3CFF381}.Release|Any CPU.Build.0 = Release|Any CPU
{175D5340-CC5B-4542-939D-4E7D15A0BC8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{175D5340-CC5B-4542-939D-4E7D15A0BC8D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{175D5340-CC5B-4542-939D-4E7D15A0BC8D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{175D5340-CC5B-4542-939D-4E7D15A0BC8D}.Release|Any CPU.Build.0 = Release|Any CPU
{72867E4C-4E15-4E8E-8FAB-AE9253286BBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{72867E4C-4E15-4E8E-8FAB-AE9253286BBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72867E4C-4E15-4E8E-8FAB-AE9253286BBC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72867E4C-4E15-4E8E-8FAB-AE9253286BBC}.Release|Any CPU.Build.0 = Release|Any CPU
{374D5861-F7A6-42A2-8CBE-040846000EF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{374D5861-F7A6-42A2-8CBE-040846000EF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{374D5861-F7A6-42A2-8CBE-040846000EF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{374D5861-F7A6-42A2-8CBE-040846000EF9}.Release|Any CPU.Build.0 = Release|Any CPU
{C876EFFD-C5AD-4E26-BD9F-4C48252C02BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C876EFFD-C5AD-4E26-BD9F-4C48252C02BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C876EFFD-C5AD-4E26-BD9F-4C48252C02BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C876EFFD-C5AD-4E26-BD9F-4C48252C02BC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{A7FF0C91-25DE-4BA6-B39E-F54E8DADF1CC} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
{FF1F72D6-9524-4422-9497-3CC0002216ED} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
{3587E506-55A2-4EB3-99C7-DC01E42D25D2} = {32A630A7-2598-41D7-B625-204CD906F5FB}
{3D283AAD-AAA8-4339-8394-52F80B6304DB} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
{C6FF8AEA-0855-41EC-A1F3-AC262225BAB9} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
{F10C4060-F7EE-4A83-919F-FF723E72F94A} = {32A630A7-2598-41D7-B625-204CD906F5FB}
{C444E9C8-95FA-430E-9126-274129DE16CD} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587}
{998D04DD-7CB0-45F5-A393-E2495C16399E} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
{C400533A-8EBA-4F0B-BF4D-295C3708604B} = {12816BCC-AF9E-44A9-9AE5-C246AF2A0587}
{61B62223-F5D0-48E4-BBD6-2CBA9353CB5E} = {9248C2E1-B9D6-40BF-81EC-86004D7765B4}
{5699FB8C-838C-4AB0-80A5-9CA809F9B65B} = {32A630A7-2598-41D7-B625-204CD906F5FB}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {07536672-5CBC-4BE3-ACE0-708A431A7894}
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
EndGlobalSection
EndGlobal
+247 -1
View File
@@ -1,14 +1,260 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertIfStatementToSwitchStatement/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InconsistentNaming/@EntryIndexedValue">SUGGESTION</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UncatchableException/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnthrowableException/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_EMBEDDED_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_EXPR_MEMBER_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INITIALIZER_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_INVOCATION_PARENS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_EXISTING_PROPERTY_PATTERNS_ARRANGEMENT/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_USER_LINEBREAKS/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_ANONYMOUSMETHOD_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_STATEMENT_ON_SAME_LINE/@EntryValue">NEVER</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_INITIALIZER_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_PROPERTY_PATTERN_ON_SINGLE_LINE/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_METHOD_CALL_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_METHOD_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_WITHIN_PARENTHESES/@EntryValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_AFTER_DECLARATION_LPAR/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_AFTER_INVOCATION_LPAR/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ARGUMENTS_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_ARRAY_INITIALIZER_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_CHAINED_METHOD_CALLS/@EntryValue">CHOP_IF_LONG</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_EXTENDS_LIST_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">180</s:Int64>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_PARAMETERS_STYLE/@EntryValue">CHOP_IF_LONG</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/XmlDocFormatter/KeepUserLineBreaks/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/XmlDocFormatter/ProcessingInstructionAttributesFormat/@EntryValue">OnDifferentLines</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/XmlDocFormatter/TagAttributesFormat/@EntryValue">OnDifferentLines</s:String>
<s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;
&lt;Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns"&gt;
&lt;TypePattern DisplayName="Non-reorderable types"&gt;
&lt;TypePattern.Match&gt;
&lt;Or&gt;
&lt;And&gt;
&lt;Kind Is="Interface" /&gt;
&lt;Or&gt;
&lt;HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" /&gt;
&lt;HasAttribute Name="System.Runtime.InteropServices.ComImport" /&gt;
&lt;/Or&gt;
&lt;/And&gt;
&lt;Kind Is="Struct" /&gt;
&lt;HasAttribute Name="JetBrains.Annotations.NoReorderAttribute" /&gt;
&lt;HasAttribute Name="JetBrains.Annotations.NoReorder" /&gt;
&lt;/Or&gt;
&lt;/TypePattern.Match&gt;
&lt;/TypePattern&gt;
&lt;TypePattern DisplayName="xUnit.net Test Classes" RemoveRegions="All"&gt;
&lt;TypePattern.Match&gt;
&lt;And&gt;
&lt;Kind Is="Class" /&gt;
&lt;HasMember&gt;
&lt;And&gt;
&lt;Kind Is="Method" /&gt;
&lt;HasAttribute Name="Xunit.FactAttribute" Inherited="True" /&gt;
&lt;HasAttribute Name="Xunit.TheoryAttribute" Inherited="True" /&gt;
&lt;/And&gt;
&lt;/HasMember&gt;
&lt;/And&gt;
&lt;/TypePattern.Match&gt;
&lt;Entry DisplayName="Setup/Teardown Methods"&gt;
&lt;Entry.Match&gt;
&lt;Or&gt;
&lt;Kind Is="Constructor" /&gt;
&lt;And&gt;
&lt;Kind Is="Method" /&gt;
&lt;ImplementsInterface Name="System.IDisposable" /&gt;
&lt;/And&gt;
&lt;/Or&gt;
&lt;/Entry.Match&gt;
&lt;Entry.SortBy&gt;
&lt;Kind Order="Constructor" /&gt;
&lt;/Entry.SortBy&gt;
&lt;/Entry&gt;
&lt;Entry DisplayName="All other members" /&gt;
&lt;Entry Priority="100" DisplayName="Test Methods"&gt;
&lt;Entry.Match&gt;
&lt;And&gt;
&lt;Kind Is="Method" /&gt;
&lt;HasAttribute Name="Xunit.FactAttribute" /&gt;
&lt;HasAttribute Name="Xunit.TheoryAttribute" /&gt;
&lt;/And&gt;
&lt;/Entry.Match&gt;
&lt;Entry.SortBy&gt;
&lt;Name /&gt;
&lt;/Entry.SortBy&gt;
&lt;/Entry&gt;
&lt;/TypePattern&gt;
&lt;TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All"&gt;
&lt;TypePattern.Match&gt;
&lt;And&gt;
&lt;Kind Is="Class" /&gt;
&lt;Or&gt;
&lt;HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" /&gt;
&lt;HasAttribute Name="NUnit.Framework.TestFixtureSourceAttribute" Inherited="True" /&gt;
&lt;HasMember&gt;
&lt;And&gt;
&lt;Kind Is="Method" /&gt;
&lt;HasAttribute Name="NUnit.Framework.TestAttribute" /&gt;
&lt;HasAttribute Name="NUnit.Framework.TestCaseAttribute" /&gt;
&lt;HasAttribute Name="NUnit.Framework.TestCaseSourceAttribute" /&gt;
&lt;/And&gt;
&lt;/HasMember&gt;
&lt;/Or&gt;
&lt;/And&gt;
&lt;/TypePattern.Match&gt;
&lt;Entry DisplayName="Setup/Teardown Methods"&gt;
&lt;Entry.Match&gt;
&lt;And&gt;
&lt;Kind Is="Method" /&gt;
&lt;Or&gt;
&lt;HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="True" /&gt;
&lt;HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="True" /&gt;
&lt;HasAttribute Name="NUnit.Framework.TestFixtureSetUpAttribute" Inherited="True" /&gt;
&lt;HasAttribute Name="NUnit.Framework.TestFixtureTearDownAttribute" Inherited="True" /&gt;
&lt;HasAttribute Name="NUnit.Framework.OneTimeSetUpAttribute" Inherited="True" /&gt;
&lt;HasAttribute Name="NUnit.Framework.OneTimeTearDownAttribute" Inherited="True" /&gt;
&lt;/Or&gt;
&lt;/And&gt;
&lt;/Entry.Match&gt;
&lt;/Entry&gt;
&lt;Entry DisplayName="All other members" /&gt;
&lt;Entry Priority="100" DisplayName="Test Methods"&gt;
&lt;Entry.Match&gt;
&lt;And&gt;
&lt;Kind Is="Method" /&gt;
&lt;HasAttribute Name="NUnit.Framework.TestAttribute" /&gt;
&lt;HasAttribute Name="NUnit.Framework.TestCaseAttribute" /&gt;
&lt;HasAttribute Name="NUnit.Framework.TestCaseSourceAttribute" /&gt;
&lt;/And&gt;
&lt;/Entry.Match&gt;
&lt;Entry.SortBy&gt;
&lt;Name /&gt;
&lt;/Entry.SortBy&gt;
&lt;/Entry&gt;
&lt;/TypePattern&gt;
&lt;TypePattern DisplayName="Default Pattern"&gt;
&lt;Entry Priority="100" DisplayName="Public Delegates"&gt;
&lt;Entry.Match&gt;
&lt;And&gt;
&lt;Access Is="Public" /&gt;
&lt;Kind Is="Delegate" /&gt;
&lt;/And&gt;
&lt;/Entry.Match&gt;
&lt;Entry.SortBy&gt;
&lt;Name /&gt;
&lt;/Entry.SortBy&gt;
&lt;/Entry&gt;
&lt;Entry Priority="100" DisplayName="Public Enums"&gt;
&lt;Entry.Match&gt;
&lt;And&gt;
&lt;Access Is="Public" /&gt;
&lt;Kind Is="Enum" /&gt;
&lt;/And&gt;
&lt;/Entry.Match&gt;
&lt;Entry.SortBy&gt;
&lt;Name /&gt;
&lt;/Entry.SortBy&gt;
&lt;/Entry&gt;
&lt;Entry DisplayName="Static Fields and Constants"&gt;
&lt;Entry.Match&gt;
&lt;Or&gt;
&lt;Kind Is="Constant" /&gt;
&lt;And&gt;
&lt;Kind Is="Field" /&gt;
&lt;Static /&gt;
&lt;/And&gt;
&lt;/Or&gt;
&lt;/Entry.Match&gt;
&lt;Entry.SortBy&gt;
&lt;Kind Order="Constant Field" /&gt;
&lt;/Entry.SortBy&gt;
&lt;/Entry&gt;
&lt;Entry DisplayName="Fields"&gt;
&lt;Entry.Match&gt;
&lt;And&gt;
&lt;Kind Is="Field" /&gt;
&lt;Not&gt;
&lt;Static /&gt;
&lt;/Not&gt;
&lt;/And&gt;
&lt;/Entry.Match&gt;
&lt;Entry.SortBy&gt;
&lt;Readonly /&gt;
&lt;Name /&gt;
&lt;/Entry.SortBy&gt;
&lt;/Entry&gt;
&lt;Entry DisplayName="Constructors"&gt;
&lt;Entry.Match&gt;
&lt;Kind Is="Constructor" /&gt;
&lt;/Entry.Match&gt;
&lt;Entry.SortBy&gt;
&lt;Static /&gt;
&lt;/Entry.SortBy&gt;
&lt;/Entry&gt;
&lt;Entry DisplayName="Events"&gt;
&lt;Entry.Match&gt;
&lt;Kind Is="Event" /&gt;
&lt;/Entry.Match&gt;
&lt;Entry.SortBy&gt;
&lt;Name /&gt;
&lt;/Entry.SortBy&gt;
&lt;/Entry&gt;
&lt;Entry DisplayName="Properties, Indexers"&gt;
&lt;Entry.Match&gt;
&lt;Or&gt;
&lt;Kind Is="Property" /&gt;
&lt;Kind Is="Indexer" /&gt;
&lt;/Or&gt;
&lt;/Entry.Match&gt;
&lt;Entry.SortBy&gt;
&lt;Access Order="Public Internal Protected Private" /&gt;
&lt;Name /&gt;
&lt;/Entry.SortBy&gt;
&lt;/Entry&gt;
&lt;Entry DisplayName="All other members"&gt;
&lt;Entry.SortBy&gt;
&lt;Access Order="Public Internal Protected Private" /&gt;
&lt;Name /&gt;
&lt;/Entry.SortBy&gt;
&lt;/Entry&gt;
&lt;Entry DisplayName="Nested Types"&gt;
&lt;Entry.Match&gt;
&lt;Kind Is="Type" /&gt;
&lt;/Entry.Match&gt;
&lt;/Entry&gt;
&lt;/TypePattern&gt;
&lt;/Patterns&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">Licensed to the .NET Foundation under one or more agreements.
The .NET Foundation licenses this file to you under the MIT license.
See the LICENSE file in the project root for more information.</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002ECodeCleanup_002EFileHeader_002EFileHeaderSettingsMigrate/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002EMemberReordering_002EMigrations_002ECSharpFileLayoutPatternRemoveIsAttributeUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAlwaysTreatStructAsNotReorderableMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=catched/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=CONNACK/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=PINGREQ/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=PINGRESP/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=PUBACK/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=PUBCOMP/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=PUBREC/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=PUBREL/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=SUBACK/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Tnet/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=unsub/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=UNSUBACK/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
+36 -84
View File
@@ -1,41 +1,44 @@
<p align="center">
<img src="https://github.com/chkr1011/MQTTnet/blob/master/Images/Logo_128x128.png?raw=true" width="128">
<br/>
<img src="https://github.com/dotnet/MQTTnet/blob/master/Images/icon_det_256.png?raw=true" width="196">
<br/>
</p>
[![NuGet Badge](https://buildstats.info/nuget/MQTTnet)](https://www.nuget.org/packages/MQTTnet)
[![Build status](https://ci.appveyor.com/api/projects/status/ycit86voxfevm2aa/branch/master?svg=true)](https://ci.appveyor.com/project/chkr1011/mqttnet)
[![BCH compliance](https://bettercodehub.com/edge/badge/chkr1011/MQTTnet?branch=master)](https://bettercodehub.com/)
[![OpenCollective](https://opencollective.com/mqttnet/backers/badge.svg)](https://opencollective.com/mqttnet)
[![OpenCollective](https://opencollective.com/mqttnet/sponsors/badge.svg)](https://opencollective.com/mqttnet)
[![NuGet Badge](https://img.shields.io/nuget/dt/MQTTnet)](https://www.nuget.org/packages/MQTTnet)
[![CI](https://github.com/dotnet/MQTTnet/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/dotnet/MQTTnet/actions/workflows/ci.yml)
[![MyGet](https://img.shields.io/myget/mqttnet/v/mqttnet?color=orange&label=preview)](https://www.myget.org/feed/mqttnet/package/nuget/MQTTnet)
![Size](https://img.shields.io/github/repo-size/dotnet/MQTTnet.svg)
[![Join the chat at https://gitter.im/MQTTnet/community](https://badges.gitter.im/MQTTnet/community.svg)](https://gitter.im/MQTTnet/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://raw.githubusercontent.com/dotnet/MQTTnet/master/LICENSE)
# MQTTnet
MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker). The implementation is based on the documentation from <http://mqtt.org/>.
MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (
broker) and supports the MQTT protocol up to version 5. It is compatible with mostly any supported .NET Framework
version and CPU architecture.
## Features
### General
* Async support
* TLS 1.2 support for client and server (but not UWP servers)
* TLS support for client and server (but not UWP servers)
* Extensible communication channels (e.g. In-Memory, TCP, TCP+TLS, WS)
* Lightweight (only the low level implementation of MQTT, no overhead)
* Performance optimized (processing ~70.000 messages / second)*
* Performance optimized (processing ~150.000 messages / second)*
* Uniform API across all supported versions of the MQTT protocol
* Interfaces included for mocking and testing
* Access to internal trace messages
* Unit tested (~200 tests)
* Unit tested (~636 tests)
* No external dependencies
\* Tested on local machine (Intel i7 8700K) with MQTTnet client and server running in the same process using the TCP channel. The app for verification is part of this repository and stored in _/Tests/MQTTnet.TestApp.NetCore_.
\* Tested on local machine (Intel i7 8700K) with MQTTnet client and server running in the same process using the TCP
channel. The app for verification is part of this repository and stored in _/Tests/MQTTnet.TestApp.NetCore_.
### Client
* Communication via TCP (+TLS) or WS (WebSocket) supported
* Included core _MqttClient_ with low level functionality
* Also included _ManagedMqttClient_ which maintains the connection and subscriptions automatically. Also application messages are queued and re-scheduled for higher QoS levels automatically.
* Included core _LowLevelMqttClient_ with low level functionality
* Also included _ManagedMqttClient_ which maintains the connection and subscriptions automatically. Also application
messages are queued and re-scheduled for higher QoS levels automatically.
* Rx support (via another project)
* Compatible with Microsoft Azure IoT Hub
@@ -50,82 +53,31 @@ MQTTnet is a high performance .NET library for MQTT based communication. It prov
* WebSockets supported (via ASP.NET Core 2.0, separate nuget)
* A custom message interceptor can be added which allows transforming or extending every received application message
* Validate subscriptions and deny subscribing of certain topics depending on requesting clients
* Connect clients with different protocol versions at the same time.
## MQTTnet Server
## Getting Started
_MQTTnet Server_ is a standalone cross platform MQTT server (like mosquitto) basing on this library. It has the following features.
* Running portable (no installation required)
* Runs und Windows, Linux, macOS, Raspberry Pi
* Python scripting support for manipulating messages, validation of clients, building business logic etc.
* Supports WebSocket and TCP (with and without TLS) connections
* Provides a HTTP based API (including Swagger endpoint)
* Extensive configuration parameters and customization supported
MQTTnet is delivered via <b>NuGet</b> package manager. You can find the packages
here: https://www.nuget.org/packages/MQTTnet/
## Supported frameworks
Use these command in the Package Manager console to install MQTTnet manually:
* .NET Standard 1.3+
* .NET Core 1.1+
* .NET Core App 1.1+
* .NET Framework 4.5.2+ (x86, x64, AnyCPU)
* Mono 5.2+
* Universal Windows Platform (UWP) 10.0.10240+ (x86, x64, ARM, AnyCPU, Windows 10 IoT Core)
* Xamarin.Android 7.5+
* Xamarin.iOS 10.14+
```
Install-Package MQTTnet
```
## Supported MQTT versions
Samples for using MQTTnet are part of this repository. For starters these samples are recommended:
* 5.0.0
* 3.1.1
* 3.1.0
- [Connect with a broker](https://github.com/dotnet/MQTTnet/blob/master/Samples/Client/Client_Connection_Samples.cs)
- [Subscribing to data](https://github.com/dotnet/MQTTnet/blob/master/Samples/Client/Client_Subscribe_Samples.cs)
- [Publishing data](https://github.com/dotnet/MQTTnet/blob/master/Samples/Client/Client_Publish_Samples.cs)
- [Host own broker](https://github.com/dotnet/MQTTnet/blob/master/Samples/Server/Server_Simple_Samples.cs)
## Nuget
## Code of Conduct
This library is available as a nuget package: <https://www.nuget.org/packages/MQTTnet/>
This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our
community.
For more information see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
## Examples
## .NET Foundation
Please find examples and the documentation at the Wiki of this repository (<https://github.com/chkr1011/MQTTnet/wiki>).
## Contributions
If you want to contribute to this project just create a pull request. But only pull requests which are matching the code style of this library will be accepted. Before creating a pull request please have a look at the library to get an overview of the required style.
Also additions and updates in the Wiki are welcome.
**This project, like all projects requires time and money. If you feel compelled to support the development team, you can do so through Open Collective (https://opencollective.com/mqttnet)**.
## References
This library is used in the following projects:
* Azure Functions MQTT Bindings, [CaseOnline.Azure.WebJobs.Extensions.Mqtt](https://github.com/keesschollaart81/CaseOnline.Azure.WebJobs.Extensions.Mqtt/)
* HA4IoT (Open Source Home Automation system for .NET, <https://github.com/chkr1011/HA4IoT>)
* MQTT Client Rx (Wrapper for Reactive Extensions, <https://github.com/1iveowl/MQTTClient.rx>)
* MQTT Tester (MQTT client test app for [Android](https://play.google.com/store/apps/details?id=com.liveowl.mqtttester) and [iOS](https://itunes.apple.com/us/app/mqtt-tester/id1278621826?mt=8))
* Wirehome.Core (Open Source Home Automation system for .NET Core, <https://github.com/chkr1011/Wirehome.Core>)
If you use this library and want to see your project here please create a pull request.
## License
MIT License
MQTTnet Copyright (c) 2016-2019 Christian Kratky
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
This project is supported by the [.NET Foundation](https://dotnetfoundation.org).
+522
View File
@@ -0,0 +1,522 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using MQTTnet.Formatter;
using MQTTnet.Protocol;
using MQTTnet.Samples.Helpers;
using MQTTnet.Server;
using MQTTnet.Server.EnhancedAuthentication;
namespace MQTTnet.Samples.Client;
public static class Client_Connection_Samples
{
const string mosquitto_org = @"
-----BEGIN CERTIFICATE-----
MIIEAzCCAuugAwIBAgIUBY1hlCGvdj4NhBXkZ/uLUZNILAwwDQYJKoZIhvcNAQEL
BQAwgZAxCzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5Vbml0ZWQgS2luZ2RvbTEOMAwG
A1UEBwwFRGVyYnkxEjAQBgNVBAoMCU1vc3F1aXR0bzELMAkGA1UECwwCQ0ExFjAU
BgNVBAMMDW1vc3F1aXR0by5vcmcxHzAdBgkqhkiG9w0BCQEWEHJvZ2VyQGF0Y2hv
by5vcmcwHhcNMjAwNjA5MTEwNjM5WhcNMzAwNjA3MTEwNjM5WjCBkDELMAkGA1UE
BhMCR0IxFzAVBgNVBAgMDlVuaXRlZCBLaW5nZG9tMQ4wDAYDVQQHDAVEZXJieTES
MBAGA1UECgwJTW9zcXVpdHRvMQswCQYDVQQLDAJDQTEWMBQGA1UEAwwNbW9zcXVp
dHRvLm9yZzEfMB0GCSqGSIb3DQEJARYQcm9nZXJAYXRjaG9vLm9yZzCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAME0HKmIzfTOwkKLT3THHe+ObdizamPg
UZmD64Tf3zJdNeYGYn4CEXbyP6fy3tWc8S2boW6dzrH8SdFf9uo320GJA9B7U1FW
Te3xda/Lm3JFfaHjkWw7jBwcauQZjpGINHapHRlpiCZsquAthOgxW9SgDgYlGzEA
s06pkEFiMw+qDfLo/sxFKB6vQlFekMeCymjLCbNwPJyqyhFmPWwio/PDMruBTzPH
3cioBnrJWKXc3OjXdLGFJOfj7pP0j/dr2LH72eSvv3PQQFl90CZPFhrCUcRHSSxo
E6yjGOdnz7f6PveLIB574kQORwt8ePn0yidrTC1ictikED3nHYhMUOUCAwEAAaNT
MFEwHQYDVR0OBBYEFPVV6xBUFPiGKDyo5V3+Hbh4N9YSMB8GA1UdIwQYMBaAFPVV
6xBUFPiGKDyo5V3+Hbh4N9YSMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
BQADggEBAGa9kS21N70ThM6/Hj9D7mbVxKLBjVWe2TPsGfbl3rEDfZ+OKRZ2j6AC
6r7jb4TZO3dzF2p6dgbrlU71Y/4K0TdzIjRj3cQ3KSm41JvUQ0hZ/c04iGDg/xWf
+pp58nfPAYwuerruPNWmlStWAXf0UTqRtg4hQDWBuUFDJTuWuuBvEXudz74eh/wK
sMwfu1HFvjy5Z0iMDU8PUDepjVolOCue9ashlS4EB5IECdSR2TItnAIiIwimx839
LdUdRudafMu5T5Xma182OC0/u/xRlEm+tvKGGmfFcN0piqVl8OrSPBgIlb+1IKJE
m/XriWr/Cq4h/JfB7NTsezVslgkBaoU=
-----END CERTIFICATE-----
";
public static async Task Clean_Disconnect()
{
/*
* This sample disconnects in a clean way. This will send a MQTT DISCONNECT packet
* to the server and close the connection afterward.
*
* See sample _Connect_Client_ for more details.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build();
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
// This will send the DISCONNECT packet. Calling _Dispose_ without DisconnectAsync the
// connection is closed in a "not clean" way. See MQTT specification for more details.
await mqttClient.DisconnectAsync(new MqttClientDisconnectOptionsBuilder().WithReason(MqttClientDisconnectOptionsReason.NormalDisconnection).Build());
}
public static async Task Connect()
{
/*
* This sample creates a simple MQTT client and connects to a public broker.
*
* Always dispose the client when it is no longer used.
* The default version of MQTT is 3.1.1.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
// Use builder classes where possible in this project.
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build();
// This will throw an exception if the server is not available.
// The result from this message returns additional data which was sent
// from the server. Please refer to the MQTT protocol specification for details.
var response = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
Console.WriteLine("The MQTT client is connected.");
response.DumpToConsole();
// Send a clean disconnect to the server by calling _DisconnectAsync_. Without this the TCP connection
// gets dropped and the server will handle this as a non clean disconnect (see MQTT spec for details).
var mqttClientDisconnectOptions = mqttFactory.CreateClientDisconnectOptionsBuilder().Build();
await mqttClient.DisconnectAsync(mqttClientDisconnectOptions, CancellationToken.None);
}
public static async Task Connect_Using_Enhanced_Authentication()
{
/*
* This sample uses enhanced authentication (Kerberos) when creating the connection.
*/
/*
* Server part...
*/
var mqttServerFactory = new MqttServerFactory();
var serverOptions = mqttServerFactory.CreateServerOptionsBuilder().WithDefaultEndpoint().Build();
var server = mqttServerFactory.CreateMqttServer(serverOptions);
server.ValidatingConnectionAsync += async args =>
{
if (args.AuthenticationMethod == "GS2-KRB5")
{
var result = await args.ExchangeEnhancedAuthenticationAsync(new ExchangeEnhancedAuthenticationOptions(), args.CancellationToken);
Console.WriteLine($"Received AUTH data from client: {Encoding.UTF8.GetString(result.AuthenticationData)}");
var authOptions = mqttServerFactory.CreateExchangeExtendedAuthenticationOptionsBuilder().WithAuthenticationData("reply context token").Build();
result = await args.ExchangeEnhancedAuthenticationAsync(authOptions, args.CancellationToken);
Console.WriteLine($"Received AUTH data from client: {Encoding.UTF8.GetString(result.AuthenticationData)}");
args.ResponseAuthenticationData = "outcome of authentication"u8.ToArray();
// Authentication DONE!
args.ReasonCode = MqttConnectReasonCode.Success; // Also the default!
}
else
{
args.ReasonCode = MqttConnectReasonCode.BadAuthenticationMethod;
}
};
await server.StartAsync();
/*
* Client part...
*/
var mqttClientFactory = new MqttClientFactory();
// Use Kerberos sample from the MQTT RFC.
var kerberosAuthenticationHandler = new SampleClientKerberosAuthenticationHandler();
var clientOptions = mqttClientFactory.CreateClientOptionsBuilder()
.WithTcpServer("localhost")
.WithProtocolVersion(MqttProtocolVersion.V500)
.WithEnhancedAuthenticationHandler(kerberosAuthenticationHandler)
.WithEnhancedAuthentication("GS2-KRB5")
.Build();
var client = mqttClientFactory.CreateMqttClient();
var result = await client.ConnectAsync(clientOptions);
Console.WriteLine($"Client connect result: {result.ResultCode}");
}
public static async Task Connect_Using_MQTTv5()
{
/*
* This sample creates a simple MQTT client and connects to a public broker using MQTTv5.
*
* This is a modified version of the sample _Connect_Client_! See other sample for more details.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").WithProtocolVersion(MqttProtocolVersion.V500).Build();
// In MQTTv5 the response contains much more information.
var response = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
Console.WriteLine("The MQTT client is connected.");
response.DumpToConsole();
}
public static async Task Connect_Using_TLS_1_2()
{
/*
* This sample creates a simple MQTT client and connects to a public broker using TLS 1.2 encryption.
*
* This is a modified version of the sample _Connect_Client_! See other sample for more details.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("mqtt.fluux.io")
.WithTlsOptions(
o =>
{
// The used public broker sometimes has invalid certificates. This sample accepts all
// certificates. This should not be used in live environments.
o.WithCertificateValidationHandler(_ => true);
// The default value is determined by the OS. Set manually to force version.
o.WithSslProtocols(SslProtocols.Tls12);
})
.Build();
using var timeout = new CancellationTokenSource(5000);
await mqttClient.ConnectAsync(mqttClientOptions, timeout.Token);
Console.WriteLine("The MQTT client is connected.");
}
public static async Task Connect_Using_TLS_Encryption()
{
/*
* This sample creates a simple MQTT client and connects to a public broker with enabled TLS encryption.
*
* This is a modified version of the sample _Connect_Client_! See other sample for more details.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("test.mosquitto.org", 8883)
.WithTlsOptions(
o => o.WithCertificateValidationHandler(
// The used public broker sometimes has invalid certificates. This sample accepts all
// certificates. This should not be used in live environments.
_ => true))
.Build();
// In MQTTv5 the response contains much more information.
using var timeout = new CancellationTokenSource(5000);
var response = await mqttClient.ConnectAsync(mqttClientOptions, timeout.Token);
Console.WriteLine("The MQTT client is connected.");
response.DumpToConsole();
}
public static async Task Connect_Using_TLS_With_CA_File()
{
var mqttFactory = new MqttClientFactory();
var caChain = new X509Certificate2Collection();
caChain.ImportFromPem(mosquitto_org); // from https://test.mosquitto.org/ssl/mosquitto.org.crt
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("test.mosquitto.org", 8883)
.WithTlsOptions(new MqttClientTlsOptionsBuilder().WithTrustChain(caChain).Build())
.Build();
var connAck = await mqttClient.ConnectAsync(mqttClientOptions);
Console.WriteLine("Connected to test.moquitto.org:8883 with CaFile mosquitto.org.crt: " + connAck.ResultCode);
}
public static async Task Connect_Using_WebSockets()
{
/*
* This sample creates a simple MQTT client and connects to a public broker using a WebSocket connection.
*
* This is a modified version of the sample _Connect_Client_! See other sample for more details.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithWebSocketServer(o => o.WithUri("broker.hivemq.com:8000/mqtt")).Build();
var response = await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
Console.WriteLine("The MQTT client is connected.");
response.DumpToConsole();
}
public static async Task Connect_With_Amazon_AWS()
{
/*
* This sample creates a simple MQTT client and connects to an Amazon Web Services broker.
*
* The broker requires special settings which are set here.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("amazon.web.services.broker")
// Disabling packet fragmentation is very important!
.WithoutPacketFragmentation()
.Build();
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
Console.WriteLine("The MQTT client is connected.");
await mqttClient.DisconnectAsync();
}
public static async Task Disconnect_Clean()
{
/*
* This sample disconnects from the server with sending a DISCONNECT packet.
* This way of disconnecting is treated as a clean disconnect which will not
* trigger sending the last will etc.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build();
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
// Calling _DisconnectAsync_ will send a DISCONNECT packet before closing the connection.
// Using a reason code requires MQTT version 5.0.0!
await mqttClient.DisconnectAsync(MqttClientDisconnectOptionsReason.ImplementationSpecificError);
}
public static async Task Disconnect_Non_Clean()
{
/*
* This sample disconnects from the server without sending a DISCONNECT packet.
* This way of disconnecting is treated as a non-clean disconnect which will
* trigger sending the last will etc.
*/
var mqttFactory = new MqttClientFactory();
var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build();
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
// Calling _Dispose_ or use of a _using_ statement will close the transport connection
// without sending a DISCONNECT packet to the server.
mqttClient.Dispose();
}
public static async Task Inspect_Certificate_Validation_Errors()
{
/*
* This sample prints the certificate information while connection. This data can be used to decide whether a connection is secure or not
* including the reason for that status.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("mqtt.fluux.io", 8883)
.WithTlsOptions(
o =>
{
o.WithCertificateValidationHandler(
eventArgs =>
{
eventArgs.Certificate.Subject.DumpToConsole();
eventArgs.Certificate.GetExpirationDateString().DumpToConsole();
eventArgs.Chain.ChainPolicy.RevocationMode.DumpToConsole();
eventArgs.Chain.ChainStatus.DumpToConsole();
eventArgs.SslPolicyErrors.DumpToConsole();
return true;
});
})
.Build();
// In MQTTv5 the response contains much more information.
using var timeout = new CancellationTokenSource(5000);
await mqttClient.ConnectAsync(mqttClientOptions, timeout.Token);
}
public static async Task Ping_Server()
{
/*
* This sample sends a PINGREQ packet to the server and waits for a reply.
*
* This is only supported in MQTTv5.0.0+.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build();
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
// This will throw an exception if the server does not reply.
await mqttClient.PingAsync(CancellationToken.None);
Console.WriteLine("The MQTT server replied to the ping request.");
}
public static async Task Reconnect_Using_Event()
{
/*
* This sample shows how to reconnect when the connection was dropped.
* This approach uses one of the events from the client.
* This approach has a risk of deadlocks! Consider using the timer approach (see sample).
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build();
mqttClient.DisconnectedAsync += async e =>
{
if (e.ClientWasConnected)
{
// Use the current options as the new options.
await mqttClient.ConnectAsync(mqttClientOptions);
}
};
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
}
public static void Reconnect_Using_Timer()
{
/*
* This sample shows how to reconnect when the connection was dropped.
* This approach uses a custom Task/Thread which will monitor the connection status.
* This is the recommended way but requires more custom code!
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build();
_ = Task.Run(
async () =>
{
// User proper cancellation and no while(true).
while (true)
{
try
{
// This code will also do the very first connect! So no call to _ConnectAsync_ is required in the first place.
if (!await mqttClient.TryPingAsync())
{
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
// Subscribe to topics when session is clean etc.
Console.WriteLine("The MQTT client is connected.");
}
}
catch
{
// Handle the exception properly (logging etc.).
}
finally
{
// Check the connection state every 5 seconds and perform a reconnect if required.
await Task.Delay(TimeSpan.FromSeconds(5));
}
}
});
Console.WriteLine("Press <Enter> to exit");
Console.ReadLine();
}
public static async Task Timeout()
{
/*
* This sample creates a simple MQTT client and connects to an invalid broker using a timeout.
*
* This is a modified version of the sample _Connect_Client_! See other sample for more details.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1").Build();
try
{
using var timeoutToken = new CancellationTokenSource(TimeSpan.FromSeconds(1));
await mqttClient.ConnectAsync(mqttClientOptions, timeoutToken.Token);
}
catch (OperationCanceledException)
{
Console.WriteLine("Timeout while connecting.");
}
}
class SampleClientKerberosAuthenticationHandler : IMqttEnhancedAuthenticationHandler
{
public async Task HandleEnhancedAuthenticationAsync(MqttEnhancedAuthenticationEventArgs eventArgs)
{
if (eventArgs.AuthenticationMethod != "GS2-KRB5")
{
throw new InvalidOperationException("Wrong authentication method");
}
var sendOptions = new SendMqttEnhancedAuthenticationDataOptions
{
Data = "initial context token"u8.ToArray()
};
await eventArgs.SendAsync(sendOptions);
var response = await eventArgs.ReceiveAsync(CancellationToken.None);
Console.WriteLine($"Received AUTH data from server: {Encoding.UTF8.GetString(response.AuthenticationData)}");
// No further data is required, but we have to fulfil the exchange.
sendOptions = new SendMqttEnhancedAuthenticationDataOptions
{
Data = []
};
await eventArgs.SendAsync(sendOptions, CancellationToken.None);
}
}
}
+87
View File
@@ -0,0 +1,87 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
namespace MQTTnet.Samples.Client;
public static class Client_Publish_Samples
{
public static async Task Publish_Application_Message()
{
/*
* This sample pushes a simple application message including a topic and a payload.
*
* Always use builders where they exist. Builders (in this project) are designed to be
* backward compatible. Creating an _MqttApplicationMessage_ via its constructor is also
* supported but the class might change often in future releases where the builder does not
* or at least provides backward compatibility where possible.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder()
.WithTcpServer("broker.hivemq.com")
.Build();
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
var applicationMessage = new MqttApplicationMessageBuilder()
.WithTopic("samples/temperature/living_room")
.WithPayload("19.5")
.Build();
await mqttClient.PublishAsync(applicationMessage, CancellationToken.None);
await mqttClient.DisconnectAsync();
Console.WriteLine("MQTT application message is published.");
}
public static async Task Publish_Multiple_Application_Messages()
{
/*
* This sample pushes multiple simple application message including a topic and a payload.
*
* See sample _Publish_Application_Message_ for more details.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder()
.WithTcpServer("broker.hivemq.com")
.Build();
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
var applicationMessage = new MqttApplicationMessageBuilder()
.WithTopic("samples/temperature/living_room")
.WithPayload("19.5")
.Build();
await mqttClient.PublishAsync(applicationMessage, CancellationToken.None);
applicationMessage = new MqttApplicationMessageBuilder()
.WithTopic("samples/temperature/living_room")
.WithPayload("20.0")
.Build();
await mqttClient.PublishAsync(applicationMessage, CancellationToken.None);
applicationMessage = new MqttApplicationMessageBuilder()
.WithTopic("samples/temperature/living_room")
.WithPayload("21.0")
.Build();
await mqttClient.PublishAsync(applicationMessage, CancellationToken.None);
await mqttClient.DisconnectAsync();
Console.WriteLine("MQTT application message is published.");
}
}
+202
View File
@@ -0,0 +1,202 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
// ReSharper disable UnusedMember.Local
using MQTTnet.Extensions.TopicTemplate;
using MQTTnet.Packets;
using MQTTnet.Protocol;
using MQTTnet.Samples.Helpers;
namespace MQTTnet.Samples.Client;
public static class Client_Subscribe_Samples
{
static readonly MqttTopicTemplate sampleTemplate = new("mqttnet/samples/topic/{id}");
public static async Task Handle_Received_Application_Message()
{
/*
* This sample subscribes to a topic and processes the received message.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build();
// Setup message handling before connecting so that queued messages
// are also handled properly. When there is no event handler attached all
// received messages get lost.
mqttClient.ApplicationMessageReceivedAsync += e =>
{
Console.WriteLine("Received application message.");
e.DumpToConsole();
return Task.CompletedTask;
};
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder().WithTopicTemplate(sampleTemplate.WithParameter("id", "2")).Build();
await mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);
Console.WriteLine("MQTT client subscribed to topic.");
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
}
public static async Task Send_Responses()
{
/*
* This sample subscribes to a topic and sends a response to the broker. This requires at least QoS level 1 to work!
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
mqttClient.ApplicationMessageReceivedAsync += delegate(MqttApplicationMessageReceivedEventArgs args)
{
// Do some work with the message...
// Now respond to the broker with a reason code other than success.
args.ReasonCode = MqttApplicationMessageReceivedReasonCode.ImplementationSpecificError;
args.ResponseReasonString = "That did not work!";
// User properties require MQTT v5!
args.ResponseUserProperties.Add(new MqttUserProperty("My", "Data"));
// Now the broker will resend the message again.
return Task.CompletedTask;
};
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build();
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder().WithTopicTemplate(sampleTemplate.WithParameter("id", "1")).Build();
var response = await mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);
Console.WriteLine("MQTT client subscribed to topic.");
// The response contains additional data sent by the server after subscribing.
response.DumpToConsole();
}
public static async Task Subscribe_Multiple_Topics()
{
/*
* This sample subscribes to several topics in a single request.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build();
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
// Create the subscribe options including several topics with different options.
// It is also possible to all of these topics using a dedicated call of _SubscribeAsync_ per topic.
var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
.WithTopicTemplate(sampleTemplate.WithParameter("id", "1"))
.WithTopicTemplate(sampleTemplate.WithParameter("id", "2"), noLocal: true)
.WithTopicTemplate(sampleTemplate.WithParameter("id", "3"), retainHandling: MqttRetainHandling.SendAtSubscribe)
.Build();
var response = await mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);
Console.WriteLine("MQTT client subscribed to topics.");
// The response contains additional data sent by the server after subscribing.
response.DumpToConsole();
}
public static async Task Subscribe_Topic()
{
/*
* This sample subscribes to a topic.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("broker.hivemq.com").Build();
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder().WithTopicTemplate(sampleTemplate.WithParameter("id", "1")).Build();
var response = await mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);
Console.WriteLine("MQTT client subscribed to topic.");
// The response contains additional data sent by the server after subscribing.
response.DumpToConsole();
}
static void ConcurrentProcessingDisableAutoAcknowledge(CancellationToken shutdownToken, IMqttClient mqttClient)
{
/*
* This sample shows how to achieve concurrent processing and not have message AutoAcknowledged
* This to have a proper QoS1 (at-least-once) experience for what at least MQTT specification can provide
*/
mqttClient.ApplicationMessageReceivedAsync += ea =>
{
ea.AutoAcknowledge = false;
async Task ProcessAsync()
{
// DO YOUR WORK HERE!
await Task.Delay(1000, shutdownToken);
await ea.AcknowledgeAsync(shutdownToken);
// WARNING: If process failures are not transient the message will be retried on every restart of the client
// A failed message will not be dispatched again to the client as MQTT does not have a NACK packet to let
// the broker know processing failed
//
// Optionally: Use a framework like Polly to create a retry policy: https://github.com/App-vNext/Polly#retry
}
_ = Task.Run(ProcessAsync, shutdownToken);
return Task.CompletedTask;
};
}
static void ConcurrentProcessingWithLimit(CancellationToken shutdownToken, IMqttClient mqttClient)
{
/*
* This sample shows how to achieve concurrent processing, with:
* - a maximum concurrency limit based on Environment.ProcessorCount
*/
var concurrent = new SemaphoreSlim(Environment.ProcessorCount);
mqttClient.ApplicationMessageReceivedAsync += async ea =>
{
await concurrent.WaitAsync(shutdownToken).ConfigureAwait(false);
async Task ProcessAsync()
{
try
{
// DO YOUR WORK HERE!
await Task.Delay(1000, shutdownToken);
}
finally
{
concurrent.Release();
}
}
_ = Task.Run(ProcessAsync, shutdownToken);
};
}
}
+91
View File
@@ -0,0 +1,91 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
using System.Text;
using MQTTnet.Diagnostics.Logger;
namespace MQTTnet.Samples.Diagnostics;
public static class Logger_Samples
{
public static async Task Create_Custom_Logger()
{
/*
* This sample covers the creation of a custom logger which can be used to forward MQTTnet log messages
* to other loggers like Microsoft logger or Serilog or log4net etc.
*/
var mqttFactory = new MqttClientFactory(new MyLogger());
var mqttClientOptions = mqttFactory.CreateClientOptionsBuilder()
.WithTcpServer("broker.hivemq.com")
.Build();
using var mqttClient = mqttFactory.CreateMqttClient();
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
Console.WriteLine("MQTT client is connected.");
var mqttClientDisconnectOptions = mqttFactory.CreateClientDisconnectOptionsBuilder()
.Build();
await mqttClient.DisconnectAsync(mqttClientDisconnectOptions, CancellationToken.None);
}
public static async Task Use_Event_Logger()
{
/*
* This sample shows how to get logs from the library.
*
* ATTENTION: Only use the logger for debugging etc. The performance is heavily decreased when a logger is used.
*/
// The logger ID is optional but can be set do distinguish different logger instances.
var mqttEventLogger = new MqttNetEventLogger("MyCustomLogger");
mqttEventLogger.LogMessagePublished += (_, args) =>
{
var output = new StringBuilder();
output.AppendLine($">> [{args.LogMessage.Timestamp:O}] [{args.LogMessage.ThreadId}] [{args.LogMessage.Source}] [{args.LogMessage.Level}]: {args.LogMessage.Message}");
if (args.LogMessage.Exception != null)
{
output.AppendLine(args.LogMessage.Exception.ToString());
}
Console.Write(output);
};
var mqttFactory = new MqttClientFactory(mqttEventLogger);
var mqttClientOptions = mqttFactory.CreateClientOptionsBuilder()
.WithTcpServer("broker.hivemq.com")
.Build();
using var mqttClient = mqttFactory.CreateMqttClient();
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
Console.WriteLine("MQTT client is connected.");
var mqttClientDisconnectOptions = mqttFactory.CreateClientDisconnectOptionsBuilder()
.Build();
await mqttClient.DisconnectAsync(mqttClientDisconnectOptions, CancellationToken.None);
}
sealed class MyLogger : IMqttNetLogger
{
public bool IsEnabled { get; set; } = true;
public void Publish(MqttNetLogLevel logLevel, string source, string message, object[] parameters, Exception exception)
{
// Forward the log message to other loggers.
// 1. Convert log level to matching log level in target logger.
// 2. Call target logger and pass data accordingly.
}
}
}
@@ -0,0 +1,53 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
using MQTTnet.Diagnostics.PacketInspection;
namespace MQTTnet.Samples.Diagnostics;
public static class PackageInspection_Samples
{
public static async Task Inspect_Outgoing_Package()
{
/*
* This sample covers the inspection of outgoing packages from the client.
*/
var mqttFactory = new MqttClientFactory();
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = mqttFactory.CreateClientOptionsBuilder()
.WithTcpServer("broker.hivemq.com")
.Build();
mqttClient.InspectPacketAsync += OnInspectPacket;
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
Console.WriteLine("MQTT client is connected.");
var mqttClientDisconnectOptions = mqttFactory.CreateClientDisconnectOptionsBuilder()
.Build();
await mqttClient.DisconnectAsync(mqttClientDisconnectOptions, CancellationToken.None);
}
static Task OnInspectPacket(InspectMqttPacketEventArgs eventArgs)
{
if (eventArgs.Direction == MqttPacketFlowDirection.Inbound)
{
Console.WriteLine($"IN: {Convert.ToBase64String(eventArgs.Buffer)}");
}
else
{
Console.WriteLine($"OUT: {Convert.ToBase64String(eventArgs.Buffer)}");
}
return Task.CompletedTask;
}
}
+25
View File
@@ -0,0 +1,25 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Text.Json;
namespace MQTTnet.Samples.Helpers;
internal static class ObjectExtensions
{
public static TObject DumpToConsole<TObject>(this TObject @object)
{
var output = "NULL";
if (@object != null)
{
output = JsonSerializer.Serialize(@object, new JsonSerializerOptions
{
WriteIndented = true
});
}
Console.WriteLine($"[{@object?.GetType().Name}]:\r\n{output}");
return @object;
}
}
+30
View File
@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<DisableImplicitAspNetCoreAnalyzers>true</DisableImplicitAspNetCoreAnalyzers>
<EnableNETAnalyzers>false</EnableNETAnalyzers>
<EnforceCodeStyleInBuild>false</EnforceCodeStyleInBuild>
<NoWarn>1591;NETSDK1138;NU1803;NU1901;NU1902</NoWarn>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NuGetAuditMode>all</NuGetAuditMode>
<NuGetAudit>true</NuGetAudit>
<NuGetAuditLevel>low</NuGetAuditLevel>
<AnalysisLevel>latest-Recommended</AnalysisLevel>
<LangVersion>default</LangVersion>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Source\MQTTnet.AspnetCore\MQTTnet.AspNetCore.csproj"/>
<ProjectReference Include="..\Source\MQTTnet.Extensions.Rpc\MQTTnet.Extensions.Rpc.csproj"/>
<ProjectReference Include="..\Source\MQTTnet.Extensions.TopicTemplate\MQTTnet.Extensions.TopicTemplate.csproj" />
<ProjectReference Include="..\Source\MQTTnet.Server\MQTTnet.Server.csproj"/>
<ProjectReference Include="..\Source\MQTTnet\MQTTnet.csproj"/>
</ItemGroup>
</Project>
+71
View File
@@ -0,0 +1,71 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Reflection;
Console.BackgroundColor = ConsoleColor.White;
Console.BackgroundColor = ConsoleColor.Red;
Console.Title = "Samples - MQTTnet";
Console.WriteLine("----------------------------------------------");
Console.WriteLine("- Welcome to MQTTnet samples! -");
Console.WriteLine("----------------------------------------------");
Console.ResetColor();
Console.WriteLine();
var sampleClasses = Assembly.GetExecutingAssembly().GetExportedTypes().OrderBy(c => c.Name).ToList();
var index = 0;
foreach (var sampleClass in sampleClasses)
{
Console.WriteLine($"{index} = {sampleClass.Name}");
index++;
}
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("Please choose sample class (press Enter to continue): ");
Console.ResetColor();
var input = Console.ReadLine();
var selectedIndex = int.Parse(input ?? "0");
var selectedSampleClass = sampleClasses[selectedIndex];
var sampleMethods = selectedSampleClass.GetMethods(BindingFlags.Static | BindingFlags.Public).OrderBy(m => m.Name).ToList();
index = 0;
foreach (var sampleMethod in sampleMethods)
{
Console.WriteLine($"{index} = {sampleMethod.Name}");
index++;
}
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Green;
Console.Write("Please choose sample (press Enter to continue): ");
Console.ResetColor();
input = Console.ReadLine();
selectedIndex = int.Parse(input ?? "0");
var selectedSampleMethod = sampleMethods[selectedIndex];
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Executing sample...");
Console.ResetColor();
Console.WriteLine();
try
{
if (selectedSampleMethod.Invoke(null, null) is Task task)
{
await task;
}
}
catch (Exception exception)
{
Console.WriteLine(exception.ToString());
}
Console.WriteLine();
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
+85
View File
@@ -0,0 +1,85 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
using MQTTnet.Extensions.Rpc;
using MQTTnet.Protocol;
namespace MQTTnet.Samples.RpcClient;
public static class RpcClient_Samples
{
/*
* The extension MQTTnet.Extensions.Rpc (available as nuget) allows sending a request and waiting for the matching reply.
* This is done via defining a pattern which uses the topic to correlate the request and the response.
* From client usage it is possible to define a timeout.
*/
public static async Task Send_Request()
{
var mqttFactory = new MqttClientFactory();
// The RPC client is an addon for the existing client. So we need a regular client
// which is wrapped later.
using var mqttClient = mqttFactory.CreateMqttClient();
var mqttClientOptions = new MqttClientOptionsBuilder()
.WithTcpServer("broker.hivemq.com")
.Build();
await mqttClient.ConnectAsync(mqttClientOptions);
using (var mqttRpcClient = mqttFactory.CreateMqttRpcClient(mqttClient))
{
// Access to a fully featured application message is not supported for RPC calls!
// The method will throw an exception when the response was not received in time.
await mqttRpcClient.ExecuteAsync(TimeSpan.FromSeconds(2), "ping", "", MqttQualityOfServiceLevel.AtMostOnce);
}
Console.WriteLine("The RPC call was successful.");
}
/*
* The device must respond to the request using the correct topic. The following C code shows how a
* smart device like an ESP8266 must respond to the above sample.
*
// If using the MQTT client PubSubClient it must be ensured
// that the request topic for each method is subscribed like the following.
mqttClient.subscribe("MQTTnet.RPC/+/ping");
mqttClient.subscribe("MQTTnet.RPC/+/do_something");
// It is not allowed to change the structure of the topic.
// Otherwise RPC will not work.
// So method names can be separated using an _ or . but no +, # or /.
// If it is required to distinguish between devices
// own rules can be defined like the following:
mqttClient.subscribe("MQTTnet.RPC/+/deviceA.ping");
mqttClient.subscribe("MQTTnet.RPC/+/deviceB.ping");
mqttClient.subscribe("MQTTnet.RPC/+/deviceC.getTemperature");
// Within the callback of the MQTT client the topic must be checked
// if it belongs to MQTTnet RPC. The following code shows one
// possible way of doing this.
void mqtt_Callback(char *topic, byte *payload, unsigned int payloadLength)
{
String topicString = String(topic);
if (topicString.startsWith("MQTTnet.RPC/")) {
String responseTopic = topicString + String("/response");
if (topicString.endsWith("/deviceA.ping")) {
mqtt_publish(responseTopic, "pong", false);
return;
}
}
}
// Important notes:
// ! Do not send response message with the _retain_ flag set to true.
// ! All required data for a RPC call and the result must be placed into the payload.
*/
}
+110
View File
@@ -0,0 +1,110 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
// ReSharper disable EmptyConstructor
// ReSharper disable MemberCanBeMadeStatic.Local
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MQTTnet.AspNetCore;
using MQTTnet.Server;
namespace MQTTnet.Samples.Server;
public static class Server_ASP_NET_Samples
{
public static Task Start_Server_With_WebSockets_Support()
{
/*
* This sample starts a minimal ASP.NET Webserver including a hosted MQTT server.
*/
var host = Host.CreateDefaultBuilder(Array.Empty<string>())
.ConfigureWebHostDefaults(
webBuilder =>
{
webBuilder.UseKestrel(
o =>
{
// This will allow MQTT connections based on TCP port 1883.
o.ListenAnyIP(1883, l => l.UseMqtt());
// This will allow MQTT connections based on HTTP WebSockets with URI "localhost:5000/mqtt"
// See code below for URI configuration.
o.ListenAnyIP(5000); // Default HTTP pipeline
});
webBuilder.UseStartup<Startup>();
});
return host.RunConsoleAsync();
}
sealed class MqttController
{
public MqttController()
{
// Inject other services via constructor.
}
public Task OnClientConnected(ClientConnectedEventArgs eventArgs)
{
Console.WriteLine($"Client '{eventArgs.ClientId}' connected.");
return Task.CompletedTask;
}
public Task ValidateConnection(ValidatingConnectionEventArgs eventArgs)
{
Console.WriteLine($"Client '{eventArgs.ClientId}' wants to connect. Accepting!");
return Task.CompletedTask;
}
}
sealed class Startup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment environment, MqttController mqttController)
{
app.UseRouting();
app.UseEndpoints(
endpoints =>
{
endpoints.MapConnectionHandler<MqttConnectionHandler>(
"/mqtt",
httpConnectionDispatcherOptions => httpConnectionDispatcherOptions.WebSockets.SubProtocolSelector =
protocolList => protocolList.FirstOrDefault() ?? string.Empty);
});
app.UseMqttServer(
server =>
{
/*
* Attach event handlers etc. if required.
*/
server.ValidatingConnectionAsync += mqttController.ValidateConnection;
server.ClientConnectedAsync += mqttController.OnClientConnected;
});
}
public void ConfigureServices(IServiceCollection services)
{
services.AddHostedMqttServer(
optionsBuilder =>
{
optionsBuilder.WithDefaultEndpoint();
});
services.AddMqttConnectionHandler();
services.AddConnections();
services.AddSingleton<MqttController>();
}
}
}
@@ -0,0 +1,50 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using MQTTnet.Internal;
using MQTTnet.Packets;
using MQTTnet.Server;
namespace MQTTnet.Samples.Server;
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
// ReSharper disable EmptyConstructor
// ReSharper disable MemberCanBeMadeStatic.Local
public static class Server_Diagnostics_Samples
{
public static async Task Get_Notified_When_Client_Received_Message()
{
/*
* This sample starts a MQTT server and attaches an event which gets fired whenever
* a client received and acknowledged a PUBLISH packet.
*/
var mqttServerFactory = new MqttServerFactory();
var mqttServerOptions = new MqttServerOptionsBuilder().WithDefaultEndpoint().Build();
using var mqttServer = mqttServerFactory.CreateMqttServer(mqttServerOptions);
// Attach the event handler.
mqttServer.ClientAcknowledgedPublishPacketAsync += e =>
{
Console.WriteLine($"Client '{e.ClientId}' acknowledged packet {e.PublishPacket.PacketIdentifier} with topic '{e.PublishPacket.Topic}'");
// It is also possible to read additional data from the client response. This requires casting the response packet.
var qos1AcknowledgePacket = e.AcknowledgePacket as MqttPubAckPacket;
Console.WriteLine($"QoS 1 reason code: {qos1AcknowledgePacket?.ReasonCode}");
var qos2AcknowledgePacket = e.AcknowledgePacket as MqttPubCompPacket;
Console.WriteLine($"QoS 2 reason code: {qos2AcknowledgePacket?.ReasonCode}");
return CompletedTask.Instance;
};
await mqttServer.StartAsync();
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
await mqttServer.StopAsync();
}
}
@@ -0,0 +1,45 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
// ReSharper disable EmptyConstructor
// ReSharper disable MemberCanBeMadeStatic.Local
using MQTTnet.Internal;
using MQTTnet.Server;
namespace MQTTnet.Samples.Server;
public static class Server_Intercepting_Samples
{
public static async Task Intercept_Application_Messages()
{
/*
* This sample starts a simple MQTT server which manipulate all processed application messages.
* Please see _Server_Simple_Samples_ for more details on how to start a server.
*/
var mqttServerFactory = new MqttServerFactory();
var mqttServerOptions = new MqttServerOptionsBuilder().WithDefaultEndpoint().Build();
using var mqttServer = mqttServerFactory.CreateMqttServer(mqttServerOptions);
mqttServer.InterceptingPublishAsync += args =>
{
// Here we only change the topic of the received application message.
// but also changing the payload etc. is required. Changing the QoS after
// transmitting is not supported and makes no sense at all.
args.ApplicationMessage.Topic += "/manipulated";
return CompletedTask.Instance;
};
await mqttServer.StartAsync();
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
await mqttServer.StopAsync();
}
}
@@ -0,0 +1,141 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
using System.Buffers;
using System.Text.Json;
using MQTTnet.Packets;
using MQTTnet.Protocol;
using MQTTnet.Server;
namespace MQTTnet.Samples.Server;
public static class Server_Retained_Messages_Samples
{
public static async Task Persist_Retained_Messages()
{
/*
* This sample starts a simple MQTT server which will store all retained messages in a file.
*/
var storePath = Path.Combine(Path.GetTempPath(), "RetainedMessages.json");
var mqttServerFactory = new MqttServerFactory();
// Due to security reasons the "default" endpoint (which is unencrypted) is not enabled by default!
var mqttServerOptions = mqttServerFactory.CreateServerOptionsBuilder().WithDefaultEndpoint().Build();
using var server = mqttServerFactory.CreateMqttServer(mqttServerOptions);
// Make sure that the server will load the retained messages.
server.LoadingRetainedMessageAsync += async eventArgs =>
{
try
{
var models = await JsonSerializer.DeserializeAsync<List<MqttRetainedMessageModel>>(File.OpenRead(storePath)) ?? new List<MqttRetainedMessageModel>();
var retainedMessages = models.Select(m => m.ToApplicationMessage()).ToList();
eventArgs.LoadedRetainedMessages = retainedMessages;
Console.WriteLine("Retained messages loaded.");
}
catch (FileNotFoundException)
{
// Ignore because nothing is stored yet.
Console.WriteLine("No retained messages stored yet.");
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
};
// Make sure to persist the changed retained messages.
server.RetainedMessageChangedAsync += async eventArgs =>
{
try
{
// This sample uses the property _StoredRetainedMessages_ which will contain all(!) retained messages.
// The event args also contain the affected retained message (property ChangedRetainedMessage). This can be
// used to write all retained messages to dedicated files etc. Then all files must be loaded and a full list
// of retained messages must be provided in the loaded event.
var models = eventArgs.StoredRetainedMessages.Select(MqttRetainedMessageModel.Create);
var buffer = JsonSerializer.SerializeToUtf8Bytes(models);
await File.WriteAllBytesAsync(storePath, buffer);
Console.WriteLine("Retained messages saved.");
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
};
// Make sure to clear the retained messages when they are all deleted via API.
server.RetainedMessagesClearedAsync += _ =>
{
File.Delete(storePath);
return Task.CompletedTask;
};
await server.StartAsync();
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
}
sealed class MqttRetainedMessageModel
{
public string? ContentType { get; set; }
public byte[]? CorrelationData { get; set; }
public byte[]? Payload { get; set; }
public MqttPayloadFormatIndicator PayloadFormatIndicator { get; set; }
public MqttQualityOfServiceLevel QualityOfServiceLevel { get; set; }
public string? ResponseTopic { get; set; }
public string? Topic { get; set; }
public List<MqttUserProperty>? UserProperties { get; set; }
public static MqttRetainedMessageModel Create(MqttApplicationMessage message)
{
ArgumentNullException.ThrowIfNull(message);
return new MqttRetainedMessageModel
{
Topic = message.Topic,
// Create a copy of the buffer from the payload segment because
// it cannot be serialized and deserialized with the JSON serializer.
Payload = message.Payload.ToArray(),
UserProperties = message.UserProperties,
ResponseTopic = message.ResponseTopic,
CorrelationData = message.CorrelationData,
ContentType = message.ContentType,
PayloadFormatIndicator = message.PayloadFormatIndicator,
QualityOfServiceLevel = message.QualityOfServiceLevel
// Other properties like "Retain" are not if interest in the storage.
// That's why a custom model makes sense.
};
}
public MqttApplicationMessage ToApplicationMessage()
{
return new MqttApplicationMessage
{
Topic = Topic,
PayloadSegment = new ArraySegment<byte>(Payload ?? Array.Empty<byte>()),
PayloadFormatIndicator = PayloadFormatIndicator,
ResponseTopic = ResponseTopic,
CorrelationData = CorrelationData,
ContentType = ContentType,
UserProperties = UserProperties,
QualityOfServiceLevel = QualityOfServiceLevel,
Dup = false,
Retain = true
};
}
}
}
+209
View File
@@ -0,0 +1,209 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Protocol;
using MQTTnet.Server;
namespace MQTTnet.Samples.Server;
public static class Server_Simple_Samples
{
public static async Task Force_Disconnecting_Client()
{
/*
* This sample will disconnect a client.
*
* See _Run_Minimal_Server_ for more information.
*/
using var mqttServer = await StartMqttServer();
// Let the client connect.
await Task.Delay(TimeSpan.FromSeconds(5));
// Now disconnect the client (if connected).
var affectedClient = (await mqttServer.GetClientsAsync()).FirstOrDefault(c => c.Id == "MyClient");
if (affectedClient != null)
{
await affectedClient.DisconnectAsync();
}
}
public static async Task Publish_Message_From_Broker()
{
/*
* This sample will publish a message directly at the broker.
*
* See _Run_Minimal_Server_ for more information.
*/
using var mqttServer = await StartMqttServer();
// Create a new message using the builder as usual.
var message = new MqttApplicationMessageBuilder().WithTopic("HelloWorld").WithPayload("Test").Build();
// Now inject the new message at the broker.
await mqttServer.InjectApplicationMessage(
new InjectedMqttApplicationMessage(message)
{
SenderClientId = "SenderClientId"
});
}
public static async Task Run_Minimal_Server()
{
/*
* This sample starts a simple MQTT server which will accept any TCP connection.
*/
var mqttServerFactory = new MqttServerFactory();
// The port for the default endpoint is 1883.
// The default endpoint is NOT encrypted!
// Use the builder classes where possible.
var mqttServerOptions = new MqttServerOptionsBuilder().WithDefaultEndpoint().Build();
// The port can be changed using the following API (not used in this example).
// new MqttServerOptionsBuilder()
// .WithDefaultEndpoint()
// .WithDefaultEndpointPort(1234)
// .Build();
using var mqttServer = mqttServerFactory.CreateMqttServer(mqttServerOptions);
await mqttServer.StartAsync();
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
// Stop and dispose the MQTT server if it is no longer needed!
await mqttServer.StopAsync();
}
public static async Task Run_Server_With_Logging()
{
/*
* This sample starts a simple MQTT server and prints the logs to the output.
*
* IMPORTANT! Do not enable logging in live environment. It will decrease performance.
*
* See sample "Run_Minimal_Server" for more details.
*/
var mqttServerFactory = new MqttServerFactory(new ConsoleLogger());
var mqttServerOptions = new MqttServerOptionsBuilder().WithDefaultEndpoint().Build();
using var mqttServer = mqttServerFactory.CreateMqttServer(mqttServerOptions);
await mqttServer.StartAsync();
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
// Stop and dispose the MQTT server if it is no longer needed!
await mqttServer.StopAsync();
}
public static async Task Validating_Connections()
{
/*
* This sample starts a simple MQTT server which will check for valid credentials and client ID.
*
* See _Run_Minimal_Server_ for more information.
*/
var mqttServerFactory = new MqttServerFactory();
var mqttServerOptions = new MqttServerOptionsBuilder().WithDefaultEndpoint().Build();
using var mqttServer = mqttServerFactory.CreateMqttServer(mqttServerOptions);
// Setup connection validation before starting the server so that there is
// no change to connect without valid credentials.
mqttServer.ValidatingConnectionAsync += e =>
{
if (e.ClientId != "ValidClientId")
{
e.ReasonCode = MqttConnectReasonCode.ClientIdentifierNotValid;
}
if (e.UserName != "ValidUser")
{
e.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
}
if (e.Password != "SecretPassword")
{
e.ReasonCode = MqttConnectReasonCode.BadUserNameOrPassword;
}
return Task.CompletedTask;
};
await mqttServer.StartAsync();
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
await mqttServer.StopAsync();
}
static async Task<MqttServer> StartMqttServer()
{
var mqttServerFactory = new MqttServerFactory();
// Due to security reasons the "default" endpoint (which is unencrypted) is not enabled by default!
var mqttServerOptions = mqttServerFactory.CreateServerOptionsBuilder().WithDefaultEndpoint().Build();
var server = mqttServerFactory.CreateMqttServer(mqttServerOptions);
await server.StartAsync();
return server;
}
class ConsoleLogger : IMqttNetLogger
{
readonly object _consoleSyncRoot = new();
public bool IsEnabled => true;
public void Publish(MqttNetLogLevel logLevel, string source, string message, object[]? parameters, Exception? exception)
{
var foregroundColor = ConsoleColor.White;
switch (logLevel)
{
case MqttNetLogLevel.Verbose:
foregroundColor = ConsoleColor.White;
break;
case MqttNetLogLevel.Info:
foregroundColor = ConsoleColor.Green;
break;
case MqttNetLogLevel.Warning:
foregroundColor = ConsoleColor.DarkYellow;
break;
case MqttNetLogLevel.Error:
foregroundColor = ConsoleColor.Red;
break;
}
if (parameters?.Length > 0)
{
message = string.Format(message, parameters);
}
lock (_consoleSyncRoot)
{
Console.ForegroundColor = foregroundColor;
Console.WriteLine(message);
if (exception != null)
{
Console.WriteLine(exception);
}
}
}
}
}
+69
View File
@@ -0,0 +1,69 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable InconsistentNaming
using System.Net;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using MQTTnet.Server;
namespace MQTTnet.Samples.Server;
public static class Server_TLS_Samples
{
public static async Task Run_Server_With_Self_Signed_Certificate()
{
/*
* This sample starts a simple MQTT server which will accept any TCP connection.
* It also has an encrypted connection using a self signed TLS certificate.
*
* See sample "Run_Minimal_Server" for more details.
*/
var mqttServerFactory = new MqttServerFactory();
// This certificate is self signed so that
var certificate = CreateSelfSignedCertificate("1.3.6.1.5.5.7.3.1");
var mqttServerOptions = new MqttServerOptionsBuilder().WithEncryptionCertificate(certificate).WithEncryptedEndpoint().Build();
using var mqttServer = mqttServerFactory.CreateMqttServer(mqttServerOptions);
await mqttServer.StartAsync();
Console.WriteLine("Press Enter to exit.");
Console.ReadLine();
// Stop and dispose the MQTT server if it is no longer needed!
await mqttServer.StopAsync();
}
static X509Certificate2 CreateSelfSignedCertificate(string oid)
{
var sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddIpAddress(IPAddress.Loopback);
sanBuilder.AddIpAddress(IPAddress.IPv6Loopback);
sanBuilder.AddDnsName("localhost");
using var rsa = RSA.Create();
var certRequest = new CertificateRequest("CN=localhost", rsa, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
certRequest.CertificateExtensions.Add(
new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature, false));
certRequest.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new(oid) }, false));
certRequest.CertificateExtensions.Add(sanBuilder.Build());
using var certificate = certRequest.CreateSelfSigned(DateTimeOffset.Now.AddMinutes(-10), DateTimeOffset.Now.AddMinutes(10));
var pfxCertificate = new X509Certificate2(
certificate.Export(X509ContentType.Pfx),
(string)null!,
X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
return pfxCertificate;
}
}
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<IsPackable>false</IsPackable>
<DisableImplicitAspNetCoreAnalyzers>true</DisableImplicitAspNetCoreAnalyzers>
<EnableNETAnalyzers>false</EnableNETAnalyzers>
<EnforceCodeStyleInBuild>false</EnforceCodeStyleInBuild>
<NoWarn>1591;NETSDK1138;NU1803;NU1901;NU1902</NoWarn>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NuGetAuditMode>all</NuGetAuditMode>
<NuGetAudit>true</NuGetAudit>
<NuGetAuditLevel>low</NuGetAuditLevel>
<AnalysisLevel>latest-Recommended</AnalysisLevel>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Source\MQTTnet.AspnetCore\MQTTnet.AspNetCore.csproj"/>
<ProjectReference Include="..\..\Source\MQTTnet.Server\MQTTnet.Server.csproj"/>
<ProjectReference Include="..\MQTTnet\MQTTnet.csproj"/>
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\"/>
</ItemGroup>
</Project>
@@ -0,0 +1,34 @@
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div>
<h1>MQTTnet ASP.NET Core Test App</h1>
</div>
<script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
<script>
const options = {
clean: true,
connectTimeout: 4000,
clientId: 'mqttnet_web_client'
}
const client = mqtt.connect('ws://localhost:5000/mqtt')
client.on('connect', function () {
console.log('Connected')
client.subscribe('#', function (err) {
if (!err) {
client.publish('test', 'Hello mqtt')
}
})
})
client.on('message', function (topic, message) {
console.log(message.toString())
})
</script>
@@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace MQTTnet.AspTestApp.Pages;
public class IndexModel : PageModel
{
readonly ILogger<IndexModel> _logger;
public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public void OnGet()
{
_logger.LogDebug("OnGet");
}
}
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MQTTnet</title>
</head>
<body>
@RenderBody()
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
@@ -0,0 +1,2 @@
@namespace MQTTnet.AspTestApp.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}
+70
View File
@@ -0,0 +1,70 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using MQTTnet;
using MQTTnet.AspNetCore;
using MQTTnet.Server;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
// Setup MQTT stuff.
builder.Services.AddMqttServer();
builder.Services.AddConnections();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
// Setup MQTT stuff.
app.MapMqtt("/mqtt");
app.UseMqttServer(server =>
{
server.StartedAsync += args =>
{
_ = Task.Run(async () =>
{
var mqttApplicationMessage = new MqttApplicationMessageBuilder()
.WithPayload("Test application message from MQTTnet server.")
.WithTopic("message")
.Build();
while (true)
{
try
{
await server.InjectApplicationMessage(new InjectedMqttApplicationMessage(mqttApplicationMessage)
{
SenderClientId = "server"
});
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
await Task.Delay(TimeSpan.FromSeconds(5));
}
}
});
return Task.CompletedTask;
};
});
app.Run();
@@ -0,0 +1,9 @@
{
"DetailedErrors": true,
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
+5
View File
@@ -0,0 +1,5 @@
{
"version": "1.0",
"defaultProvider": "cdnjs",
"libraries": []
}
@@ -1,18 +1,23 @@
using System;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using MQTTnet.Server;
using System.Collections.Generic;
namespace MQTTnet.AspNetCore
namespace MQTTnet.AspNetCore;
public static class ApplicationBuilderExtensions
{
public static class ApplicationBuilderExtensions
[Obsolete(
"This class is obsolete and will be removed in a future version. The recommended alternative is to use MapMqtt inside Microsoft.AspNetCore.Builder.UseEndpoints(...).")]
public static IApplicationBuilder UseMqttEndpoint(this IApplicationBuilder app, string path = "/mqtt")
{
public static IApplicationBuilder UseMqttEndpoint(this IApplicationBuilder app, string path = "/mqtt")
{
app.UseWebSockets();
app.Use(async (context, next) =>
app.UseWebSockets();
app.Use(
async (context, next) =>
{
if (!context.WebSockets.IsWebSocketRequest || context.Request.Path != path)
{
@@ -24,34 +29,23 @@ namespace MQTTnet.AspNetCore
if (context.Request.Headers.TryGetValue("Sec-WebSocket-Protocol", out var requestedSubProtocolValues))
{
subProtocol = SelectSubProtocol(requestedSubProtocolValues);
subProtocol = MqttSubProtocolSelector.SelectSubProtocol(requestedSubProtocolValues);
}
var adapter = app.ApplicationServices.GetRequiredService<MqttWebSocketServerAdapter>();
using (var webSocket = await context.WebSockets.AcceptWebSocketAsync(subProtocol).ConfigureAwait(false))
{
await adapter.RunWebSocketConnectionAsync(webSocket, context);
}
using var webSocket = await context.WebSockets.AcceptWebSocketAsync(subProtocol).ConfigureAwait(false);
await adapter.RunWebSocketConnectionAsync(webSocket, context);
});
return app;
}
public static string SelectSubProtocol(IList<string> requestedSubProtocolValues)
{
// Order the protocols to also match "mqtt", "mqttv-3.1", "mqttv-3.11" etc.
return requestedSubProtocolValues
.OrderByDescending(p => p.Length)
.FirstOrDefault(p => p.ToLower().StartsWith("mqtt"));
}
public static IApplicationBuilder UseMqttServer(this IApplicationBuilder app, Action<IMqttServer> configure)
{
var server = app.ApplicationServices.GetRequiredService<IMqttServer>();
configure(server);
return app;
}
return app;
}
}
public static IApplicationBuilder UseMqttServer(this IApplicationBuilder app, Action<MqttServer> configure)
{
var server = app.ApplicationServices.GetRequiredService<MqttServer>();
configure(server);
return app;
}
}
@@ -1,15 +1,18 @@
using MQTTnet.Server;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using MQTTnet.Server;
namespace MQTTnet.AspNetCore
namespace MQTTnet.AspNetCore;
public sealed class AspNetMqttServerOptionsBuilder : MqttServerOptionsBuilder
{
public class AspNetMqttServerOptionsBuilder : MqttServerOptionsBuilder
public AspNetMqttServerOptionsBuilder(IServiceProvider serviceProvider)
{
public AspNetMqttServerOptionsBuilder(IServiceProvider serviceProvider)
{
ServiceProvider = serviceProvider;
}
public IServiceProvider ServiceProvider { get; }
ServiceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
}
}
public IServiceProvider ServiceProvider { get; }
}
@@ -0,0 +1,21 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
namespace MQTTnet.AspNetCore;
public static class BufferExtensions
{
public static ArraySegment<byte> GetArray(this ReadOnlyMemory<byte> memory)
{
if (!MemoryMarshal.TryGetArray(memory, out var result))
{
throw new InvalidOperationException("Buffer backed by array was expected");
}
return result;
}
}
@@ -1,36 +0,0 @@
using System;
using System.Net;
using MQTTnet.Adapter;
using MQTTnet.AspNetCore.Client.Tcp;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using MQTTnet.Diagnostics;
using MQTTnet.Formatter;
namespace MQTTnet.AspNetCore.Client
{
public class MqttClientConnectionContextFactory : IMqttClientAdapterFactory
{
public IMqttChannelAdapter CreateClientAdapter(IMqttClientOptions options, IMqttNetChildLogger logger)
{
if (options == null) throw new ArgumentNullException(nameof(options));
switch (options.ChannelOptions)
{
case MqttClientTcpOptions tcpOptions:
{
var endpoint = new DnsEndPoint(tcpOptions.Server, tcpOptions.GetPort());
var tcpConnection = new TcpConnection(endpoint);
var writer = new SpanBasedMqttPacketWriter();
var formatter = new MqttPacketFormatterAdapter(options.ProtocolVersion, writer);
return new MqttConnectionContext(formatter, tcpConnection);
}
default:
{
throw new NotSupportedException();
}
}
}
}
}
@@ -1,22 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace MQTTnet.AspNetCore.Client.Tcp
{
public static class BufferExtensions
{
public static ArraySegment<byte> GetArray(this Memory<byte> memory)
{
return ((ReadOnlyMemory<byte>)memory).GetArray();
}
public static ArraySegment<byte> GetArray(this ReadOnlyMemory<byte> memory)
{
if (!MemoryMarshal.TryGetArray(memory, out var result))
{
throw new InvalidOperationException("Buffer backed by array was expected");
}
return result;
}
}
}
@@ -1,41 +0,0 @@
using System.IO.Pipelines;
namespace MQTTnet.AspNetCore.Client.Tcp
{
public class DuplexPipe : IDuplexPipe
{
public DuplexPipe(PipeReader reader, PipeWriter writer)
{
Input = reader;
Output = writer;
}
public PipeReader Input { get; }
public PipeWriter Output { get; }
public static DuplexPipePair CreateConnectionPair(PipeOptions inputOptions, PipeOptions outputOptions)
{
var input = new Pipe(inputOptions);
var output = new Pipe(outputOptions);
var transportToApplication = new DuplexPipe(output.Reader, input.Writer);
var applicationToTransport = new DuplexPipe(input.Reader, output.Writer);
return new DuplexPipePair(applicationToTransport, transportToApplication);
}
// This class exists to work around issues with value tuple on .NET Framework
public readonly struct DuplexPipePair
{
public IDuplexPipe Transport { get; }
public IDuplexPipe Application { get; }
public DuplexPipePair(IDuplexPipe transport, IDuplexPipe application)
{
Transport = transport;
Application = application;
}
}
}
}
@@ -1,70 +0,0 @@
using System;
using System.Diagnostics;
using System.IO.Pipelines;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace MQTTnet.AspNetCore.Client.Tcp
{
public class SocketAwaitable : ICriticalNotifyCompletion
{
private static readonly Action _callbackCompleted = () => { };
private readonly PipeScheduler _ioScheduler;
private Action _callback;
private int _bytesTransferred;
private SocketError _error;
public SocketAwaitable(PipeScheduler ioScheduler)
{
_ioScheduler = ioScheduler;
}
public bool IsCompleted => ReferenceEquals(_callback, _callbackCompleted);
public SocketAwaitable GetAwaiter() => this;
public int GetResult()
{
Debug.Assert(ReferenceEquals(_callback, _callbackCompleted));
_callback = null;
if (_error != SocketError.Success)
{
throw new SocketException((int)_error);
}
return _bytesTransferred;
}
public void OnCompleted(Action continuation)
{
if (ReferenceEquals(_callback, _callbackCompleted) ||
ReferenceEquals(Interlocked.CompareExchange(ref _callback, continuation, null), _callbackCompleted))
{
Task.Run(continuation);
}
}
public void UnsafeOnCompleted(Action continuation)
{
OnCompleted(continuation);
}
public void Complete(int bytesTransferred, SocketError socketError)
{
_error = socketError;
_bytesTransferred = bytesTransferred;
var continuation = Interlocked.Exchange(ref _callback, _callbackCompleted);
if (continuation != null)
{
_ioScheduler.Schedule(state => ((Action)state)(), continuation);
}
}
}
}
@@ -1,37 +0,0 @@
using System;
using System.IO.Pipelines;
using System.Net.Sockets;
namespace MQTTnet.AspNetCore.Client.Tcp
{
public class SocketReceiver
{
private readonly Socket _socket;
private readonly SocketAsyncEventArgs _eventArgs = new SocketAsyncEventArgs();
private readonly SocketAwaitable _awaitable;
public SocketReceiver(Socket socket, PipeScheduler scheduler)
{
_socket = socket;
_awaitable = new SocketAwaitable(scheduler);
_eventArgs.UserToken = _awaitable;
_eventArgs.Completed += (_, e) => ((SocketAwaitable)e.UserToken).Complete(e.BytesTransferred, e.SocketError);
}
public SocketAwaitable ReceiveAsync(Memory<byte> buffer)
{
#if NETCOREAPP2_1
_eventArgs.SetBuffer(buffer);
#else
var segment = buffer.GetArray();
_eventArgs.SetBuffer(segment.Array, segment.Offset, segment.Count);
#endif
if (!_socket.ReceiveAsync(_eventArgs))
{
_awaitable.Complete(_eventArgs.BytesTransferred, _eventArgs.SocketError);
}
return _awaitable;
}
}
}
@@ -1,101 +0,0 @@
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Pipelines;
using System.Net.Sockets;
#if NETCOREAPP2_1
using System.Runtime.InteropServices;
#endif
namespace MQTTnet.AspNetCore.Client.Tcp
{
public class SocketSender
{
private readonly Socket _socket;
private readonly SocketAsyncEventArgs _eventArgs = new SocketAsyncEventArgs();
private readonly SocketAwaitable _awaitable;
private List<ArraySegment<byte>> _bufferList;
public SocketSender(Socket socket, PipeScheduler scheduler)
{
_socket = socket;
_awaitable = new SocketAwaitable(scheduler);
_eventArgs.UserToken = _awaitable;
_eventArgs.Completed += (_, e) => ((SocketAwaitable)e.UserToken).Complete(e.BytesTransferred, e.SocketError);
}
public SocketAwaitable SendAsync(in ReadOnlySequence<byte> buffers)
{
if (buffers.IsSingleSegment)
{
return SendAsync(buffers.First);
}
#if NETCOREAPP2_1
if (!_eventArgs.MemoryBuffer.Equals(Memory<byte>.Empty))
#else
if (_eventArgs.Buffer != null)
#endif
{
_eventArgs.SetBuffer(null, 0, 0);
}
_eventArgs.BufferList = GetBufferList(buffers);
if (!_socket.SendAsync(_eventArgs))
{
_awaitable.Complete(_eventArgs.BytesTransferred, _eventArgs.SocketError);
}
return _awaitable;
}
private SocketAwaitable SendAsync(ReadOnlyMemory<byte> memory)
{
// The BufferList getter is much less expensive then the setter.
if (_eventArgs.BufferList != null)
{
_eventArgs.BufferList = null;
}
#if NETCOREAPP2_1
_eventArgs.SetBuffer(MemoryMarshal.AsMemory(memory));
#else
var segment = memory.GetArray();
_eventArgs.SetBuffer(segment.Array, segment.Offset, segment.Count);
#endif
if (!_socket.SendAsync(_eventArgs))
{
_awaitable.Complete(_eventArgs.BytesTransferred, _eventArgs.SocketError);
}
return _awaitable;
}
private List<ArraySegment<byte>> GetBufferList(in ReadOnlySequence<byte> buffer)
{
Debug.Assert(!buffer.IsEmpty);
Debug.Assert(!buffer.IsSingleSegment);
if (_bufferList == null)
{
_bufferList = new List<ArraySegment<byte>>();
}
else
{
// Buffers are pooled, so it's OK to root them until the next multi-buffer write.
_bufferList.Clear();
}
foreach (var b in buffer)
{
_bufferList.Add(b.GetArray());
}
return _bufferList;
}
}
}
@@ -1,258 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipelines;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Http.Features;
using MQTTnet.Exceptions;
namespace MQTTnet.AspNetCore.Client.Tcp
{
public class TcpConnection : ConnectionContext
{
private volatile bool _aborted;
private readonly EndPoint _endPoint;
private SocketSender _sender;
private SocketReceiver _receiver;
private Socket _socket;
private IDuplexPipe _application;
public bool IsConnected { get; private set; }
public override string ConnectionId { get; set; }
public override IFeatureCollection Features { get; }
public override IDictionary<object, object> Items { get; set; }
public override IDuplexPipe Transport { get; set; }
public TcpConnection(EndPoint endPoint)
{
_endPoint = endPoint;
}
public TcpConnection(Socket socket)
{
_socket = socket;
_endPoint = socket.RemoteEndPoint;
_sender = new SocketSender(_socket, PipeScheduler.ThreadPool);
_receiver = new SocketReceiver(_socket, PipeScheduler.ThreadPool);
}
public Task DisposeAsync()
{
IsConnected = false;
Transport?.Output.Complete();
Transport?.Input.Complete();
_socket?.Dispose();
return Task.CompletedTask;
}
public async Task StartAsync()
{
if (_socket == null)
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_sender = new SocketSender(_socket, PipeScheduler.ThreadPool);
_receiver = new SocketReceiver(_socket, PipeScheduler.ThreadPool);
await _socket.ConnectAsync(_endPoint);
}
var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
Transport = pair.Transport;
_application = pair.Application;
_ = ExecuteAsync();
IsConnected = true;
}
private async Task ExecuteAsync()
{
Exception sendError = null;
try
{
// Spawn send and receive logic
var receiveTask = DoReceive();
var sendTask = DoSend();
// If the sending task completes then close the receive
// We don't need to do this in the other direction because the kestrel
// will trigger the output closing once the input is complete.
if (await Task.WhenAny(receiveTask, sendTask) == sendTask)
{
// Tell the reader it's being aborted
_socket.Dispose();
}
// Now wait for both to complete
await receiveTask;
sendError = await sendTask;
// Dispose the socket(should noop if already called)
_socket.Dispose();
}
catch (Exception ex)
{
Console.WriteLine($"Unexpected exception in {nameof(TcpConnection)}.{nameof(StartAsync)}: " + ex);
}
finally
{
// Complete the output after disposing the socket
_application.Input.Complete(sendError);
}
}
private async Task DoReceive()
{
Exception error = null;
try
{
await ProcessReceives();
}
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.ConnectionReset)
{
error = new MqttCommunicationException(ex);
}
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.OperationAborted ||
ex.SocketErrorCode == SocketError.ConnectionAborted ||
ex.SocketErrorCode == SocketError.Interrupted ||
ex.SocketErrorCode == SocketError.InvalidArgument)
{
if (!_aborted)
{
// Calling Dispose after ReceiveAsync can cause an "InvalidArgument" error on *nix.
error = ConnectionAborted();
}
}
catch (ObjectDisposedException)
{
if (!_aborted)
{
error = ConnectionAborted();
}
}
catch (IOException ex)
{
error = ex;
}
catch (Exception ex)
{
error = new IOException(ex.Message, ex);
}
finally
{
if (_aborted)
{
error = error ?? ConnectionAborted();
}
_application.Output.Complete(error);
}
}
private async Task ProcessReceives()
{
while (true)
{
// Ensure we have some reasonable amount of buffer space
var buffer = _application.Output.GetMemory();
var bytesReceived = await _receiver.ReceiveAsync(buffer);
if (bytesReceived == 0)
{
// FIN
break;
}
_application.Output.Advance(bytesReceived);
var flushTask = _application.Output.FlushAsync();
if (!flushTask.IsCompleted)
{
await flushTask;
}
var result = flushTask.GetAwaiter().GetResult();
if (result.IsCompleted)
{
// Pipe consumer is shut down, do we stop writing
break;
}
}
}
private Exception ConnectionAborted()
{
return new MqttCommunicationException("Connection Aborted");
}
private async Task<Exception> DoSend()
{
Exception error = null;
try
{
await ProcessSends();
}
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.OperationAborted)
{
}
catch (ObjectDisposedException)
{
}
catch (IOException ex)
{
error = ex;
}
catch (Exception ex)
{
error = new IOException(ex.Message, ex);
}
finally
{
_aborted = true;
_socket.Shutdown(SocketShutdown.Both);
}
return error;
}
private async Task ProcessSends()
{
while (true)
{
// Wait for data to write from the pipe producer
var result = await _application.Input.ReadAsync();
var buffer = result.Buffer;
if (result.IsCanceled)
{
break;
}
var end = buffer.End;
var isCompleted = result.IsCompleted;
if (!buffer.IsEmpty)
{
await _sender.SendAsync(buffer);
}
_application.Input.AdvanceTo(end);
if (isCompleted)
{
break;
}
}
}
}
}
@@ -1,12 +1,15 @@
using Microsoft.AspNetCore.Connections;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace MQTTnet.AspNetCore
using Microsoft.AspNetCore.Connections;
namespace MQTTnet.AspNetCore;
public static class ConnectionBuilderExtensions
{
public static class ConnectionBuilderExtensions
public static IConnectionBuilder UseMqtt(this IConnectionBuilder builder)
{
public static IConnectionBuilder UseMqtt(this IConnectionBuilder builder)
{
return builder.UseConnectionHandler<MqttConnectionHandler>();
}
return builder.UseConnectionHandler<MqttConnectionHandler>();
}
}
}
+44
View File
@@ -0,0 +1,44 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.IO.Pipelines;
namespace MQTTnet.AspNetCore;
public class DuplexPipe : IDuplexPipe
{
public DuplexPipe(PipeReader reader, PipeWriter writer)
{
Input = reader;
Output = writer;
}
public PipeReader Input { get; }
public PipeWriter Output { get; }
public static DuplexPipePair CreateConnectionPair(PipeOptions inputOptions, PipeOptions outputOptions)
{
var input = new Pipe(inputOptions);
var output = new Pipe(outputOptions);
var transportToApplication = new DuplexPipe(output.Reader, input.Writer);
var applicationToTransport = new DuplexPipe(input.Reader, output.Writer);
return new DuplexPipePair(applicationToTransport, transportToApplication);
}
// This class exists to work around issues with value tuple on .NET Framework
public readonly struct DuplexPipePair
{
public IDuplexPipe Transport { get; }
public IDuplexPipe Application { get; }
public DuplexPipePair(IDuplexPipe transport, IDuplexPipe application)
{
Transport = transport;
Application = application;
}
}
}
@@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
namespace MQTTnet.AspNetCore;
public static class EndpointRouterExtensions
{
public static void MapMqtt(this IEndpointRouteBuilder endpoints, string pattern)
{
ArgumentNullException.ThrowIfNull(endpoints);
endpoints.MapConnectionHandler<MqttConnectionHandler>(pattern, options =>
{
options.WebSockets.SubProtocolSelector = MqttSubProtocolSelector.SelectSubProtocol;
});
}
}
@@ -1,28 +1,64 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netcoreapp2.1</TargetFrameworks>
<Product />
<Company />
<Authors />
<PackageId />
<LangVersion>7.2</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AssemblyName>MQTTnet.AspNetCore</AssemblyName>
<RootNamespace>MQTTnet.AspNetCore</RootNamespace>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Company>The contributors of MQTTnet</Company>
<Product>MQTTnet</Product>
<Description>MQTTnet is a high performance .NET library for MQTT based communication. It provides a MQTT client and a MQTT server (broker) and supports v3.1.0, v3.1.1 and v5.0.0 of the MQTT protocol.</Description>
<Authors>The contributors of MQTTnet</Authors>
<PackageId>MQTTnet.AspNetCore</PackageId>
<SignAssembly>false</SignAssembly>
<DelaySign>false</DelaySign>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<Copyright>Copyright (c) .NET Foundation and Contributors</Copyright>
<PackageProjectUrl>https://github.com/dotnet/MQTTnet</PackageProjectUrl>
<RepositoryUrl>https://github.com/dotnet/MQTTnet.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>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 Blazor</PackageTags>
<NeutralLanguage>en-US</NeutralLanguage>
<EnableNETAnalyzers>false</EnableNETAnalyzers>
<EnforceCodeStyleInBuild>false</EnforceCodeStyleInBuild>
<PackageIcon>nuget.png</PackageIcon>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageReleaseNotes>For release notes please go to MQTTnet release notes (https://www.nuget.org/packages/MQTTnet/).</PackageReleaseNotes>
<DisableImplicitAspNetCoreAnalyzers>true</DisableImplicitAspNetCoreAnalyzers>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>1591;NETSDK1138;NU1803;NU1901;NU1902</NoWarn>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NuGetAuditMode>all</NuGetAuditMode>
<NuGetAudit>true</NuGetAudit>
<NuGetAuditLevel>low</NuGetAuditLevel>
<NuGetAuditLevel>low</NuGetAuditLevel>
<AnalysisLevel>latest-Recommended</AnalysisLevel>
<IsAotCompatible>true</IsAotCompatible>
<LangVersion>default</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DefineConstants>RELEASE;NETSTANDARD2_0</DefineConstants>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\Images\nuget.png" Pack="true" PackagePath="" />
<None Include="..\..\LICENSE" Pack="true" PackagePath="" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Connections.Abstractions" Version="2.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Http.Connections" Version="1.0.3" />
<PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="2.1.1" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All"/>
<FrameworkReference Include="Microsoft.AspNetCore.App"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MQTTnet\MQTTnet.csproj" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release'">
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\MQTTnet.Server\MQTTnet.Server.csproj"/>
<ProjectReference Include="..\MQTTnet\MQTTnet.csproj"/>
</ItemGroup>
</Project>
@@ -0,0 +1,33 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Formatter;
namespace MQTTnet.AspNetCore;
public sealed class MqttClientConnectionContextFactory : IMqttClientAdapterFactory
{
public IMqttChannelAdapter CreateClientAdapter(MqttClientOptions options, MqttPacketInspector packetInspector, IMqttNetLogger logger)
{
if (options == null) throw new ArgumentNullException(nameof(options));
switch (options.ChannelOptions)
{
case MqttClientTcpOptions tcpOptions:
{
var tcpConnection = new SocketConnection(tcpOptions.RemoteEndpoint);
var formatter = new MqttPacketFormatterAdapter(options.ProtocolVersion, new MqttBufferWriter(4096, 65535));
return new MqttConnectionContext(formatter, tcpConnection);
}
default:
{
throw new NotSupportedException();
}
}
}
}
+229 -162
View File
@@ -1,172 +1,239 @@
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Http.Connections.Features;
using MQTTnet.Adapter;
using MQTTnet.AspNetCore.Client.Tcp;
using MQTTnet.Exceptions;
using MQTTnet.Formatter;
using MQTTnet.Packets;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Buffers;
using System.IO.Pipelines;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Http.Connections.Features;
using Microsoft.AspNetCore.Http.Features;
using MQTTnet.Adapter;
using MQTTnet.Exceptions;
using MQTTnet.Formatter;
using MQTTnet.Internal;
using MQTTnet.Packets;
namespace MQTTnet.AspNetCore
namespace MQTTnet.AspNetCore;
public sealed class MqttConnectionContext : IMqttChannelAdapter
{
public class MqttConnectionContext : IMqttChannelAdapter
readonly ConnectionContext _connection;
readonly AsyncLock _writerLock = new();
PipeReader _input;
PipeWriter _output;
public MqttConnectionContext(MqttPacketFormatterAdapter packetFormatterAdapter, ConnectionContext connection)
{
public MqttConnectionContext(MqttPacketFormatterAdapter packetFormatterAdapter, ConnectionContext connection)
{
PacketFormatterAdapter = packetFormatterAdapter ?? throw new ArgumentNullException(nameof(packetFormatterAdapter));
Connection = connection ?? throw new ArgumentNullException(nameof(connection));
if (Connection.Transport != null)
{
_input = Connection.Transport.Input;
_output = Connection.Transport.Output;
}
_reader = new SpanBasedMqttPacketBodyReader();
}
private PipeReader _input;
private PipeWriter _output;
private readonly SpanBasedMqttPacketBodyReader _reader;
public string Endpoint
{
get
{
var connection = Http?.HttpContext?.Connection;
if (connection == null)
{
return Connection.ConnectionId;
}
return $"{connection.RemoteIpAddress}:{connection.RemotePort}";
}
}
public bool IsSecureConnection => Http?.HttpContext?.Request?.IsHttps ?? false;
private IHttpContextFeature Http => Connection.Features.Get<IHttpContextFeature>();
public ConnectionContext Connection { get; }
public MqttPacketFormatterAdapter PacketFormatterAdapter { get; }
public long BytesSent { get; set; }
public long BytesReceived { get; set; }
public Action ReadingPacketStartedCallback { get; set; }
public Action ReadingPacketCompletedCallback { get; set; }
private readonly SemaphoreSlim _writerSemaphore = new SemaphoreSlim(1, 1);
public async Task ConnectAsync(TimeSpan timeout, CancellationToken cancellationToken)
{
if (Connection is TcpConnection tcp && !tcp.IsConnected)
{
await tcp.StartAsync().ConfigureAwait(false);
}
_input = Connection.Transport.Input;
_output = Connection.Transport.Output;
}
public Task DisconnectAsync(TimeSpan timeout, CancellationToken cancellationToken)
{
_input?.Complete();
_output?.Complete();
return Task.CompletedTask;
}
public async Task<MqttBasePacket> ReceivePacketAsync(TimeSpan timeout, CancellationToken cancellationToken)
{
var input = Connection.Transport.Input;
try
{
while (!cancellationToken.IsCancellationRequested)
{
ReadResult readResult;
var readTask = input.ReadAsync(cancellationToken);
if (readTask.IsCompleted)
{
readResult = readTask.Result;
}
else
{
readResult = await readTask.ConfigureAwait(false);
}
var buffer = readResult.Buffer;
var consumed = buffer.Start;
var observed = buffer.Start;
try
{
if (!buffer.IsEmpty)
{
if (PacketFormatterAdapter.TryDecode(_reader, buffer, out var packet, out consumed, out observed, out var received))
{
BytesReceived += received;
return packet;
}
else
{
// we did receive something but the message is not yet complete
ReadingPacketStartedCallback?.Invoke();
}
}
else if (readResult.IsCompleted)
{
throw new MqttCommunicationException("Connection Aborted");
}
}
finally
{
// The buffer was sliced up to where it was consumed, so we can just advance to the start.
// We mark examined as buffer.End so that if we didn't receive a full frame, we'll wait for more data
// before yielding the read again.
input.AdvanceTo(consumed, observed);
}
}
}
finally
{
ReadingPacketCompletedCallback?.Invoke();
}
cancellationToken.ThrowIfCancellationRequested();
return null;
}
public async Task SendPacketAsync(MqttBasePacket packet, TimeSpan timeout, CancellationToken cancellationToken)
{
var formatter = PacketFormatterAdapter;
await _writerSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
var buffer = formatter.Encode(packet);
var msg = buffer.AsMemory();
var output = _output;
msg.CopyTo(output.GetMemory(msg.Length));
BytesSent += msg.Length;
PacketFormatterAdapter.FreeBuffer();
output.Advance(msg.Length);
await output.FlushAsync().ConfigureAwait(false);
}
finally
{
_writerSemaphore.Release();
}
}
public void Dispose()
PacketFormatterAdapter = packetFormatterAdapter ?? throw new ArgumentNullException(nameof(packetFormatterAdapter));
_connection = connection ?? throw new ArgumentNullException(nameof(connection));
if (!(_connection is SocketConnection tcp) || tcp.IsConnected)
{
_input = connection.Transport.Input;
_output = connection.Transport.Output;
}
}
}
public long BytesReceived { get; private set; }
public long BytesSent { get; private set; }
public X509Certificate2 ClientCertificate
{
get
{
// mqtt over tcp
var tlsFeature = _connection.Features.Get<ITlsConnectionFeature>();
if (tlsFeature != null)
{
return tlsFeature.ClientCertificate;
}
// mqtt over websocket
var httpFeature = _connection.Features.Get<IHttpContextFeature>();
return httpFeature?.HttpContext?.Connection.ClientCertificate;
}
}
public EndPoint RemoteEndPoint
{
get
{
// mqtt over tcp
if (_connection.RemoteEndPoint != null)
{
return _connection.RemoteEndPoint;
}
// mqtt over websocket
var httpFeature = _connection.Features.Get<IHttpConnectionFeature>();
if (httpFeature?.RemoteIpAddress != null)
{
return new IPEndPoint(httpFeature.RemoteIpAddress, httpFeature.RemotePort);
}
return null;
}
}
public bool IsSecureConnection
{
get
{
// mqtt over tcp
var tlsFeature = _connection.Features.Get<ITlsConnectionFeature>();
if (tlsFeature != null)
{
return true;
}
// mqtt over websocket
var httpFeature = _connection.Features.Get<IHttpContextFeature>();
if (httpFeature?.HttpContext != null)
{
return httpFeature.HttpContext.Request.IsHttps;
}
return false;
}
}
public MqttPacketFormatterAdapter PacketFormatterAdapter { get; }
public async Task ConnectAsync(CancellationToken cancellationToken)
{
if (_connection is SocketConnection tcp && !tcp.IsConnected)
{
await tcp.StartAsync().ConfigureAwait(false);
}
_input = _connection.Transport.Input;
_output = _connection.Transport.Output;
}
public Task DisconnectAsync(CancellationToken cancellationToken)
{
_input?.Complete();
_output?.Complete();
return Task.CompletedTask;
}
public void Dispose()
{
_writerLock.Dispose();
}
public async Task<MqttPacket> ReceivePacketAsync(CancellationToken cancellationToken)
{
try
{
while (!cancellationToken.IsCancellationRequested)
{
ReadResult readResult;
var readTask = _input.ReadAsync(cancellationToken);
if (readTask.IsCompleted)
{
readResult = readTask.Result;
}
else
{
readResult = await readTask.ConfigureAwait(false);
}
var buffer = readResult.Buffer;
var consumed = buffer.Start;
var observed = buffer.Start;
try
{
if (!buffer.IsEmpty)
{
if (PacketFormatterAdapter.TryDecode(buffer, out var packet, out consumed, out observed, out var received))
{
BytesReceived += received;
return packet;
}
}
else if (readResult.IsCompleted)
{
throw new MqttCommunicationException("Connection Aborted");
}
}
finally
{
// The buffer was sliced up to where it was consumed, so we can just advance to the start.
// We mark examined as buffer.End so that if we didn't receive a full frame, we'll wait for more data
// before yielding the read again.
_input.AdvanceTo(consumed, observed);
}
}
}
catch (Exception exception)
{
// completing the channel makes sure that there is no more data read after a protocol error
_input?.Complete(exception);
_output?.Complete(exception);
throw;
}
cancellationToken.ThrowIfCancellationRequested();
return null;
}
public void ResetStatistics()
{
BytesReceived = 0;
BytesSent = 0;
}
public async Task SendPacketAsync(MqttPacket packet, CancellationToken cancellationToken)
{
using (await _writerLock.EnterAsync(cancellationToken).ConfigureAwait(false))
{
try
{
var buffer = PacketFormatterAdapter.Encode(packet);
if (buffer.Payload.Length == 0)
{
// zero copy
// https://github.com/dotnet/runtime/blob/e31ddfdc4f574b26231233dc10c9a9c402f40590/src/libraries/System.IO.Pipelines/src/System/IO/Pipelines/StreamPipeWriter.cs#L279
await _output.WriteAsync(buffer.Packet, cancellationToken).ConfigureAwait(false);
}
else
{
WritePacketBuffer(_output, buffer);
await _output.FlushAsync(cancellationToken).ConfigureAwait(false);
}
BytesSent += buffer.Length;
}
finally
{
PacketFormatterAdapter.Cleanup();
}
}
}
static void WritePacketBuffer(PipeWriter output, MqttPacketBuffer buffer)
{
// copy MqttPacketBuffer's Packet and Payload to the same buffer block of PipeWriter
// MqttPacket will be transmitted within the bounds of a WebSocket frame after PipeWriter.FlushAsync
var span = output.GetSpan(buffer.Length);
buffer.Packet.AsSpan().CopyTo(span);
int offset = buffer.Packet.Count;
buffer.Payload.CopyTo(destination: span.Slice(offset));
output.Advance(buffer.Length);
}
}
@@ -1,50 +1,55 @@
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Connections.Features;
using MQTTnet.Adapter;
using MQTTnet.Server;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Connections.Features;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Formatter;
using MQTTnet.Server;
namespace MQTTnet.AspNetCore
namespace MQTTnet.AspNetCore;
public sealed class MqttConnectionHandler : ConnectionHandler, IMqttServerAdapter
{
public class MqttConnectionHandler : ConnectionHandler, IMqttServerAdapter
MqttServerOptions _serverOptions;
public Func<IMqttChannelAdapter, Task> ClientHandler { get; set; }
public void Dispose()
{
public Func<IMqttChannelAdapter, Task> ClientHandler { get; set; }
}
public override async Task OnConnectedAsync(ConnectionContext connection)
public override async Task OnConnectedAsync(ConnectionContext connection)
{
// required for websocket transport to work
var transferFormatFeature = connection.Features.Get<ITransferFormatFeature>();
if (transferFormatFeature != null)
{
// required for websocket transport to work
var transferFormatFeature = connection.Features.Get<ITransferFormatFeature>();
if (transferFormatFeature != null)
{
transferFormatFeature.ActiveFormat = TransferFormat.Binary;
}
var writer = new SpanBasedMqttPacketWriter();
var formatter = new MqttPacketFormatterAdapter(writer);
using (var adapter = new MqttConnectionContext(formatter, connection))
{
var clientHandler = ClientHandler;
if (clientHandler != null)
{
await clientHandler(adapter).ConfigureAwait(false);
}
}
transferFormatFeature.ActiveFormat = TransferFormat.Binary;
}
public Task StartAsync(IMqttServerOptions options)
{
return Task.CompletedTask;
}
public Task StopAsync()
{
return Task.CompletedTask;
}
public void Dispose()
var formatter = new MqttPacketFormatterAdapter(new MqttBufferWriter(_serverOptions.WriterBufferSize, _serverOptions.WriterBufferSizeMax));
using var adapter = new MqttConnectionContext(formatter, connection);
var clientHandler = ClientHandler;
if (clientHandler != null)
{
await clientHandler(adapter).ConfigureAwait(false);
}
}
}
public Task StartAsync(MqttServerOptions options, IMqttNetLogger logger)
{
_serverOptions = options;
return Task.CompletedTask;
}
public Task StopAsync()
{
return Task.CompletedTask;
}
}
+39 -23
View File
@@ -1,32 +1,48 @@
using System;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Server;
namespace MQTTnet.AspNetCore
namespace MQTTnet.AspNetCore;
public sealed class MqttHostedServer : MqttServer, IHostedService
{
public class MqttHostedServer : MqttServer, IHostedService
readonly IHostApplicationLifetime _hostApplicationLifetime;
readonly MqttServerFactory _mqttFactory;
public MqttHostedServer(
IHostApplicationLifetime hostApplicationLifetime,
MqttServerFactory mqttFactory,
MqttServerOptions options,
IEnumerable<IMqttServerAdapter> adapters,
IMqttNetLogger logger) : base(options, adapters, logger)
{
private readonly IMqttServerOptions _options;
public MqttHostedServer(IMqttServerOptions options, IEnumerable<IMqttServerAdapter> adapters, IMqttNetLogger logger)
: base(adapters, logger.CreateChildLogger(nameof(MqttHostedServer)))
{
_options = options ?? throw new ArgumentNullException(nameof(options));
}
public Task StartAsync(CancellationToken cancellationToken)
{
return StartAsync(_options);
}
public Task StopAsync(CancellationToken cancellationToken)
{
return StopAsync();
}
_mqttFactory = mqttFactory ?? throw new ArgumentNullException(nameof(mqttFactory));
_hostApplicationLifetime = hostApplicationLifetime;
}
}
public async Task StartAsync(CancellationToken cancellationToken)
{
// The yield makes sure that the hosted service is considered up and running.
await Task.Yield();
_hostApplicationLifetime.ApplicationStarted.Register(OnStarted);
}
public Task StopAsync(CancellationToken cancellationToken)
{
return StopAsync(_mqttFactory.CreateMqttServerStopOptionsBuilder().Build());
}
void OnStarted()
{
_ = StartAsync();
}
}
@@ -0,0 +1,34 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Http;
namespace MQTTnet.AspNetCore;
public static class MqttSubProtocolSelector
{
public static string SelectSubProtocol(HttpRequest request)
{
ArgumentNullException.ThrowIfNull(request);
string subProtocol = null;
if (request.Headers.TryGetValue("Sec-WebSocket-Protocol", out var requestedSubProtocolValues))
{
subProtocol = SelectSubProtocol(requestedSubProtocolValues);
}
return subProtocol;
}
public static string SelectSubProtocol(IList<string> requestedSubProtocolValues)
{
ArgumentNullException.ThrowIfNull(requestedSubProtocolValues);
// Order the protocols to also match "mqtt", "mqttv-3.1", "mqttv-3.11" etc.
return requestedSubProtocolValues.OrderByDescending(p => p.Length).FirstOrDefault(p => p.ToLower().StartsWith("mqtt"));
}
}
@@ -1,63 +1,66 @@
using System;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Net;
using System.Net.WebSockets;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Formatter;
using MQTTnet.Implementations;
using MQTTnet.Server;
namespace MQTTnet.AspNetCore
namespace MQTTnet.AspNetCore;
public sealed class MqttWebSocketServerAdapter : IMqttServerAdapter
{
public class MqttWebSocketServerAdapter : IMqttServerAdapter
IMqttNetLogger _logger = MqttNetNullLogger.Instance;
public Func<IMqttChannelAdapter, Task> ClientHandler { get; set; }
public void Dispose()
{
private readonly IMqttNetChildLogger _logger;
}
public MqttWebSocketServerAdapter(IMqttNetChildLogger logger)
public async Task RunWebSocketConnectionAsync(WebSocket webSocket, HttpContext httpContext)
{
ArgumentNullException.ThrowIfNull(webSocket);
var remoteAddress = httpContext.Connection.RemoteIpAddress;
var remoteEndPoint = remoteAddress == null ? null : new IPEndPoint(remoteAddress, httpContext.Connection.RemotePort);
var clientCertificate = await httpContext.Connection.GetClientCertificateAsync().ConfigureAwait(false);
try
{
if (logger == null) throw new ArgumentNullException(nameof(logger));
_logger = logger.CreateChildLogger(nameof(MqttTcpServerAdapter));
}
public Func<IMqttChannelAdapter, Task> ClientHandler { get; set; }
public Task StartAsync(IMqttServerOptions options)
{
return Task.CompletedTask;
}
public Task StopAsync()
{
return Task.CompletedTask;
}
public async Task RunWebSocketConnectionAsync(WebSocket webSocket, HttpContext httpContext)
{
if (webSocket == null) throw new ArgumentNullException(nameof(webSocket));
var endpoint = $"{httpContext.Connection.RemoteIpAddress}:{httpContext.Connection.RemotePort}";
var clientCertificate = await httpContext.Connection.GetClientCertificateAsync().ConfigureAwait(false);
var isSecureConnection = clientCertificate != null;
clientCertificate?.Dispose();
var clientHandler = ClientHandler;
if (clientHandler != null)
{
var writer = new SpanBasedMqttPacketWriter();
var formatter = new MqttPacketFormatterAdapter(writer);
var channel = new MqttWebSocketChannel(webSocket, endpoint, isSecureConnection);
using (var channelAdapter = new MqttChannelAdapter(channel, formatter, _logger.CreateChildLogger(nameof(MqttWebSocketServerAdapter))))
{
await clientHandler(channelAdapter).ConfigureAwait(false);
}
var formatter = new MqttPacketFormatterAdapter(new MqttBufferWriter(4096, 65535));
var channel = new MqttWebSocketChannel(webSocket, remoteEndPoint, isSecureConnection, clientCertificate);
using var channelAdapter = new MqttChannelAdapter(channel, formatter, _logger);
await clientHandler(channelAdapter).ConfigureAwait(false);
}
}
public void Dispose()
finally
{
clientCertificate?.Dispose();
}
}
public Task StartAsync(MqttServerOptions options, IMqttNetLogger logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
return Task.CompletedTask;
}
public Task StopAsync()
{
return Task.CompletedTask;
}
}
+113 -88
View File
@@ -1,110 +1,135 @@
using System;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Buffers;
using System.Runtime.InteropServices;
using MQTTnet.Adapter;
using MQTTnet.Exceptions;
using MQTTnet.Formatter;
using MQTTnet.Packets;
namespace MQTTnet.AspNetCore
namespace MQTTnet.AspNetCore;
public static class ReaderExtensions
{
public static class ReaderExtensions
public static bool TryDecode(
this MqttPacketFormatterAdapter formatter,
in ReadOnlySequence<byte> input,
out MqttPacket packet,
out SequencePosition consumed,
out SequencePosition observed,
out int bytesRead)
{
public static bool TryDecode(this MqttPacketFormatterAdapter formatter,
SpanBasedMqttPacketBodyReader reader,
in ReadOnlySequence<byte> input,
out MqttBasePacket packet,
out SequencePosition consumed,
out SequencePosition observed,
out int bytesRead)
ArgumentNullException.ThrowIfNull(formatter);
packet = null;
consumed = input.Start;
observed = input.End;
bytesRead = 0;
var copy = input;
if (copy.Length < 2)
{
if (formatter == null) throw new ArgumentNullException(nameof(formatter));
packet = null;
consumed = input.Start;
observed = input.End;
bytesRead = 0;
var copy = input;
if (copy.Length < 2)
{
return false;
}
var fixedheader = copy.First.Span[0];
if (!TryReadBodyLength(ref copy, out int headerLength, out var bodyLength))
{
return false;
}
if (copy.Length < bodyLength)
{
return false;
}
var bodySlice = copy.Slice(0, bodyLength);
var buffer = bodySlice.GetMemory();
reader.SetBuffer(buffer);
var receivedMqttPacket = new ReceivedMqttPacket(fixedheader, reader, buffer.Length + 2);
if (formatter.ProtocolVersion == MqttProtocolVersion.Unknown)
{
formatter.DetectProtocolVersion(receivedMqttPacket);
}
packet = formatter.Decode(receivedMqttPacket);
consumed = bodySlice.End;
observed = bodySlice.End;
bytesRead = headerLength + bodyLength;
return true;
return false;
}
private static ReadOnlyMemory<byte> GetMemory(this in ReadOnlySequence<byte> input)
if (!TryReadBodyLength(ref copy, out var headerLength, out var bodyLength))
{
if (input.IsSingleSegment)
{
return input.First;
}
// Should be rare
return input.ToArray();
return false;
}
private static bool TryReadBodyLength(ref ReadOnlySequence<byte> input, out int headerLength, out int bodyLength)
var fixedHeader = copy.First.Span[0];
copy = copy.Slice(headerLength);
if (copy.Length < bodyLength)
{
// Alorithm taken from https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html.
var multiplier = 1;
var value = 0;
byte encodedByte;
var index = 1;
headerLength = 0;
bodyLength = 0;
var temp = input.Slice(0, Math.Min(5, input.Length)).GetMemory();
return false;
}
do
{
if (index == temp.Length)
{
return false;
}
encodedByte = temp.Span[index];
index++;
var bodySlice = copy.Slice(0, bodyLength);
var bodySegment = GetArraySegment(ref bodySlice);
value += (byte)(encodedByte & 127) * multiplier;
if (multiplier > 128 * 128 * 128)
{
throw new MqttProtocolViolationException($"Remaining length is invalid (Data={string.Join(",", temp.Slice(1, index).ToArray())}).");
}
var receivedMqttPacket = new ReceivedMqttPacket(fixedHeader, bodySegment, headerLength + bodyLength);
if (formatter.ProtocolVersion == MqttProtocolVersion.Unknown)
{
formatter.DetectProtocolVersion(receivedMqttPacket);
}
multiplier *= 128;
} while ((encodedByte & 128) != 0);
packet = formatter.Decode(receivedMqttPacket);
consumed = bodySlice.End;
observed = bodySlice.End;
bytesRead = headerLength + bodyLength;
return true;
}
input = input.Slice(index);
static ArraySegment<byte> GetArraySegment(ref ReadOnlySequence<byte> input)
{
if (input.IsSingleSegment && MemoryMarshal.TryGetArray(input.First, out var segment))
{
return segment;
}
headerLength = index;
bodyLength = value;
return true;
// Should be rare
var array = input.ToArray();
return new ArraySegment<byte>(array);
}
static void ThrowProtocolViolationException(ReadOnlySpan<byte> valueSpan, int index)
{
throw new MqttProtocolViolationException($"Remaining length is invalid (Data={string.Join(",", valueSpan.Slice(1, index).ToArray())}).");
}
static bool TryReadBodyLength(ref ReadOnlySequence<byte> input, out int headerLength, out int bodyLength)
{
var valueSequence = input.Slice(0, Math.Min(5, input.Length));
if (valueSequence.IsSingleSegment)
{
var valueSpan = valueSequence.FirstSpan;
return TryReadBodyLength(valueSpan, out headerLength, out bodyLength);
}
else
{
Span<byte> valueSpan = stackalloc byte[8];
valueSequence.CopyTo(valueSpan);
valueSpan = valueSpan.Slice(0, (int)valueSequence.Length);
return TryReadBodyLength(valueSpan, out headerLength, out bodyLength);
}
}
}
static bool TryReadBodyLength(ReadOnlySpan<byte> span, out int headerLength, out int bodyLength)
{
// Alorithm taken from https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html.
var multiplier = 1;
var value = 0;
byte encodedByte;
var index = 1;
headerLength = 0;
bodyLength = 0;
do
{
if (index == span.Length)
{
return false;
}
encodedByte = span[index];
index++;
value += (byte)(encodedByte & 127) * multiplier;
if (multiplier > 128 * 128 * 128)
{
ThrowProtocolViolationException(span, index);
}
multiplier *= 128;
} while ((encodedByte & 128) != 0);
headerLength = index;
bodyLength = value;
return true;
}
}
@@ -1,98 +1,109 @@
using System;
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Server;
using MQTTnet.Implementations;
using MQTTnet.Server.Internal.Adapter;
namespace MQTTnet.AspNetCore
namespace MQTTnet.AspNetCore;
public static class ServiceCollectionExtensions
{
public static class ServiceCollectionExtensions
public static IServiceCollection AddHostedMqttServer(this IServiceCollection services, MqttServerOptions options)
{
public static IServiceCollection AddHostedMqttServer(this IServiceCollection services, IMqttServerOptions options)
{
if (options == null) throw new ArgumentNullException(nameof(options));
services.AddSingleton(options);
ArgumentNullException.ThrowIfNull(services);
ArgumentNullException.ThrowIfNull(options);
services.AddHostedMqttServer();
services.AddSingleton(options);
services.AddHostedMqttServer();
return services;
}
return services;
}
public static IServiceCollection AddHostedMqttServer(this IServiceCollection services, Action<MqttServerOptionsBuilder> configure)
{
services.AddSingleton<IMqttServerOptions>(s => {
var builder = new MqttServerOptionsBuilder();
configure(builder);
return builder.Build();
});
public static IServiceCollection AddHostedMqttServer(this IServiceCollection services, Action<MqttServerOptionsBuilder> configure)
{
ArgumentNullException.ThrowIfNull(services);
services.AddHostedMqttServer();
var serverOptionsBuilder = new MqttServerOptionsBuilder();
return services;
}
configure?.Invoke(serverOptionsBuilder);
public static IServiceCollection AddHostedMqttServerWithServices(this IServiceCollection services, Action<AspNetMqttServerOptionsBuilder> configure)
{
services.AddSingleton<IMqttServerOptions>(s => {
var options = serverOptionsBuilder.Build();
return AddHostedMqttServer(services, options);
}
public static void AddHostedMqttServer(this IServiceCollection services)
{
// The user may have these services already registered.
services.TryAddSingleton<IMqttNetLogger>(MqttNetNullLogger.Instance);
services.TryAddSingleton(new MqttServerFactory());
services.AddSingleton<MqttHostedServer>();
services.AddSingleton<IHostedService>(s => s.GetService<MqttHostedServer>());
services.AddSingleton<MqttServer>(s => s.GetService<MqttHostedServer>());
}
public static IServiceCollection AddHostedMqttServerWithServices(this IServiceCollection services, Action<AspNetMqttServerOptionsBuilder> configure)
{
ArgumentNullException.ThrowIfNull(services);
services.AddSingleton(
s =>
{
var builder = new AspNetMqttServerOptionsBuilder(s);
configure(builder);
return builder.Build();
});
services.AddHostedMqttServer();
services.AddHostedMqttServer();
return services;
}
public static IServiceCollection AddHostedMqttServer<TOptions>(this IServiceCollection services)
where TOptions : class, IMqttServerOptions
{
services.AddSingleton<IMqttServerOptions, TOptions>();
services.AddHostedMqttServer();
return services;
}
private static IServiceCollection AddHostedMqttServer(this IServiceCollection services)
{
var logger = new MqttNetLogger();
var childLogger = logger.CreateChildLogger();
services.AddSingleton<IMqttNetLogger>(logger);
services.AddSingleton(childLogger);
services.AddSingleton<MqttHostedServer>();
services.AddSingleton<IHostedService>(s => s.GetService<MqttHostedServer>());
services.AddSingleton<IMqttServer>(s => s.GetService<MqttHostedServer>());
return services;
}
public static IServiceCollection AddMqttWebSocketServerAdapter(this IServiceCollection services)
{
services.AddSingleton<MqttWebSocketServerAdapter>();
services.AddSingleton<IMqttServerAdapter>(s => s.GetService<MqttWebSocketServerAdapter>());
return services;
}
public static IServiceCollection AddMqttTcpServerAdapter(this IServiceCollection services)
{
services.AddSingleton<MqttTcpServerAdapter>();
services.AddSingleton<IMqttServerAdapter>(s => s.GetService<MqttTcpServerAdapter>());
return services;
}
public static IServiceCollection AddMqttConnectionHandler(this IServiceCollection services)
{
services.AddSingleton<MqttConnectionHandler>();
services.AddSingleton<IMqttServerAdapter>(s => s.GetService<MqttConnectionHandler>());
return services;
}
return services;
}
}
public static IServiceCollection AddMqttConnectionHandler(this IServiceCollection services)
{
services.AddSingleton<MqttConnectionHandler>();
services.AddSingleton<IMqttServerAdapter>(s => s.GetService<MqttConnectionHandler>());
return services;
}
public static void AddMqttLogger(this IServiceCollection services, IMqttNetLogger logger)
{
ArgumentNullException.ThrowIfNull(services);
services.AddSingleton(logger);
}
public static IServiceCollection AddMqttServer(this IServiceCollection serviceCollection, Action<MqttServerOptionsBuilder> configure = null)
{
ArgumentNullException.ThrowIfNull(serviceCollection);
serviceCollection.AddMqttConnectionHandler();
serviceCollection.AddHostedMqttServer(configure);
return serviceCollection;
}
public static IServiceCollection AddMqttTcpServerAdapter(this IServiceCollection services)
{
services.AddSingleton<MqttTcpServerAdapter>();
services.AddSingleton<IMqttServerAdapter>(s => s.GetService<MqttTcpServerAdapter>());
return services;
}
public static IServiceCollection AddMqttWebSocketServerAdapter(this IServiceCollection services)
{
services.AddSingleton<MqttWebSocketServerAdapter>();
services.AddSingleton<IMqttServerAdapter>(s => s.GetService<MqttWebSocketServerAdapter>());
return services;
}
}
@@ -0,0 +1,71 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Diagnostics;
using System.IO.Pipelines;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace MQTTnet.AspNetCore;
public class SocketAwaitable(PipeScheduler ioScheduler) : ICriticalNotifyCompletion
{
static readonly Action CallbackCompleted = () =>
{
};
int _bytesTransferred;
Action _callback;
SocketError _error;
public bool IsCompleted => ReferenceEquals(_callback, CallbackCompleted);
public void Complete(int bytesTransferred, SocketError socketError)
{
_error = socketError;
_bytesTransferred = bytesTransferred;
var continuation = Interlocked.Exchange(ref _callback, CallbackCompleted);
if (continuation != null)
{
ioScheduler.Schedule(state => ((Action)state)(), continuation);
}
}
public SocketAwaitable GetAwaiter()
{
return this;
}
public int GetResult()
{
Debug.Assert(ReferenceEquals(_callback, CallbackCompleted));
_callback = null;
if (_error != SocketError.Success)
{
throw new SocketException((int)_error);
}
return _bytesTransferred;
}
public void OnCompleted(Action continuation)
{
if (ReferenceEquals(_callback, CallbackCompleted) || ReferenceEquals(Interlocked.CompareExchange(ref _callback, continuation, null), CallbackCompleted))
{
Task.Run(continuation);
}
}
public void UnsafeOnCompleted(Action continuation)
{
OnCompleted(continuation);
}
}
@@ -0,0 +1,263 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipelines;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Http.Features;
using MQTTnet.Exceptions;
namespace MQTTnet.AspNetCore;
public sealed class SocketConnection : ConnectionContext
{
readonly EndPoint _endPoint;
volatile bool _aborted;
IDuplexPipe _application;
SocketReceiver _receiver;
SocketSender _sender;
Socket _socket;
public SocketConnection(EndPoint endPoint)
{
_endPoint = endPoint;
}
public SocketConnection(Socket socket)
{
_socket = socket;
_endPoint = socket.RemoteEndPoint;
_sender = new SocketSender(_socket, PipeScheduler.ThreadPool);
_receiver = new SocketReceiver(_socket, PipeScheduler.ThreadPool);
}
public override string ConnectionId { get; set; }
public override IFeatureCollection Features { get; }
public bool IsConnected { get; private set; }
public override IDictionary<object, object> Items { get; set; }
public override IDuplexPipe Transport { get; set; }
public override ValueTask DisposeAsync()
{
IsConnected = false;
Transport?.Output.Complete();
Transport?.Input.Complete();
_socket?.Dispose();
return base.DisposeAsync();
}
public async Task StartAsync()
{
if (_socket == null)
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_sender = new SocketSender(_socket, PipeScheduler.ThreadPool);
_receiver = new SocketReceiver(_socket, PipeScheduler.ThreadPool);
await _socket.ConnectAsync(_endPoint);
}
var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default);
Transport = pair.Transport;
_application = pair.Application;
_ = ExecuteAsync();
IsConnected = true;
}
static Exception ConnectionAborted()
{
return new MqttCommunicationException("Connection Aborted");
}
async Task DoReceive()
{
Exception error = null;
try
{
await ProcessReceives();
}
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.ConnectionReset)
{
error = new MqttCommunicationException(ex);
}
catch (SocketException ex) when (ex.SocketErrorCode is SocketError.OperationAborted or SocketError.ConnectionAborted or SocketError.Interrupted or SocketError.InvalidArgument)
{
if (!_aborted)
{
// Calling Dispose after ReceiveAsync can cause an "InvalidArgument" error on *nix.
error = ConnectionAborted();
}
}
catch (ObjectDisposedException)
{
if (!_aborted)
{
error = ConnectionAborted();
}
}
catch (IOException ex)
{
error = ex;
}
catch (Exception ex)
{
error = new IOException(ex.Message, ex);
}
finally
{
if (_aborted)
{
error ??= ConnectionAborted();
}
await _application.Output.CompleteAsync(error);
}
}
async Task<Exception> DoSend()
{
Exception error = null;
try
{
await ProcessSends();
}
catch (SocketException ex) when (ex.SocketErrorCode == SocketError.OperationAborted)
{
}
catch (ObjectDisposedException)
{
}
catch (IOException ex)
{
error = ex;
}
catch (Exception ex)
{
error = new IOException(ex.Message, ex);
}
finally
{
_aborted = true;
_socket.Shutdown(SocketShutdown.Both);
}
return error;
}
async Task ExecuteAsync()
{
Exception sendError = null;
try
{
// Spawn send and receive logic
var receiveTask = DoReceive();
var sendTask = DoSend();
// If the sending task completes then close the receive
// We don't need to do this in the other direction because the kestrel
// will trigger the output closing once the input is complete.
if (await Task.WhenAny(receiveTask, sendTask).ConfigureAwait(false) == sendTask)
{
// Tell the reader it's being aborted
_socket.Dispose();
}
// Now wait for both to complete
await receiveTask;
sendError = await sendTask;
// Dispose the socket(should noop if already called)
_socket.Dispose();
}
catch (Exception ex)
{
Console.WriteLine($"Unexpected exception in {nameof(SocketConnection)}.{nameof(StartAsync)}: " + ex);
}
finally
{
// Complete the output after disposing the socket
await _application.Input.CompleteAsync(sendError).ConfigureAwait(false);
}
}
async Task ProcessReceives()
{
while (true)
{
// Ensure we have some reasonable amount of buffer space
var buffer = _application.Output.GetMemory();
var bytesReceived = await _receiver.ReceiveAsync(buffer);
if (bytesReceived == 0)
{
// FIN
break;
}
_application.Output.Advance(bytesReceived);
var flushTask = _application.Output.FlushAsync();
if (!flushTask.IsCompleted)
{
await flushTask;
}
var result = flushTask.GetAwaiter().GetResult();
if (result.IsCompleted)
{
// Pipe consumer is shut down, do we stop writing
break;
}
}
}
async Task ProcessSends()
{
while (true)
{
// Wait for data to write from the pipe producer
var result = await _application.Input.ReadAsync();
var buffer = result.Buffer;
if (result.IsCanceled)
{
break;
}
var end = buffer.End;
var isCompleted = result.IsCompleted;
if (!buffer.IsEmpty)
{
await _sender.SendAsync(buffer);
}
_application.Input.AdvanceTo(end);
if (isCompleted)
{
break;
}
}
}
}
@@ -0,0 +1,36 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO.Pipelines;
using System.Net.Sockets;
namespace MQTTnet.AspNetCore;
public sealed class SocketReceiver
{
readonly SocketAwaitable _awaitable;
readonly SocketAsyncEventArgs _eventArgs = new();
readonly Socket _socket;
public SocketReceiver(Socket socket, PipeScheduler scheduler)
{
_socket = socket;
_awaitable = new SocketAwaitable(scheduler);
_eventArgs.UserToken = _awaitable;
_eventArgs.Completed += (_, e) => ((SocketAwaitable)e.UserToken).Complete(e.BytesTransferred, e.SocketError);
}
public SocketAwaitable ReceiveAsync(Memory<byte> buffer)
{
_eventArgs.SetBuffer(buffer);
if (!_socket.ReceiveAsync(_eventArgs))
{
_awaitable.Complete(_eventArgs.BytesTransferred, _eventArgs.SocketError);
}
return _awaitable;
}
}
+93
View File
@@ -0,0 +1,93 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Pipelines;
using System.Net.Sockets;
using System.Runtime.InteropServices;
namespace MQTTnet.AspNetCore;
public sealed class SocketSender
{
readonly SocketAwaitable _awaitable;
readonly SocketAsyncEventArgs _eventArgs = new();
readonly Socket _socket;
List<ArraySegment<byte>> _bufferList;
public SocketSender(Socket socket, PipeScheduler scheduler)
{
_socket = socket;
_awaitable = new SocketAwaitable(scheduler);
_eventArgs.UserToken = _awaitable;
_eventArgs.Completed += (_, e) => ((SocketAwaitable)e.UserToken).Complete(e.BytesTransferred, e.SocketError);
}
public SocketAwaitable SendAsync(in ReadOnlySequence<byte> buffers)
{
if (buffers.IsSingleSegment)
{
return SendAsync(buffers.First);
}
if (!_eventArgs.MemoryBuffer.Equals(Memory<byte>.Empty))
{
_eventArgs.SetBuffer(null, 0, 0);
}
_eventArgs.BufferList = GetBufferList(buffers);
if (!_socket.SendAsync(_eventArgs))
{
_awaitable.Complete(_eventArgs.BytesTransferred, _eventArgs.SocketError);
}
return _awaitable;
}
List<ArraySegment<byte>> GetBufferList(in ReadOnlySequence<byte> buffer)
{
Debug.Assert(!buffer.IsEmpty);
Debug.Assert(!buffer.IsSingleSegment);
if (_bufferList == null)
{
_bufferList = new List<ArraySegment<byte>>();
}
else
{
// Buffers are pooled, so it's OK to root them until the next multi-buffer write.
_bufferList.Clear();
}
foreach (var b in buffer)
{
_bufferList.Add(b.GetArray());
}
return _bufferList;
}
SocketAwaitable SendAsync(ReadOnlyMemory<byte> memory)
{
// The BufferList getter is much less expensive then the setter.
if (_eventArgs.BufferList != null)
{
_eventArgs.BufferList = null;
}
_eventArgs.SetBuffer(MemoryMarshal.AsMemory(memory));
if (!_socket.SendAsync(_eventArgs))
{
_awaitable.Complete(_eventArgs.BytesTransferred, _eventArgs.SocketError);
}
return _awaitable;
}
}
@@ -1,124 +0,0 @@
using MQTTnet.Exceptions;
using MQTTnet.Formatter;
using System;
using System.Buffers.Binary;
using System.Text;
namespace MQTTnet.AspNetCore
{
public class SpanBasedMqttPacketBodyReader : IMqttPacketBodyReader
{
private ReadOnlyMemory<byte> _buffer;
private int _offset;
public void SetBuffer(ReadOnlyMemory<byte> buffer)
{
_buffer = buffer;
_offset = 0;
}
public ulong Length => (ulong)_buffer.Length;
public bool EndOfStream => _buffer.Length.Equals(_offset);
public ulong Offset => (ulong)_offset;
public byte ReadByte()
{
return _buffer.Span[_offset++];
}
public byte[] ReadRemainingData()
{
return _buffer.Slice(_offset).ToArray();
}
public byte[] ReadWithLengthPrefix()
{
return ReadSegmentWithLengthPrefix().ToArray();
}
private ReadOnlySpan<byte> ReadSegmentWithLengthPrefix()
{
var span = _buffer.Span;
var length = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(_offset));
var result = span.Slice(_offset+2, length);
_offset += 2 + length;
return result;
}
public unsafe string ReadStringWithLengthPrefix()
{
var buffer = ReadSegmentWithLengthPrefix();
if (buffer.Length == 0)
{
return string.Empty;
}
fixed (byte* bytes = &buffer.GetPinnableReference())
{
var result = Encoding.UTF8.GetString(bytes, buffer.Length);
return result;
}
}
public ushort ReadTwoByteInteger()
{
var result = BinaryPrimitives.ReadUInt16BigEndian(_buffer.Span.Slice(_offset));
_offset += 2;
return result;
}
public uint ReadFourByteInteger()
{
var result = BinaryPrimitives.ReadUInt32BigEndian(_buffer.Span.Slice(_offset));
_offset += 4;
return result;
}
public uint ReadVariableLengthInteger()
{
var multiplier = 1;
var value = 0U;
byte encodedByte;
do
{
encodedByte = ReadByte();
value += (uint)((encodedByte & 127) * multiplier);
if (multiplier > 2097152)
{
throw new MqttProtocolViolationException("Variable length integer is invalid.");
}
multiplier *= 128;
} while ((encodedByte & 128) != 0);
return value;
}
public bool ReadBoolean()
{
var buffer = ReadByte();
if (buffer == 0)
{
return false;
}
if (buffer == 1)
{
return true;
}
throw new MqttProtocolViolationException("Boolean values can be 0 or 1 only.");
}
public void Seek(ulong position)
{
_offset = (int)position;
}
}
}
@@ -1,146 +0,0 @@
using MQTTnet.Formatter;
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Text;
namespace MQTTnet.AspNetCore
{
public class SpanBasedMqttPacketWriter : IMqttPacketWriter
{
private readonly ArrayPool<byte> _pool;
public SpanBasedMqttPacketWriter()
{
_pool = ArrayPool<byte>.Create();
}
private byte[] _buffer;
private int _position;
public int Length { get; set; }
public void FreeBuffer()
{
_pool.Return(_buffer);
}
public byte[] GetBuffer()
{
return _buffer;
}
public void Reset(int v)
{
_buffer = _pool.Rent(1500);
Length = v;
_position = v;
}
public void Seek(int v)
{
_position = v;
}
public void Write(byte value)
{
GrowIfNeeded(1);
_buffer[_position] = value;
Commit(1);
}
public void Write(ushort value)
{
GrowIfNeeded(2);
BinaryPrimitives.WriteUInt16BigEndian(_buffer.AsSpan(_position), value);
Commit(2);
}
public void Write(IMqttPacketWriter propertyWriter)
{
if (propertyWriter == null) throw new ArgumentNullException(nameof(propertyWriter));
GrowIfNeeded(propertyWriter.Length);
Write(propertyWriter.GetBuffer(), 0, propertyWriter.Length);
Commit(propertyWriter.Length);
}
public void Write(byte[] payload, int start, int length)
{
GrowIfNeeded(length);
payload.AsSpan(start, length).CopyTo(_buffer.AsSpan(_position));
Commit(length);
}
public void WriteVariableLengthInteger(uint value)
{
GrowIfNeeded(4);
var x = value;
do
{
var encodedByte = x % 128;
x = x / 128;
if (x > 0)
{
encodedByte = encodedByte | 128;
}
_buffer[_position] = (byte)encodedByte;
Commit(1);
} while (x > 0);
}
public void WriteWithLengthPrefix(string value)
{
var bytesLength = Encoding.UTF8.GetByteCount(value ?? string.Empty);
GrowIfNeeded(bytesLength + 2);
Write((ushort)bytesLength);
Encoding.UTF8.GetBytes(value ?? string.Empty, 0, value?.Length ?? 0, _buffer, _position);
Commit(bytesLength);
}
public void WriteWithLengthPrefix(byte[] payload)
{
GrowIfNeeded(payload.Length + 2);
Write((ushort)payload.Length);
payload.CopyTo(_buffer, _position);
Commit(payload.Length);
}
private void Commit(int count)
{
if (_position == Length)
{
Length += count;
}
_position += count;
}
private void GrowIfNeeded(int requiredAdditional)
{
var requiredTotal = _position + requiredAdditional;
if (_buffer.Length >= requiredTotal)
{
return;
}
var newBufferLength = _buffer.Length;
while (newBufferLength < requiredTotal)
{
newBufferLength *= 2;
}
var newBuffer = _pool.Rent(newBufferLength);
Array.Copy(_buffer, newBuffer, _buffer.Length);
_pool.Return(_buffer);
_buffer = newBuffer;
}
}
}
@@ -0,0 +1,3 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
[assembly: DoNotParallelize]
@@ -0,0 +1,63 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using MQTTnet.Internal;
namespace MQTTnet.Benchmarks;
[SimpleJob(RuntimeMoniker.Net60)]
[MemoryDiagnoser]
public class AsyncLockBenchmark : BaseBenchmark
{
[Benchmark]
public async Task Synchronize_100_Tasks()
{
const int tasksCount = 100;
var tasks = new Task[tasksCount];
var asyncLock = new AsyncLock();
var globalI = 0;
for (var i = 0; i < tasksCount; i++)
{
tasks[i] = Task.Run(
async () =>
{
using (await asyncLock.EnterAsync().ConfigureAwait(false))
{
var localI = globalI;
await Task.Delay(5).ConfigureAwait(false); // Increase the chance for wrong data.
localI++;
globalI = localI;
}
});
}
await Task.WhenAll(tasks).ConfigureAwait(false);
if (globalI != tasksCount)
{
throw new Exception($"Code is broken ({globalI})!");
}
}
[Benchmark]
public async Task Wait_100_000_Times()
{
var asyncLock = new AsyncLock();
using var cancellationToken = new CancellationTokenSource();
for (var i = 0; i < 100000; i++)
{
using (await asyncLock.EnterAsync(cancellationToken.Token).ConfigureAwait(false))
{
}
}
}
}
@@ -0,0 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace MQTTnet.Benchmarks;
public abstract class BaseBenchmark
{
}
@@ -0,0 +1,89 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
using System.Threading;
using BenchmarkDotNet.Attributes;
using MQTTnet.Adapter;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Formatter;
using MQTTnet.Packets;
using MQTTnet.Tests.Mockups;
namespace MQTTnet.Benchmarks;
[MemoryDiagnoser]
public sealed class ChannelAdapterBenchmark : BaseBenchmark
{
MqttChannelAdapter _channelAdapter;
int _iterations;
MqttPublishPacket _packet;
MemoryStream _stream;
[Benchmark]
public void Receive_10000_Messages()
{
_stream.Position = 0;
for (var i = 0; i < 10000; i++)
{
_channelAdapter.ReceivePacketAsync(CancellationToken.None).GetAwaiter().GetResult();
}
_stream.Position = 0;
}
[Benchmark]
public void Send_10000_Messages()
{
_stream.Position = 0;
for (var i = 0; i < 10000; i++)
{
_channelAdapter.SendPacketAsync(_packet, CancellationToken.None).GetAwaiter().GetResult();
}
_stream.Position = 0;
}
[GlobalSetup]
public void Setup()
{
_packet = new MqttPublishPacket
{
Topic = "A"
};
var serializer = new MqttPacketFormatterAdapter(MqttProtocolVersion.V311, new MqttBufferWriter(4096, 65535));
var serializedPacket = Join(serializer.Encode(_packet).Join());
_iterations = 10000;
_stream = new MemoryStream(_iterations * serializedPacket.Length);
for (var i = 0; i < _iterations; i++)
{
_stream.Write(serializedPacket, 0, serializedPacket.Length);
}
_stream.Position = 0;
var channel = new MemoryMqttChannel(_stream);
_channelAdapter = new MqttChannelAdapter(channel, serializer, new MqttNetEventLogger());
}
static byte[] Join(params ArraySegment<byte>[] chunks)
{
var buffer = new MemoryStream();
foreach (var chunk in chunks)
{
buffer.Write(chunk.Array, chunk.Offset, chunk.Count);
}
return buffer.ToArray();
}
}
@@ -0,0 +1,91 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using MQTTnet.Diagnostics.Logger;
namespace MQTTnet.Benchmarks;
[SimpleJob(RuntimeMoniker.Net60)]
[RPlotExporter]
[MemoryDiagnoser]
public class LoggerBenchmark : BaseBenchmark
{
MqttNetNullLogger _nullLogger;
MqttNetSourceLogger _sourceNullLogger;
MqttNetEventLogger _eventLogger;
MqttNetSourceLogger _sourceEventLogger;
MqttNetEventLogger _eventLoggerNoListener;
MqttNetSourceLogger _sourceEventLoggerNoListener;
bool _useHandler;
[GlobalSetup]
public void Setup()
{
_nullLogger = new MqttNetNullLogger();
_sourceNullLogger = _nullLogger.WithSource("Source");
_eventLogger = new MqttNetEventLogger();
_eventLogger.LogMessagePublished += OnLogMessagePublished;
_sourceEventLogger = _eventLogger.WithSource("Source");
_eventLoggerNoListener = new MqttNetEventLogger();
_sourceEventLoggerNoListener = _eventLoggerNoListener.WithSource("Source");
}
void OnLogMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs eventArgs)
{
if (_useHandler)
{
Debug.WriteLine(eventArgs.LogMessage.ToString());
}
}
[Benchmark]
public void Log_10000_Messages_No_Listener()
{
_useHandler = false;
for (var i = 0; i < 10000; i++)
{
_sourceEventLoggerNoListener.Verbose("test log message {0}", "parameter");
}
}
[Benchmark]
public void Log_10000_Messages_With_To_String()
{
_useHandler = true;
for (var i = 0; i < 10000; i++)
{
_sourceEventLogger.Verbose("test log message {0}", "parameter");
}
}
[Benchmark]
public void Log_10000_Messages_Without_To_String()
{
_useHandler = false;
for (var i = 0; i < 10000; i++)
{
_sourceEventLogger.Verbose("test log message {0}", "parameter");
}
}
[Benchmark]
public void Log_10000_Messages_With_NullLogger()
{
for (var i = 0; i < 10000; i++)
{
_sourceNullLogger.Verbose("test log message {0}", "parameter");
}
}
}
@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<OutputType>Exe</OutputType>
<DebugType>Full</DebugType>
<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
<EnableNETAnalyzers>false</EnableNETAnalyzers>
<EnforceCodeStyleInBuild>false</EnforceCodeStyleInBuild>
<DisableImplicitAspNetCoreAnalyzers>true</DisableImplicitAspNetCoreAnalyzers>
<NoWarn>1591;NETSDK1138;NU1803;NU1901;NU1902;CS8892</NoWarn>
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<NuGetAuditMode>all</NuGetAuditMode>
<NuGetAudit>true</NuGetAudit>
<NuGetAuditLevel>low</NuGetAuditLevel>
<AnalysisLevel>latest-Recommended</AnalysisLevel>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.15.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Source\MQTTnet.Server\MQTTnet.Server.csproj"/>
<ProjectReference Include="..\..\Source\MQTTnet.AspnetCore\MQTTnet.AspNetCore.csproj"/>
<ProjectReference Include="..\MQTTnet.Tests\MQTTnet.Tests.csproj"/>
<ProjectReference Include="..\MQTTnet\MQTTnet.csproj"/>
</ItemGroup>
</Project>
@@ -0,0 +1,40 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using System;
namespace MQTTnet.Benchmarks;
[SimpleJob(RuntimeMoniker.Net60)]
[RPlotExporter, RankColumn]
[MemoryDiagnoser]
public class MemoryCopyBenchmark
{
const int MaxLength = 1024 * 8;
byte[] _source;
byte[] _target;
[Params(64 - 1, 128 - 1, 256 - 1, 512 - 1, 1024 - 1, 2048 - 1, 5096 - 1)]
public int Length { get; set; }
[GlobalSetup]
public void Setup()
{
_source = new byte[MaxLength];
_target = new byte[MaxLength];
}
[Benchmark(Baseline = true)]
public void Array_Copy()
{
Array.Copy(_source, 0, _target, 0, Length);
}
[Benchmark]
public void Memory_Copy()
{
Internal.MqttMemoryHelper.Copy(_source, 0, _target, 0, Length);
}
}
@@ -0,0 +1,194 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using MQTTnet.Packets;
using MQTTnet.Server;
namespace MQTTnet.Benchmarks;
[MemoryDiagnoser]
public class MessageDeliveryBenchmark : BaseBenchmark
{
List<string> _allSubscribedTopics; // Keep track of the subset of topics that are subscribed
CancellationTokenSource _cancellationTokenSource;
object _lockMsgCount;
int _messagesExpectedCount;
int _messagesReceivedCount;
Dictionary<string, IMqttClient> _mqttPublisherClientsByPublisherName;
MqttServer _mqttServer;
List<IMqttClient> _mqttSubscriberClients;
[Params(1000, 10000)] public int _numPublishers;
[Params(5, 10, 20, 50)] public int _numSubscribedTopicsPerSubscriber;
[Params(10)] public int _numSubscribers;
[Params(1, 5)] public int _numTopicsPerPublisher;
Dictionary<string, string> _publisherByTopic;
Dictionary<string, List<string>> _topicsByPublisher;
[GlobalCleanup]
public void Cleanup()
{
foreach (var mp in _mqttPublisherClientsByPublisherName)
{
var mqttPublisherClient = mp.Value;
mqttPublisherClient.DisconnectAsync().GetAwaiter().GetResult();
mqttPublisherClient.Dispose();
}
_mqttPublisherClientsByPublisherName.Clear();
foreach (var mqttSubscriber in _mqttSubscriberClients)
{
mqttSubscriber.DisconnectAsync().GetAwaiter().GetResult();
mqttSubscriber.Dispose();
}
_mqttSubscriberClients.Clear();
_mqttServer.StopAsync().GetAwaiter().GetResult();
_mqttServer.Dispose();
_mqttServer = null;
}
[Benchmark]
public void DeliverMessages()
{
// There should be one message received per publish for each subscribed topic
_messagesExpectedCount = _numSubscribedTopicsPerSubscriber * _numSubscribers;
// Loop for a while and exchange messages
_messagesReceivedCount = 0;
_cancellationTokenSource = new CancellationTokenSource();
// same payload for all messages
var payload = new byte[] { 1, 2, 3, 4 };
// publish a message for each subscribed topic
foreach (var topic in _allSubscribedTopics)
{
var message = new MqttApplicationMessageBuilder().WithTopic(topic).WithPayload(payload).Build();
// pick the correct publisher
var publisherName = _publisherByTopic[topic];
var publisherClient = _mqttPublisherClientsByPublisherName[publisherName];
_ = publisherClient.PublishAsync(message);
}
// Wait one message per publish to be received by subscriber (in the subscriber's application message handler)
try
{
Task.Delay(30000, _cancellationTokenSource.Token).GetAwaiter().GetResult();
}
catch
{
// Ignore all errors.
}
_cancellationTokenSource.Dispose();
if (_messagesReceivedCount < _messagesExpectedCount)
{
throw new Exception($"Messages Received Count mismatch, expected {_messagesExpectedCount}, received {_messagesReceivedCount}");
}
}
[GlobalSetup]
public void Setup()
{
_lockMsgCount = new object();
TopicGenerator.Generate(_numPublishers, _numTopicsPerPublisher, out _topicsByPublisher, out _, out _);
// Create server
var serverFactory = new MqttServerFactory();
var clientFactory = new MqttClientFactory();
var serverOptions = new MqttServerOptionsBuilder().WithDefaultEndpoint().Build();
_mqttServer = serverFactory.CreateMqttServer(serverOptions);
_mqttServer.StartAsync().GetAwaiter().GetResult();
// Create publisher clients
_mqttPublisherClientsByPublisherName = [];
foreach (var pt in _topicsByPublisher)
{
var publisherName = pt.Key;
var mqttClient = clientFactory.CreateMqttClient();
var publisherOptions = new MqttClientOptionsBuilder().WithTcpServer("localhost").WithClientId(publisherName).WithKeepAlivePeriod(TimeSpan.FromSeconds(30)).Build();
mqttClient.ConnectAsync(publisherOptions).GetAwaiter().GetResult();
_mqttPublisherClientsByPublisherName.Add(publisherName, mqttClient);
}
// Create subscriber clients
_mqttSubscriberClients = new List<IMqttClient>();
for (var i = 0; i < _numSubscribers; i++)
{
var mqttSubscriberClient = clientFactory.CreateMqttClient();
_mqttSubscriberClients.Add(mqttSubscriberClient);
var subscriberOptions = new MqttClientOptionsBuilder().WithTcpServer("localhost").WithClientId("subscriber" + i).Build();
mqttSubscriberClient.ApplicationMessageReceivedAsync += _ =>
{
// count messages and signal cancellation when expected message count is reached
lock (_lockMsgCount)
{
++_messagesReceivedCount;
if (_messagesReceivedCount == _messagesExpectedCount)
{
_cancellationTokenSource.Cancel();
}
}
return Task.CompletedTask;
};
mqttSubscriberClient.ConnectAsync(subscriberOptions).GetAwaiter().GetResult();
}
var allTopics = new List<string>();
_publisherByTopic = [];
foreach (var t in _topicsByPublisher)
{
foreach (var topic in t.Value)
{
_publisherByTopic.Add(topic, t.Key);
allTopics.Add(topic);
}
}
// Subscribe to NumSubscribedTopics topics spread across all topics
_allSubscribedTopics = new List<string>();
var totalNumTopics = _numPublishers * _numTopicsPerPublisher;
var topicIndexStep = totalNumTopics / (_numSubscribedTopicsPerSubscriber * _numSubscribers);
if (topicIndexStep * _numSubscribedTopicsPerSubscriber * _numSubscribers != totalNumTopics)
{
throw new Exception(
$"The total number of topics must be divisible by the number of subscribed topics across all subscribers. Total number of topics: {totalNumTopics}, topic step: {topicIndexStep}");
}
var topicIndex = 0;
foreach (var mqttSubscriber in _mqttSubscriberClients)
{
for (var i = 0; i < _numSubscribedTopicsPerSubscriber; ++i, topicIndex += topicIndexStep)
{
var topic = allTopics[topicIndex];
_allSubscribedTopics.Add(topic);
var subOptions = new MqttClientSubscribeOptionsBuilder().WithTopicFilter(new MqttTopicFilter { Topic = topic }).Build();
mqttSubscriber.SubscribeAsync(subOptions).GetAwaiter().GetResult();
}
}
Task.Delay(1000).GetAwaiter().GetResult();
}
}
@@ -0,0 +1,48 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using MQTTnet.Server;
namespace MQTTnet.Benchmarks;
[SimpleJob(RuntimeMoniker.Net60)]
[RPlotExporter]
[RankColumn]
[MemoryDiagnoser]
public class MessageProcessingBenchmark : BaseBenchmark
{
MqttApplicationMessage _message;
IMqttClient _mqttClient;
MqttServer _mqttServer;
[Benchmark]
public void Send_10000_Messages()
{
for (var i = 0; i < 10000; i++)
{
_mqttClient.PublishAsync(_message).GetAwaiter().GetResult();
}
}
[GlobalSetup]
public void Setup()
{
var serverOptions = new MqttServerOptionsBuilder().Build();
var serverFactory = new MqttServerFactory();
_mqttServer = serverFactory.CreateMqttServer(serverOptions);
var clientFactory = new MqttClientFactory();
_mqttClient = clientFactory.CreateMqttClient();
_mqttServer.StartAsync().GetAwaiter().GetResult();
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("localhost").Build();
_mqttClient.ConnectAsync(clientOptions).GetAwaiter().GetResult();
_message = new MqttApplicationMessageBuilder().WithTopic("A").Build();
}
}
@@ -0,0 +1,72 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using MQTTnet.AspNetCore;
using MQTTnet.Diagnostics.Logger;
namespace MQTTnet.Benchmarks;
[SimpleJob(RuntimeMoniker.Net60)]
[MemoryDiagnoser]
public class MessageProcessingMqttConnectionContextBenchmark : BaseBenchmark
{
IWebHost _host;
IMqttClient _mqttClient;
MqttApplicationMessage _message;
[GlobalSetup]
public void Setup()
{
_host = WebHost.CreateDefaultBuilder()
.UseKestrel(o => o.ListenAnyIP(1883, l => l.UseMqtt()))
.ConfigureServices(services => {
services
.AddHostedMqttServer(mqttServerOptions => mqttServerOptions.WithoutDefaultEndpoint())
.AddMqttConnectionHandler();
})
.Configure(app => {
app.UseMqttServer(_ => {
});
})
.Build();
var factory = new MqttClientFactory();
_mqttClient = factory.CreateMqttClient(new MqttNetEventLogger(), new MqttClientConnectionContextFactory());
_host.StartAsync().GetAwaiter().GetResult();
var clientOptions = new MqttClientOptionsBuilder()
.WithTcpServer("localhost").Build();
_mqttClient.ConnectAsync(clientOptions).GetAwaiter().GetResult();
_message = new MqttApplicationMessageBuilder()
.WithTopic("A")
.Build();
}
[GlobalCleanup]
public void Cleanup()
{
_mqttClient.DisconnectAsync().GetAwaiter().GetResult();
_mqttClient.Dispose();
_host.StopAsync().GetAwaiter().GetResult();
_host.Dispose();
}
[Benchmark]
public void Send_10000_Messages()
{
for (var i = 0; i < 10000; i++)
{
_mqttClient.PublishAsync(_message).GetAwaiter().GetResult();
}
}
}
@@ -0,0 +1,42 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Text;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using MQTTnet.Formatter;
namespace MQTTnet.Benchmarks;
[SimpleJob(RuntimeMoniker.Net60)]
[MemoryDiagnoser]
public class MqttBufferReaderBenchmark
{
byte[] _buffer;
int _bufferLength;
[GlobalSetup]
public void GlobalSetup()
{
var writer = new MqttBufferWriter(1024, 1024);
writer.WriteString("hgfjkdfkjlghfdjghdfljkdfhgdlkjfshgsldkfjghsdflkjghdsflkjhrstiuoghlkfjbhnfbutghjoiöjhklötnbhtroliöuhbjntluiobkjzbhtdrlskbhtruhjkfthgbkftgjhgfiklhotriuöhbjtrsioöbtrsötrhträhtrühjtriüoätrhjtsrölbktrbnhtrulöbionhströloubinströoliubhnsöotrunbtöroisntröointröioujhgötiohjgötorshjnbgtöorihbnjtröoihbjntröobntröoibntrjhötrohjbtröoihntröoibnrtoiöbtrjnboöitrhjtnriohötrhjtöroihjtroöihjtroösibntsroönbotöirsbntöoihjntröoihntroöbtrboöitrnhoöitrhjntröoishbnjtröosbhtröbntriohjtröoijtöoitbjöotibjnhöotirhbjntroöibhnjrtoöibnhtroöibnhtörsbnhtöoirbnhtöroibntoörhjnbträöbtrbträbtrbtirbätrsibohjntrsöiobthnjiohjsrtoib");
_buffer = writer.GetBuffer();
_bufferLength = writer.Length;
}
[Benchmark]
public void Use_Span()
{
var span = _buffer.AsSpan(0, _bufferLength);
Encoding.UTF8.GetString(span);
}
[Benchmark]
public void Use_Encoding()
{
Encoding.UTF8.GetString(_buffer, 0, _bufferLength);
}
}
@@ -0,0 +1,95 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using MQTTnet.Formatter;
using MQTTnet.Tests.Mockups;
namespace MQTTnet.Benchmarks;
[SimpleJob(RuntimeMoniker.Net60)]
[MemoryDiagnoser]
public class MqttPacketReaderWriterBenchmark : BaseBenchmark
{
readonly byte[] _demoPayload = new byte[1024];
byte[] _readPayload;
[GlobalCleanup]
public void GlobalCleanup()
{
}
[GlobalSetup]
public void GlobalSetup()
{
TestEnvironment.EnableLogger = false;
var writer = new MqttBufferWriter(4096, 65535);
writer.WriteString("A relative short string.");
writer.WriteBinary(_demoPayload);
writer.WriteByte(0x01);
writer.WriteByte(0x02);
writer.WriteVariableByteInteger(5647382);
writer.WriteString("A relative short string.");
writer.WriteVariableByteInteger(8574489);
writer.WriteBinary(_demoPayload);
writer.WriteByte(2);
writer.WriteByte(0x02);
writer.WriteString("fjgffiogfhgfhoihgoireghreghreguhreguireoghreouighreouighreughreguiorehreuiohruiorehreuioghreug");
writer.WriteBinary(_demoPayload);
_readPayload = new ArraySegment<byte>(writer.GetBuffer(), 0, writer.Length).ToArray();
}
[Benchmark]
public void Read_100_000_Messages()
{
var reader = new MqttBufferReader();
reader.SetBuffer(_readPayload, 0, _readPayload.Length);
for (var i = 0; i < 100000; i++)
{
reader.Seek(0);
reader.ReadString();
reader.ReadBinaryData();
reader.ReadByte();
reader.ReadByte();
reader.ReadVariableByteInteger();
reader.ReadString();
reader.ReadVariableByteInteger();
reader.ReadBinaryData();
reader.ReadByte();
reader.ReadByte();
reader.ReadString();
reader.ReadBinaryData();
}
}
[Benchmark]
public void Write_100_000_Messages()
{
var writer = new MqttBufferWriter(4096, 65535);
for (var i = 0; i < 100000; i++)
{
writer.WriteString("A relative short string.");
writer.WriteByte(0x01);
writer.WriteByte(0x02);
writer.WriteVariableByteInteger(5647382);
writer.WriteString("A relative short string.");
writer.WriteVariableByteInteger(8574589);
writer.WriteBinary(_demoPayload);
writer.WriteByte(2);
writer.WriteByte(0x02);
writer.WriteString("fjgffiogfhgfhoihgoireghreghreguhreguireoghreouighreouighreughreguiorehreuiohruiorehreuioghreug");
writer.WriteBinary(_demoPayload);
writer.Reset(0);
}
}
}
@@ -0,0 +1,87 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Buffers;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using MQTTnet.Channel;
using MQTTnet.Diagnostics.Logger;
using MQTTnet.Implementations;
using MQTTnet.Server;
using MQTTnet.Server.Internal.Adapter;
namespace MQTTnet.Benchmarks;
[SimpleJob(RuntimeMoniker.Net60)]
[MemoryDiagnoser]
public class MqttTcpChannelBenchmark : BaseBenchmark
{
IMqttChannel _clientChannel;
MqttServer _mqttServer;
IMqttChannel _serverChannel;
[Benchmark]
public async Task Send_10000_Chunks()
{
var size = 5;
var iterations = 10000;
await Task.WhenAll(WriteAsync(iterations, size), ReadAsync(iterations, size));
}
[GlobalSetup]
public void Setup()
{
var serverFactory = new MqttServerFactory();
var tcpServer = new MqttTcpServerAdapter();
tcpServer.ClientHandler += args =>
{
_serverChannel = (IMqttChannel)args.GetType().GetField("_channel", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(args);
return Task.CompletedTask;
};
var serverOptions = new MqttServerOptionsBuilder().Build();
_mqttServer = serverFactory.CreateMqttServer(serverOptions, new[] { tcpServer }, new MqttNetEventLogger());
_mqttServer.StartAsync().GetAwaiter().GetResult();
var clientOptions = new MqttClientOptionsBuilder().WithTcpServer("localhost").Build();
var tcpOptions = (MqttClientTcpOptions)clientOptions.ChannelOptions;
_clientChannel = new MqttTcpChannel(new MqttClientOptions { ChannelOptions = tcpOptions });
_clientChannel.ConnectAsync(CancellationToken.None).GetAwaiter().GetResult();
}
async Task ReadAsync(int iterations, int size)
{
await Task.Yield();
var expected = iterations * size;
long read = 0;
while (read < expected)
{
var readResult = await _clientChannel.ReadAsync(new byte[size], 0, size, CancellationToken.None).ConfigureAwait(false);
read += readResult;
}
}
async Task WriteAsync(int iterations, int size)
{
await Task.Yield();
var buffer = new ReadOnlySequence<byte>(new byte[size]);
for (var i = 0; i < iterations; i++)
{
await _serverChannel.WriteAsync(buffer, true, CancellationToken.None).ConfigureAwait(false);
}
}
}

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