使用MQTT开发即时通讯时远程服务器连接失败求助
解决MQTT WebSocket连接的安全错误问题
我正在使用MQTT开发即时通讯功能,本人是MQTT新手,相关知识储备不足,若有错误恳请指正。发送消息时出现连接错误,错误发生在ConnectClient方法的await client.ConnectAsync(options);处,已确认所有凭证正确,且通过Broker仪表盘能看到服务器有响应。
错误日志
{MQTTnet.Exceptions.MqttCommunicationException: Unable to connect to the remote server ---> System.Net.WebSockets.WebSocketException: Unable to connect to the remote server ---> System.Net.WebSockets.WebSocketException: Unable to connect to the remote server ---> System.Net.Http.WinHttpException: A security error occurred --- End of inner exception stack trace --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult() at System.Net.WebSockets.WinHttpWebSocket.<ConnectAsync>d__18.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Net.WebSockets.WebSocketHandle.<ConnectAsyncCore>d__20.MoveNext() --- End of inner exception stack trace --- at System.Net.WebSockets.WebSocketHandle.<ConnectAsyncCore>d__20.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Net.WebSockets.ClientWebSocket.<ConnectAsyncCore>d__16.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MQTTnet.Implementations.MqttWebSocketChannel.<ConnectAsync>d__8.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MQTTnet.Internal.TaskExtensions.<TimeoutAfterAsync>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MQTTnet.Adapter.MqttChannelAdapter.<ConnectAsync>d__20.MoveNext() --- End of inner exception stack trace --- at MQTTnet.Adapter.MqttChannelAdapter.WrapException(Exception exception) at MQTTnet.Adapter.MqttChannelAdapter.<ConnectAsync>d__20.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at MQTTnet.Client.MqttClient.<ConnectAsync>d__30.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at MQTTnet.Client.MqttClient.<ConnectAsync>d__30.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at VCL_Communications.MQTTClient.<ConnectClient>d__32.MoveNext() in C:\Users\oms\source\Workspaces\Workspace\VolunteerSuite\H2-branch\VCL_CommunicationsSTD\MQTT\MQTTClient.cs:line 280}
出错代码
private async Task ConnectClient() { try { stopFlag = false; //reset the stop flag Guid theGuid = Guid.NewGuid();// new Guid(); // Use WebSocket connection. var options = new MqttClientOptionsBuilder() .WithWebSocketServer(SERVER_URL) .WithCredentials(SERVER_USER, SERVER_PW) .WithClientId(TOPIC_SERVER_PREFIX + "|" + SYSTEM_TYPE + "|" + senderProfileId.ToString() + "|" + theGuid.ToString().Substring(0, 10)) .WithCleanSession(true) .Build(); //add tls if app if (_isApp) { options.ChannelOptions.TlsOptions.UseTls = true; options.ChannelOptions.TlsOptions.SslProtocol = System.Security.Authentication.SslProtocols.Tls12; } // **Here it is failing, returning error** await client.ConnectAsync(options); if (verbose) { WriteLog("MQTT c: Connected to MQTT Server"); } }catch (Exception ex) { WriteLog("MQTT c: Error connecting: " + ex.Message); } }
解决方案建议
1. 排查TLS证书验证问题
- 如果服务器使用自签名证书(仅测试环境适用,生产环境禁止),可以临时禁用证书验证:
在TLS配置中添加证书验证回调:options.ChannelOptions.TlsOptions.CertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; - 生产环境需确保服务器证书有效且被客户端信任,可将证书导入客户端系统的信任存储。
2. 确认WebSocket URL格式正确性
- 若启用TLS,URL必须以
wss://开头,非TLS用ws://;多数MQTT Broker的WebSocket端点路径为/mqtt,例如:wss://your-broker.com:8084/mqtt,需确认SERVER_URL包含正确的路径和端口。
3. 匹配TLS协议版本
- 确认服务器支持TLS 1.2,若服务器支持更高版本,可尝试同时指定多个协议:
options.ChannelOptions.TlsOptions.SslProtocol = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls13;
4. 优化客户端配置方式
建议通过MqttClientOptionsBuilder链式配置TLS,避免Build后修改导致配置不生效:
private async Task ConnectClient() { try { stopFlag = false; Guid theGuid = Guid.NewGuid(); string clientId = $"{TOPIC_SERVER_PREFIX}|{SYSTEM_TYPE}|{senderProfileId}|{theGuid.ToString().Substring(0, 10)}"; var optionsBuilder = new MqttClientOptionsBuilder() .WithWebSocketServer(SERVER_URL) .WithCredentials(SERVER_USER, SERVER_PW) .WithClientId(clientId) .WithCleanSession(true); if (_isApp) { optionsBuilder.WithTls(tlsOptions => { tlsOptions.UseTls = true; tlsOptions.SslProtocol = System.Security.Authentication.SslProtocols.Tls12; // 测试环境可添加证书验证回调 // tlsOptions.CertificateValidationCallback = (_, _, _, _) => true; }); } var options = optionsBuilder.Build(); await client.ConnectAsync(options); if (verbose) { WriteLog("MQTT c: Connected to MQTT Server"); } } catch (Exception ex) { WriteLog($"MQTT c: Error connecting: {ex.Message}\n{ex.StackTrace}"); } }
5. 检查网络与代理
- 确认客户端防火墙/杀毒软件未拦截WebSocket端口;
- 若使用代理,需配置MQTT客户端的代理设置,或确保代理允许WebSocket流量。
内容的提问来源于stack exchange,提问作者TheHunter Shergill
相关产品推荐
相关产品推荐

