You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 22:50:39