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

Delphi中使用TMS MQTT连接Azure IoT Hub遇连接丢失问题求助

Delphi通过TMS MQTT连接Azure IoT Hub时持续触发Connection lost错误排查

我在Delphi中尝试通过TMS MQTT组件连接Azure IoT Hub,但每次都会触发Connection lost状态。已尝试两种认证方式:客户端证书认证和连接字符串认证,但均未成功。

证书认证的客户端初始化代码

FMQTTClient := TTMSMQTTClient.Create(nil);

FMQTTClient.BrokerHostName := Format('%s.azure-devices.net', [FIoTHubHostName]);
FMQTTClient.BrokerPort := 443;  // 也曾尝试8883端口,触发"csConnectionRejected_ClientNotAuthorized"错误

FMQTTClient.ClientID := FMyDeviceId;

FMQTTClient.OnConnectedStatusChanged := OnConnectedStatusChanged;
FMQTTClient.OnPublishReceived := OnMessageReceived;
FMQTTClient.OnSSLIOHandlerConfiguration := OnSSLIOHandlerConfiguration;

FMQTTClient.KeepAliveSettings.AutoReconnect:= True;
FMQTTClient.KeepAliveSettings.KeepAliveInterval := 30;
FMQTTClient.KeepAliveSettings.KeepConnectionAlive := True;

FMQTTClient.Credentials.Username :=
    Format('%s.azure-devices.net/%s/?api-version=2020-09-30', [FIoTHubHostName, FMyDeviceId]);

// 客户端证书认证无需密码
FMQTTClient.Credentials.Password := '';

if not IdSSLOpenSSLHeaders.Load then
    raise Exception.Create('Failed to load OpenSSL');
if not IsOpenSSL_TLSv1_2_Available then
    raise Exception.Create('TLSv1_2 is not available');

FMQTTClient.UseSSL := True;

注:同一证书在Python客户端中可正常连接,排除证书本身问题。

SSL连接配置代码

procedure TMQTTClient.OnSSLIOHandlerConfiguration(ASender: TObject;
  var ASSLIOHandler: TIdSSLIOHandlerSocketOpenSSL);
begin
  ASSLIOHandler.SSLOptions.CertFile := FCertFileName;    // 设备证书路径
  ASSLIOHandler.SSLOptions.KeyFile := FKeyFileName;      // 设备私钥路径
  ASSLIOHandler.SSLOptions.Mode := sslmClient;
  ASSLIOHandler.SSLOptions.Method := sslvTLSv1_2;
end;

连接状态回调代码(触发Connection lost的位置)

procedure TMQTTClient.OnConnectedStatusChanged(ASender: TObject;
  const AConnected: Boolean; AStatus: TTMSMQTTConnectionStatus);
var
  lConnStr: string;
begin
  if AConnected {and (AStatus = csConnected)} then
  begin
    ShowMessage('Connected: True');
    if FMQTTClient.Subscribe('$iothub/methods/POST/#') > 0 then
      ShowMessage('Subscribe: Ok')
    else
      ShowMessage('Subscribe: Error');
  end
  else
    if not AConnected then
    begin
      // 客户端未连接时,与Broker的交互会触发异常
      case AStatus of
        csConnectionRejected_InvalidProtocolVersion: lConnStr := 'ConnectionRejected_InvalidProtocolVersion';
        csConnectionRejected_InvalidIdentifier     : lConnStr := 'ConnectionRejected_InvalidIdentifier';
        csConnectionRejected_ServerUnavailable     : lConnStr := 'ConnectionRejected_ServerUnavailable';
        csConnectionRejected_InvalidCredentials    : lConnStr := 'ConnectionRejected_InvalidCredentials';
        csConnectionRejected_ClientNotAuthorized   : lConnStr := 'ConnectionRejected_ClientNotAuthorized'; // 连接被Broker拒绝
        csConnectionLost  : lConnStr := 'ConnectionLost'; // 与Broker的连接丢失
        csConnecting      : lConnStr := 'Connecting';     // 客户端正在尝试连接Broker
        csReconnecting    : lConnStr := 'Reconnecting';   // 客户端正在尝试重新连接Broker
      else
        lConnStr := 'Unknown status:' + IntToStr(Integer(AStatus));
      end;
      ShowMessage('Status: ' + lConnStr);
    end;
end;

各位有什么排查思路?请指出问题所在,感谢帮助!

内容的提问来源于stack exchange,提问作者Roman Dovzhenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 01:23:12