您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

578 行
19 KiB

  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Text;
  4. using System.Threading.Tasks;
  5. using Windows.Security.Cryptography.Certificates;
  6. using Windows.UI.Core;
  7. using Windows.UI.Xaml;
  8. using MQTTnet.Client;
  9. using MQTTnet.Diagnostics;
  10. using MQTTnet.Exceptions;
  11. using MQTTnet.Extensions.Rpc;
  12. using MQTTnet.Implementations;
  13. using MQTTnet.ManagedClient;
  14. using MQTTnet.Protocol;
  15. using MQTTnet.Server;
  16. namespace MQTTnet.TestApp.UniversalWindows
  17. {
  18. public sealed partial class MainPage
  19. {
  20. private readonly ConcurrentQueue<MqttNetLogMessage> _traceMessages = new ConcurrentQueue<MqttNetLogMessage>();
  21. private IMqttClient _mqttClient;
  22. private IMqttServer _mqttServer;
  23. public MainPage()
  24. {
  25. InitializeComponent();
  26. MqttNetGlobalLogger.LogMessagePublished += OnTraceMessagePublished;
  27. }
  28. private async void OnTraceMessagePublished(object sender, MqttNetLogMessagePublishedEventArgs e)
  29. {
  30. _traceMessages.Enqueue(e.TraceMessage);
  31. while (_traceMessages.Count > 100)
  32. {
  33. _traceMessages.TryDequeue(out _);
  34. }
  35. var logText = new StringBuilder();
  36. foreach (var traceMessage in _traceMessages)
  37. {
  38. logText.AppendFormat(
  39. "[{0:yyyy-MM-dd HH:mm:ss.fff}] [{1}] [{2}] [{3}] [{4}]{5}", traceMessage.Timestamp,
  40. traceMessage.Level,
  41. traceMessage.Source,
  42. traceMessage.ThreadId,
  43. traceMessage.Message,
  44. Environment.NewLine);
  45. if (traceMessage.Exception != null)
  46. {
  47. logText.AppendLine(traceMessage.Exception.ToString());
  48. }
  49. }
  50. await Trace.Dispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
  51. {
  52. Trace.Text = logText.ToString();
  53. });
  54. }
  55. private async void Connect(object sender, RoutedEventArgs e)
  56. {
  57. var tlsOptions = new MqttClientTlsOptions
  58. {
  59. UseTls = UseTls.IsChecked == true,
  60. IgnoreCertificateChainErrors = true,
  61. IgnoreCertificateRevocationErrors = true,
  62. AllowUntrustedCertificates = true
  63. };
  64. var options = new MqttClientOptions { ClientId = ClientId.Text };
  65. if (UseTcp.IsChecked == true)
  66. {
  67. options.ChannelOptions = new MqttClientTcpOptions
  68. {
  69. Server = Server.Text,
  70. Port = int.Parse(Port.Text),
  71. TlsOptions = tlsOptions
  72. };
  73. }
  74. if (UseWs.IsChecked == true)
  75. {
  76. options.ChannelOptions = new MqttClientWebSocketOptions
  77. {
  78. Uri = Server.Text,
  79. TlsOptions = tlsOptions
  80. };
  81. }
  82. if (options.ChannelOptions == null)
  83. {
  84. throw new InvalidOperationException();
  85. }
  86. options.Credentials = new MqttClientCredentials
  87. {
  88. Username = User.Text,
  89. Password = Password.Text
  90. };
  91. options.CleanSession = CleanSession.IsChecked == true;
  92. options.KeepAlivePeriod = TimeSpan.FromSeconds(double.Parse(KeepAliveInterval.Text));
  93. try
  94. {
  95. if (_mqttClient != null)
  96. {
  97. await _mqttClient.DisconnectAsync();
  98. _mqttClient.ApplicationMessageReceived -= OnApplicationMessageReceived;
  99. }
  100. var factory = new MqttFactory();
  101. _mqttClient = factory.CreateMqttClient();
  102. _mqttClient.ApplicationMessageReceived += OnApplicationMessageReceived;
  103. await _mqttClient.ConnectAsync(options);
  104. }
  105. catch (Exception exception)
  106. {
  107. Trace.Text += exception + Environment.NewLine;
  108. }
  109. }
  110. private async void OnApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs eventArgs)
  111. {
  112. var item = $"Timestamp: {DateTime.Now:O} | Topic: {eventArgs.ApplicationMessage.Topic} | Payload: {Encoding.UTF8.GetString(eventArgs.ApplicationMessage.Payload)} | QoS: {eventArgs.ApplicationMessage.QualityOfServiceLevel}";
  113. await Dispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
  114. {
  115. if (AddReceivedMessagesToList.IsChecked == true)
  116. {
  117. ReceivedMessages.Items.Add(item);
  118. }
  119. });
  120. }
  121. private async void Publish(object sender, RoutedEventArgs e)
  122. {
  123. if (_mqttClient == null)
  124. {
  125. return;
  126. }
  127. try
  128. {
  129. var qos = MqttQualityOfServiceLevel.AtMostOnce;
  130. if (QoS1.IsChecked == true)
  131. {
  132. qos = MqttQualityOfServiceLevel.AtLeastOnce;
  133. }
  134. if (QoS2.IsChecked == true)
  135. {
  136. qos = MqttQualityOfServiceLevel.ExactlyOnce;
  137. }
  138. var payload = new byte[0];
  139. if (Text.IsChecked == true)
  140. {
  141. payload = Encoding.UTF8.GetBytes(Payload.Text);
  142. }
  143. if (Base64.IsChecked == true)
  144. {
  145. payload = Convert.FromBase64String(Payload.Text);
  146. }
  147. var message = new MqttApplicationMessageBuilder()
  148. .WithTopic(Topic.Text)
  149. .WithPayload(payload)
  150. .WithQualityOfServiceLevel(qos)
  151. .WithRetainFlag(Retain.IsChecked == true)
  152. .Build();
  153. await _mqttClient.PublishAsync(message);
  154. }
  155. catch (Exception exception)
  156. {
  157. Trace.Text += exception + Environment.NewLine;
  158. }
  159. }
  160. private async void Disconnect(object sender, RoutedEventArgs e)
  161. {
  162. try
  163. {
  164. await _mqttClient.DisconnectAsync();
  165. }
  166. catch (Exception exception)
  167. {
  168. Trace.Text += exception + Environment.NewLine;
  169. }
  170. }
  171. private void Clear(object sender, RoutedEventArgs e)
  172. {
  173. Trace.Text = string.Empty;
  174. }
  175. private async void Subscribe(object sender, RoutedEventArgs e)
  176. {
  177. if (_mqttClient == null)
  178. {
  179. return;
  180. }
  181. try
  182. {
  183. var qos = MqttQualityOfServiceLevel.AtMostOnce;
  184. if (SubscribeQoS1.IsChecked == true)
  185. {
  186. qos = MqttQualityOfServiceLevel.AtLeastOnce;
  187. }
  188. if (SubscribeQoS2.IsChecked == true)
  189. {
  190. qos = MqttQualityOfServiceLevel.ExactlyOnce;
  191. }
  192. await _mqttClient.SubscribeAsync(new TopicFilter(SubscribeTopic.Text, qos));
  193. }
  194. catch (Exception exception)
  195. {
  196. Trace.Text += exception + Environment.NewLine;
  197. }
  198. }
  199. private async void Unsubscribe(object sender, RoutedEventArgs e)
  200. {
  201. if (_mqttClient == null)
  202. {
  203. return;
  204. }
  205. try
  206. {
  207. await _mqttClient.UnsubscribeAsync(SubscribeTopic.Text);
  208. }
  209. catch (Exception exception)
  210. {
  211. Trace.Text += exception + Environment.NewLine;
  212. }
  213. }
  214. // This code is for the Wiki at GitHub!
  215. // ReSharper disable once UnusedMember.Local
  216. private async void StartServer(object sender, RoutedEventArgs e)
  217. {
  218. if (_mqttServer != null)
  219. {
  220. return;
  221. }
  222. JsonServerStorage storage = null;
  223. if (ServerPersistRetainedMessages.IsChecked == true)
  224. {
  225. storage = new JsonServerStorage();
  226. if (ServerClearRetainedMessages.IsChecked == true)
  227. {
  228. storage.Clear();
  229. }
  230. }
  231. _mqttServer = new MqttFactory().CreateMqttServer();
  232. var options = new MqttServerOptions();
  233. options.DefaultEndpointOptions.Port = int.Parse(ServerPort.Text);
  234. options.Storage = storage;
  235. await _mqttServer.StartAsync(options);
  236. }
  237. private async void StopServer(object sender, RoutedEventArgs e)
  238. {
  239. if (_mqttServer == null)
  240. {
  241. return;
  242. }
  243. await _mqttServer.StopAsync();
  244. _mqttServer = null;
  245. }
  246. private void ClearReceivedMessages(object sender, RoutedEventArgs e)
  247. {
  248. ReceivedMessages.Items.Clear();
  249. }
  250. private async void ExecuteRpc(object sender, RoutedEventArgs e)
  251. {
  252. var qos = MqttQualityOfServiceLevel.AtMostOnce;
  253. if (RpcQoS1.IsChecked == true)
  254. {
  255. qos = MqttQualityOfServiceLevel.AtLeastOnce;
  256. }
  257. if (RpcQoS2.IsChecked == true)
  258. {
  259. qos = MqttQualityOfServiceLevel.ExactlyOnce;
  260. }
  261. var payload = new byte[0];
  262. if (RpcText.IsChecked == true)
  263. {
  264. payload = Encoding.UTF8.GetBytes(RpcPayload.Text);
  265. }
  266. if (RpcBase64.IsChecked == true)
  267. {
  268. payload = Convert.FromBase64String(RpcPayload.Text);
  269. }
  270. try
  271. {
  272. var rpcClient = new MqttRpcClient(_mqttClient);
  273. await rpcClient.EnableAsync();
  274. var response = await rpcClient.ExecuteAsync(TimeSpan.FromSeconds(5), RpcMethod.Text, payload, qos);
  275. await rpcClient.DisableAsync();
  276. RpcResponses.Items.Add(RpcMethod.Text + " >>> " + Encoding.UTF8.GetString(response));
  277. }
  278. catch (MqttCommunicationTimedOutException)
  279. {
  280. RpcResponses.Items.Add(RpcMethod.Text + " >>> [TIMEOUT]");
  281. }
  282. }
  283. private void ClearRpcResponses(object sender, RoutedEventArgs e)
  284. {
  285. RpcResponses.Items.Clear();
  286. }
  287. private async Task WikiCode()
  288. {
  289. {
  290. // Write all trace messages to the console window.
  291. MqttNetGlobalLogger.LogMessagePublished += (s, e) =>
  292. {
  293. Console.WriteLine($">> [{e.TraceMessage.Timestamp:O}] [{e.TraceMessage.ThreadId}] [{e.TraceMessage.Source}] [{e.TraceMessage.Level}]: {e.TraceMessage.Message}");
  294. if (e.TraceMessage.Exception != null)
  295. {
  296. Console.WriteLine(e.TraceMessage.Exception);
  297. }
  298. };
  299. }
  300. {
  301. // Use a custom identifier for the trace messages.
  302. var clientOptions = new MqttClientOptionsBuilder()
  303. .Build();
  304. }
  305. {
  306. // Create a new MQTT client.
  307. var factory = new MqttFactory();
  308. var mqttClient = factory.CreateMqttClient();
  309. {
  310. // Create TCP based options using the builder.
  311. var options = new MqttClientOptionsBuilder()
  312. .WithClientId("Client1")
  313. .WithTcpServer("broker.hivemq.com")
  314. .WithCredentials("bud", "%spencer%")
  315. .WithTls()
  316. .WithCleanSession()
  317. .Build();
  318. await mqttClient.ConnectAsync(options);
  319. }
  320. {
  321. // Use TCP connection.
  322. var options = new MqttClientOptionsBuilder()
  323. .WithTcpServer("broker.hivemq.com", 1883) // Port is optional
  324. .Build();
  325. }
  326. {
  327. // Use secure TCP connection.
  328. var options = new MqttClientOptionsBuilder()
  329. .WithTcpServer("broker.hivemq.com")
  330. .WithTls()
  331. .Build();
  332. }
  333. {
  334. // Use WebSocket connection.
  335. var options = new MqttClientOptionsBuilder()
  336. .WithWebSocketServer("broker.hivemq.com:8000/mqtt")
  337. .Build();
  338. await mqttClient.ConnectAsync(options);
  339. }
  340. {
  341. // Create TCP based options manually
  342. var options = new MqttClientOptions
  343. {
  344. ClientId = "Client1",
  345. Credentials = new MqttClientCredentials
  346. {
  347. Username = "bud",
  348. Password = "%spencer%"
  349. },
  350. ChannelOptions = new MqttClientTcpOptions
  351. {
  352. Server = "broker.hivemq.org",
  353. TlsOptions = new MqttClientTlsOptions
  354. {
  355. UseTls = true
  356. }
  357. },
  358. };
  359. }
  360. {
  361. // Subscribe to a topic
  362. await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic("my/topic").Build());
  363. // Unsubscribe from a topic
  364. await mqttClient.UnsubscribeAsync("my/topic");
  365. // Publish an application message
  366. var applicationMessage = new MqttApplicationMessageBuilder()
  367. .WithTopic("A/B/C")
  368. .WithPayload("Hello World")
  369. .WithAtLeastOnceQoS()
  370. .Build();
  371. await mqttClient.PublishAsync(applicationMessage);
  372. }
  373. }
  374. // ----------------------------------
  375. {
  376. var options = new MqttServerOptions();
  377. options.ConnectionValidator = c =>
  378. {
  379. if (c.ClientId.Length < 10)
  380. {
  381. c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected;
  382. return;
  383. }
  384. if (c.Username != "mySecretUser")
  385. {
  386. c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
  387. return;
  388. }
  389. if (c.Password != "mySecretPassword")
  390. {
  391. c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
  392. return;
  393. }
  394. c.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
  395. };
  396. var factory = new MqttFactory();
  397. var mqttServer = factory.CreateMqttServer();
  398. await mqttServer.StartAsync(options);
  399. Console.WriteLine("Press any key to exit.");
  400. Console.ReadLine();
  401. await mqttServer.StopAsync();
  402. }
  403. // ----------------------------------
  404. // For UWP apps:
  405. MqttTcpChannel.CustomIgnorableServerCertificateErrorsResolver = o =>
  406. {
  407. if (o.Server == "server_with_revoked_cert")
  408. {
  409. return new[] { ChainValidationResult.Revoked };
  410. }
  411. return new ChainValidationResult[0];
  412. };
  413. {
  414. // Start a MQTT server.
  415. var mqttServer = new MqttFactory().CreateMqttServer();
  416. await mqttServer.StartAsync(new MqttServerOptions());
  417. Console.WriteLine("Press any key to exit.");
  418. Console.ReadLine();
  419. await mqttServer.StopAsync();
  420. }
  421. {
  422. // Configure MQTT server.
  423. var optionsBuilder = new MqttServerOptionsBuilder()
  424. .WithConnectionBacklog(100)
  425. .WithDefaultEndpointPort(1884);
  426. var options = new MqttServerOptions
  427. {
  428. };
  429. options.ConnectionValidator = c =>
  430. {
  431. if (c.ClientId != "Highlander")
  432. {
  433. c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected;
  434. return;
  435. }
  436. c.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
  437. };
  438. var mqttServer = new MqttFactory().CreateMqttServer();
  439. await mqttServer.StartAsync(optionsBuilder.Build());
  440. }
  441. {
  442. // Setup client validator.
  443. var options = new MqttServerOptions
  444. {
  445. ConnectionValidator = c =>
  446. {
  447. if (c.ClientId.Length < 10)
  448. {
  449. c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedIdentifierRejected;
  450. return;
  451. }
  452. if (c.Username != "mySecretUser")
  453. {
  454. c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
  455. return;
  456. }
  457. if (c.Password != "mySecretPassword")
  458. {
  459. c.ReturnCode = MqttConnectReturnCode.ConnectionRefusedBadUsernameOrPassword;
  460. return;
  461. }
  462. c.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
  463. }
  464. };
  465. }
  466. {
  467. // Create a new MQTT server.
  468. var mqttServer = new MqttFactory().CreateMqttServer();
  469. }
  470. {
  471. // Setup and start a managed MQTT client.
  472. var options = new ManagedMqttClientOptionsBuilder()
  473. .WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
  474. .WithClientOptions(new MqttClientOptionsBuilder()
  475. .WithClientId("Client1")
  476. .WithTcpServer("broker.hivemq.com")
  477. .WithTls().Build())
  478. .Build();
  479. var mqttClient = new MqttFactory().CreateManagedMqttClient();
  480. await mqttClient.SubscribeAsync(new TopicFilterBuilder().WithTopic("my/topic").Build());
  481. await mqttClient.StartAsync(options);
  482. }
  483. }
  484. }
  485. }