IoT Amazon MQTT Client

AWS IoT Nedir?

AWS IoT, sensörler, aktüatörler, gömülü mikrodenetleyiciler veya akıllı cihazlar gibi internete bağlı cihazlar ile AWS Cloud arasında güvenli, çift yönlü iletişim sağlar. Bu, birden çok cihazdan telemetri verisi toplamanıza ve verileri depolayıp analiz etmenize olanak tanır. Ayrıca kullanıcılarınızın bu cihazları telefonlarından veya tabletlerinden kontrol etmelerini sağlayan uygulamalar da oluşturabilirsiniz.

 

Mesaj broker'ı

Cihazların ve AWS IoT uygulamalarının birbirine mesaj yayınlaması ve almasını sağlayan güvenli bir mekanizma sunar. Yayınlamak ve abone olmak için doğrudan MQTT protokolünü veya WebSocket üzerinden MQTT'yi kullanabilirsiniz.

 

AWS IoT mesaj broker'ı, AWS IoT'ye/AWS IoT'den mesaj gönderilmesini ve alınmasını sağlayan bir publish/subscribe broker hizmetidir. AWS IoT ile iletişim kurarken, bir istemci Sensor/temp/room1 gibi bir topic'e adreslenmiş bir mesaj gönderir.

 

Mesaj broker'ı da mesajı, o konu için mesaj almaya kayıtlı tüm istemcilere gönderir. Mesajı gönderme eylemine publishing denir. Bir konu filtresi için mesaj almaya kaydolma eylemine subscribing denir.

 

Konu ad alanı, her AWS hesabı ve bölge çifti için izole edilmiştir. Örneğin, bir AWS hesabı için Sensor/temp/room1 konusu, başka bir AWS hesabı için Sensor/temp/room1 konusundan bağımsızdır. Bu, bölgeler için de geçerlidir. us-east-1'deki aynı AWS hesabındaki Sensor/temp/room1 konusu, us-east-2'deki aynı konudan bağımsızdır. AWS IoT, AWS hesapları ve bölgeleri arasında mesaj göndermeyi ve almayı desteklemez.

 

Mesaj broker'ı, tüm istemci oturumlarının ve her oturum için aboneliklerin bir listesini tutar. Bir konuda bir mesaj yayımlandığında, broker konuya eşlenen aboneliklere sahip oturumları kontrol eder. Ardından broker, yayımlama mesajını şu anda bağlı bir istemcisi olan tüm oturumlara iletir.

 

MQTT Client

TsgcIoTAmazon_MQTT_Client, AWS IoT'ye bağlanmak için kullanılan bileşendir. Bir istemci yalnızca bir cihaza bağlanabilir. İstemci, düz MQTT protokolünü kullanarak bağlanır ve bir X.509 İstemci Sertifikası kullanarak kimlik doğrular.

 

AWS IoT'a bağlanmak için, istemcinin aşağıdaki özelliklere ihtiyacı vardır:

 

Amazon.ClientId: istemci tanımlaması, isteğe bağlı.

Amazon.Endpoint: MQTT istemcisinin bağlanacağı sunucu adı.

Amazon.Port: varsayılan olarak 8883 portunu kullanır. Port 443 ise, bağlanmak için otomatik olarak ALPN kullanır (özel Indy sürümü gerektirir).

 

AWS IoT Core, mesaj yayınlamak ve mesajlara abone olmak için MQTT ve MQTT over WebSocket Secure (WSS) protokollerini kullanan cihazları ve istemcileri destekler. Aşağıdaki tablo, AWS IoT cihaz uç noktalarının desteklediği protokolleri ve kullandıkları kimlik doğrulama yöntemleri ile portları listeler.

 

Protocol Authentication Port ALPN Protocol Name
MQTT over WebSocket Signature Version 4 443  
MQTT over WebSocket Özel Kimlik Doğrulama 443  
MQTT X.509 istemci sertifikası 443 x-amzn-mqtt-ca
MQTT X.509 istemci sertifikası 8883  
MQTT Özel Kimlik Doğrulama 443 mqtt

 

 

Certificates Authentication

Amazon AWS konsolunuzda sertifikalar oluşturmanız ve saklandıkları yolu ayarlamanız gerekir.

 

IOHandler olarak OpenSSL kullanırken sertifikayı aşağıdaki yollarda ayarlamanız gerekir

 

Certificate.Enabled: sertifikaları kullanmak istiyorsanız True olarak ayarlayın.

Certificate.CertFile: X.509 istemci sertifikasının yolu.

Certificate.KeyFile: X.509 istemci anahtar dosyasının yolu.

 

IOHandler olarak SChannel kullanarak, önce PEM Sertifikası + Anahtarı bir PFX sertifikasına dönüştürün. Bu, OpenSSL ikili dosyalarını gerektirir:

 


openssl pkcs12 -inkey 884ccf73ff-private.pem.key -in 884ccf73ff-certificate.pem.crt -export -out 884ccf73ff-certificate.pfx

Ardından aşağıdaki yolları ayarlayın (anahtar dosyası zaten sertifikaya dahil olduğundan onu ayarlamaya gerek yoktur).

 

Certificate.Enabled: sertifikaları kullanmak istiyorsanız True olarak ayarlayın.

Certificate.CertFile: PFX sertifikasının yolu

 

SignatureV4 Kimlik Doğrulaması

Amazon AWS konsolunuzda bir kullanıcı oluşturmanız ve WebSocket isteğini imzalamak için kullanılacak Access ve Secret anahtarlarını kaydetmeniz gerekir.

 

SignatureV4.Enabled: bu kimlik doğrulama türünü kullanmak istiyorsanız True olarak ayarlayın.

SignatureV4.Region: cihazınızın bulunduğu bölge (örnek: us-east-1).

SignatureV4.AccessKey: Amazon konsolunuzda oluşturulan veya geçici bir kimlik bilgisi olarak elde edilen erişim anahtarı.

SignatureV4.SecretKey: amazon konsolunuzda oluşturulan veya geçici kimlik bilgisi olarak alınan gizli anahtar

SignatureV4.SessionToken: (koşullu) Temporary Security Credentials kullanıyorsanız, güvenlik token'ını buraya ayarlayın.

OpenSSL_Options: openSSL kütüphanelerinin yapılandırması.

APIVersion: hangi OpenSSL API'sinin kullanılacağını tanımlamaya olanak tanır.

oslAPI_1_0: API 1.0 OpenSSL kullanır, Indy tarafından desteklenen en son sürümdür

oslAPI_1_1: API 1.1 OpenSSL kullanır, özel Indy kütüphanemizi gerektirir ve OpenSSL 1.1.1 kütüphanelerinin (TLS 1.3 desteğiyle) kullanılmasına izin verir.

oslAPI_3_0: API 3.0 OpenSSL kullanır, özel Indy kütüphanemizi gerektirir ve OpenSSL 3.0.0 kütüphanelerinin (TLS 1.3 desteğiyle) kullanılmasına olanak tanır.

LibPath: burada openSSL kütüphanelerinin nerede bulunduğunu yapılandırabilirsiniz

oslpNone: bu varsayılandır, OpenSSL kitaplıkları ikili dosyanın bulunduğu klasörde veya bilinen bir yolda olmalıdır.

oslpDefaultFolder: tüm IDE kişilikleri için kütüphanelerin bulunması gereken openSSL yolunu otomatik olarak ayarlar.

oslpCustomFolder: seçilen seçenek buysa, tam yolu LibPathCustom özelliğinde tanımlayın.

LibPathCustom: LibPath = oslpCustomFolder olduğunda openSSL kütüphanelerinin bulunduğu tam yolu burada tanımlayın.

UnixSymLinks: Unix sistemlerinde SymLinks yüklemesini etkinleştirin veya devre dışı bırakın (varsayılan olarak etkindir, OSX64 hariç):

oslsSymLinksDefault: OSX64 dışında varsayılan olarak etkindir (MacOS Monterey'den sonra kütüphaneyi sürüm olmadan yüklemeye çalışırken başarısız olur).

oslsSymLinksLoadFirst: SymLinks'i yükle ve bunu sürüm kitaplıklarını yüklemeyi denemeden önce yap.

oslsSymLinksLoad: Sürüm kütüphanelerini yüklemeyi denedikten sonra SymLinks'i yükle.

oslsSymLinksDontLoad: SymLink'leri yükleme.

 

*SignatureV4, Indy 10.5.7+ gerektirir

Özel Kimlik Doğrulama

Özel kimlik doğrulama, authorizer kaynaklarını kullanarak istemcilerin nasıl kimlik doğrulanacağını ve yetkilendirileceğini tanımlamanıza olanak tanır. Cihaz, kimlik bilgilerini ya isteğin başlık alanlarında veya sorgu parametrelerinde (MQTT over WebSockets protokolleri için) ya da MQTT CONNECT mesajının kullanıcı adı ve parola alanında (MQTT ve MQTT over WebSockets protokolleri için) geçirir.

 

CustomAuthentication.Enabled: bu tür Kimlik Doğrulamasını kullanmak istiyorsanız True olarak ayarlayın.

CustomAuthentication.Parameters: sunucuya geçirilecek sorgu parametrelerini burada ayarlayın (varsayılan /mqtt'dir)

CustomAuthentication.Headers: burada özel başlık alanlarını koyabilirsiniz.

CustomAuthentication.WebSockets: true olarak ayarlanırsa, bağlantı WebSocket protokolü üzerinden çalışır, aksi takdirde düz TCP üzerinden çalışır.

 

MQTTAuthentication.Enabled: mqtt bağlantısında kullanıcı adı/parola geçirmeniz gerekiyorsa, bu özelliği etkinleştirin

MQTTAuthentication.Username: mqtt bağlantısının kullanıcı adı

MQTTAuthentication.Password: mqtt bağlantısının gizli anahtarı.

 

 

İstemci, istemci bağlantısını tanımlamak için isteğe bağlı olarak bir ClientId gönderebilir, ardından diğer istemciler bu istemci her bağlandığında, abone olduğunda, bağlantısı kesildiğinde... bir bildirim almak için abone olabilir.

 

Authorization

8883 numaralı bağlantı noktasını kullanarak bağlanamıyorsanız ve taşıma olarak TCP kullanıyorsanız (varsayılandır), amazon istemcilere ve aboneliklere yetki verip vermemek için "AWS IoT Core policy" kullanır. Büyük olasılıkla istemci kimliğinizi yetkilendirmeniz gerekir.

Amazon AWS konsolunuza girin, IoT Core'a gidin ve "Secure/Policies" menüsüne erişin, orada IoT Thing'inize ekli politikayı seçin ve sonunda bağlantının nasıl yapılandırıldığını kontrol edin. Örnek:

 

{

"Effect": "Allow",

"Action": [

"iot:Connect"

],

"Resource": [

"arn:aws:iot:us-east-1:222178873557:client/sdk-java",

"arn:aws:iot:us-east-1:222178873557:client/basicPubSub",

"arn:aws:iot:us-east-1:222178873557:client/sdk-nodejs-*"

]

}

 

Bu yapılandırma, yalnızca şu kimliklere sahip istemcilerin bağlanmasına izin verileceği anlamına gelir: sdk-java, basicPubSub ve sdk-nodejs-*. Buna göre değiştirin ve tekrar deneyin.

Hâlâ çalışmıyorsa, günlüğü etkinleştirin ve cloudwatch'ta neden bağlanamadığınızın nedenini kontrol edin.

 

Diğer özellikler

 

MQTTHeartBeat: etkinleştirilirse, her x saniyede bir ping göndererek MQTT bağlantısını canlı tutmaya çalışır.

 

Interval: her ping arasındaki saniye sayısı.

 

MQTTAuthentication: etkinleştirilirse, MQTT bağlantısına kullanıcı adını ve parolayı dahil eder

 

UserName: kullanıcının adı

Password: gizli dize

 

WatchDog: etkinleştirilirse, beklenmeyen bir bağlantı kesilmesi algılandığında, sunucuya otomatik olarak yeniden bağlanmaya çalışır.

 

Interval: yeniden bağlanma denemelerinden önceki saniyeler.

 

Attempts: maksimum yeniden bağlanma deneme sayısı; sıfır sınırsız anlamına gelir.

 

LogFile: etkinleştirilirse, soket mesajlarını bir günlük dosyasına kaydeder (hata ayıklama için yararlıdır). Günlük dosyasına erişim, birkaç thread'den erişilirse thread güvenli değildir.

 

Enabled: etkinleştirilirse, soket aracılığıyla her mesaj alındığında ve gönderildiğinde bir dosyaya kaydedilir.

 

FileName: dosya adının tam yolu.

 

Uygulama (Implementation)

 

Amazon MQTT uygulaması MQTT sürüm 3.1.1'e dayanır ancak spesifikasyondan şu şekilde sapar:

 

 

Connect to AWS IoT

İlk olarak, AWS console'unuza oturum açmalı, yeni bir cihaz kaydetmeli ve bu cihaz için bir X.509 sertifikası oluşturmalısınız. Bittikten sonra, yeni bir TsgcIoTAmazon_MQTT_Client oluşturabilir ve AWS IoT Sunucusuna bağlanabilirsiniz. Örneğin:

 


oClient := TsgcIoTAmazon_MQTT_Client.Create(nil);
oClient.Amazon.Endpoint := 'a2ohgdjqitsmij-ats.iot.us-west-2.amazonaws.com';
oClient.Amazon.ClientId := 'sgcWebSockets';
oClient.Certificate.CertFile := 'amazon-certificate.pem.crt';
oClient.Certificate.KeyFile := 'amazon-private.pem.key';
oClient.OnMQTTConnect := OnMQTTConnectEvent;
oClient.Active := True;
 
procedure OnMQTTConnect(Connection: TsgcWSConnection; const Session: Boolean; const ReturnCode: TmqttConnReturnCode);
begin
  ShowMessage('Connected to AWS');
end;

Konular

Mesaj broker'ı, mesajları yayınlayan istemcilerden abone olan istemcilere yönlendirmek için konuları kullanır. Konu hiyerarşisini ayırmak için eğik çizgi (/) kullanılır. Aşağıdaki tablo, abone olurken konu filtresinde kullanılabilen joker karakterleri listeler. # Abone olduğunuz konudaki son karakter olmalıdır. Geçerli ağacı ve tüm alt ağaçları eşleştirerek joker karakter olarak çalışır.

Örneğin, Sensor/# aboneliği Sensor/, Sensor/temp, Sensor/temp/room1'e yayınlanan mesajları alır, ancak Sensor'a yayınlanan mesajları almaz.

+ Konu hiyerarşisinde tam olarak bir öğeyle eşleşir. Örneğin, Sensor/+/room1'e abonelik, Sensor/temp/room1, Sensor/moisture/room1 vb. adreslerine yayınlanan mesajları alır.

 


oClient := TsgcIoTAmazon_MQTT_Client.Create(nil);
...
oClient.OnSubscribe := OnSubscribeEvent;
 
vPacketIdentifier := oClient.Subscribe('Sensor/moisture/room1');
  
procedure OnMQTTSubscribe(Connection: TsgcWSConnection; aPacketIdentifier: Word; aCodes: TsgcWSSUBACKS);
begin
  if vPacketIdentifier = aPacketIdentifier then
    ShowMessage('Subscribed to topic Sensor/moisture/room1'); 
end;
 
// Client, can send a message using Publish method.
oClient.Publish('Sensor/moisture/room1', '{"temp"=10}');
  
// Messages received from server, are dispatched OnMQTTPublishEvent.
// For extended payload access (string, bytes or stream), use OnMQTTPublishEx.
procedure OnMQTTPublish(Connection: TsgcWSConnection; aTopic, aText: string);
begin
  DoLog('Received Message: ' + aTopic + ' ' + aText);
end;

Ayrılmış Konular

Aşağıdaki yöntemler, ayrılmış konulara abone olmak / yayın yapmak için kullanılır.

 

Subscribe_ClientConnected(const aClientId: String): belirtilen istemci ID'sine sahip bir MQTT istemcisi AWS IoT'ye bağlandığında AWS IoT bu konuya yayınlar

Subscribe_ClientDisconnected(const aClientId: String): Belirtilen istemci ID'sine sahip bir MQTT istemcisi AWS IoT'den bağlantısını kestiğinde AWS IoT bu konuya yayımlar

Subscribe_ClientSubscribed(const aClientId: String): Belirtilen istemci ID'sine sahip bir MQTT istemcisi bir MQTT konusuna abone olduğunda AWS IoT bu konuya yayımlar

Subscribe_ClientUnSubscribed(const aClientId: String): AWS IoT, belirtilen client ID'sine sahip bir MQTT istemcisi bir MQTT konusunun aboneliğini kaldırdığında bu konuya yayın yapar

 

Publish_Rule(const aRuleName, aText: String): Bir cihaz veya uygulama, kuralları doğrudan tetiklemek için bu konuya yayınlar

 

Publish_DeleteShadow(const aThingName, aText: String): Bir cihaz veya bir uygulama, bir shadow'u silmek için bu konuya yayın yapar

Subscribe_DeleteShadow(const aThingName: String): Bir cihaz veya bir uygulama, bir gölgeyi silmek için bu konuya abone olur

Subscribe_ShadowDeleted(const aThingName: String): Device Shadow hizmeti, bir shadow silindiğinde bu konuya mesaj gönderir

Subscribe_ShadowRejected(const aThingName: String): Bir gölgeyi silme isteği reddedildiğinde, Device Shadow hizmeti bu konuya mesaj gönderir

Publish_ShadowGet(const aThingName, aText: String): Bir uygulama veya thing, bir shadow almak için bu konuya boş bir mesaj yayınlar

Subscribe_ShadowGet(const aThingName: String): Bir uygulama veya bir thing, bir shadow almak için bu konuya abone olur

Subscribe_ShadowGetAccepted(const aThingName: String): Device Shadow hizmeti, bir gölge (shadow) isteği başarıyla yapıldığında bu konuya mesaj gönderir

Subscribe_ShadowGetRejected(const aThingName: String): Device Shadow hizmeti, bir gölge isteği reddedildiğinde bu konuya mesaj gönderir

Publish_ShadowUpdate(const aThingName, aText: String): Bir thing veya uygulama, bir shadow'u güncellemek için bu konuya yayın yapar

Subscribe_ShadowUpdateAccepted(const aThingName: String): Device Shadow hizmeti, bir shadow'a bir güncelleme başarıyla yapıldığında bu konuya mesaj gönderir

Subscribe_ShadowUpdateRejected(const aThingName: String): Bir shadow güncellemesi reddedildiğinde Device Shadow hizmeti bu konuya mesaj gönderir

Subscribe_ShadowUpdateDelta(const aThingName: String): Device Shadow hizmeti, bir shadow'un reported ve desired bölümleri arasında bir fark algılandığında bu konuya mesaj gönderir

Subscribe_ShadowUpdateDocuments(const aThingName: String): shadow'a yapılan bir güncelleme başarıyla gerçekleştirildiğinde AWS IoT bu konuya bir durum belgesi yayınlar

 

Persistent Sessions

Kalıcı bir oturum, bir MQTT mesaj broker'ına devam eden bir bağlantıyı temsil eder. Bir istemci kalıcı bir oturum kullanarak AWS IoT mesaj broker'ına bağlandığında, mesaj broker'ı istemcinin bağlantı sırasında yaptığı tüm abonelikleri kaydeder. İstemci bağlantısını kestiğinde, mesaj broker'ı onaylanmamış QoS 1 mesajlarını ve istemcinin abone olduğu konulara yayınlanan yeni QoS 1 mesajlarını saklar. İstemci kalıcı oturuma yeniden bağlandığında, tüm abonelikler yeniden etkinleştirilir ve saklanan tüm mesajlar istemciye saniyede en fazla 10 mesaj hızında gönderilir.

 

OnMQTTBeforeConnect olayında cleanSession parametresini False olarak ayarlayarak bir MQTT kalıcı oturumu oluşturursunuz. İstemci için oturum yoksa, yeni bir kalıcı oturum oluşturulur. İstemci için zaten bir oturum varsa, devam ettirilir.

 

Cihazların, kalıcı bir oturumun mevcut olup olmadığını belirlemek için OnMQTTConnect olayındaki Session özniteliğine bakması gerekir. Session True ise, kalıcı bir oturum mevcuttur ve saklanan mesajlar istemciye teslim edilir. Session False ise, kalıcı bir oturum yoktur ve istemci konu (topic) filtrelerine yeniden abone olmalıdır.

 

Kalıcı oturumların varsayılan süre sonu süresi 1 saattir. Süre sonu, mesaj broker'ı bir istemcinin bağlantısının kesildiğini (MQTT bağlantı kesme veya zaman aşımı) algıladığında başlar. Kalıcı oturum süre sonu süresi, standart sınır artırma süreci aracılığıyla artırılabilir. Bir istemci, süre sonu süresi içinde oturumunu sürdürmemişse, oturum sonlandırılır ve ilişkili saklanan mesajlar atılır. Süre sonu süresi yaklaşıktır, oturumlar yapılandırılan süreden 30 dakikaya kadar daha uzun (ancak daha az değil) kalıcı olabilir.

 

Geçici Kimlik Bilgileri

AWS IoT Core, Identity Pools aracılığıyla elde edilen Geçici Kimlik Bilgileriyle çalışabilir, 2 tür Kimlik vardır:

 

 

Unauthenticated

Kimliği doğrulanmamış kimlik bilgileri kullanıyorsanız, politikayı IAM menüsünde otomatik olarak oluşturulan UnAuthenticated Role'üne eklemeniz yeterlidir. Ardından istemciyi Cognito hizmeti tarafından döndürülen Access, Secret Key ve Token'ı ayarlayarak yapılandırın.

Kimliği doğrulanmamış kimlik bilgilerini almak için .NET'te aşağıdaki kodu bulabilirsiniz

 


CognitoAWSCredentials credentials = new CognitoAWSCredentials(
    "us-east-1:cc3c9c48-646d-44ef-bfd5-0c5fb2f0882f", // Identity pool ID
    Amazon.RegionEndpoint.USEast1 // Region
);
 
var identityPoolId = credentials.GetCredentialsAsync();
 
AmazonCognitoIdentityClient cognitoClient = new AmazonCognitoIdentityClient(
    credentials, // the anonymous credentials
    Amazon.RegionEndpoint.USEast1 // the Amazon Cognito region
);
 
GetIdRequest idRequest = new GetIdRequest();
idRequest.AccountId = "222178873557";
idRequest.IdentityPoolId = "us-east-1:cc3c9c48-646d-44ef-bfd5-0c5fb2f0882f";
 
GetIdResponse idResp = cognitoClient.GetId(idRequest);
 
string AccessKey = identityPoolId.Result.AccessKey;
string SecretKey = identityPoolId.Result.SecretKey;
string SessionToken = identityPoolId.Result.Token;
 
string IdentityId = idResp.IdentityId;

Authenticated

Kimliği doğrulanmış kimlik bilgileri, IAM menüsünde otomatik olarak oluşturulan Authenticated Role'de politikanın eklenmesini ve kullanıcının politikasının AWS IoT Core politikalarına eklenmesini gerektirir.

Bu yüzden IoT Core policies menüsünde yeni bir politika oluşturun ve her yeni kullanıcı kimlik doğruladığında, bu politikayı bu kullanıcıya ekleyin.

Bir ilke eklemek veya bir lambda işlevi oluşturmak için aşağıdaki AWS komutunu kullanabilirsiniz.

 

aws iot attach-policy --policy-name PolicyName --target us-east-1:XXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

 

 

Device Provisioning

Fleet Provisioning hizmeti aşağıdaki MQTT API işlemlerini destekler:

 

 

CreateCertificateFromCsr

 

Sertifikayı oluşturmak için CertificateSigningRequest'i parametre olarak geçirerek CreateCertificateFromCsr yöntemini kullanın. Bu isteğe yanıt almak için, önce şu yöntemlere abone olun: SubscribeCreateCertificateFromCsrResponse ve SubscribeCreateCertificateFromCsrError

 

CreateKeysAndCertificate

 

Yeni bir sertifika ve anahtar oluşturmak için CreateKeysAndCertificate yöntemini kullanın. Bu isteğe yanıt almak için, önce şu yöntemlere abone olun: SubscribeCreateKeysAndCertificateResponse ve SubscribeCreateKeysAndCertificateError

 

RegisterThing

 

Yeni bir thing kaydetmek için, parametre olarak Template Name'i ve JSON formatındaki Payload'ı geçirerek RegisterThing yöntemini kullanın. Bu isteğe yanıt almak için, önce SubscribeRegisterThingResponse ve SubscribeRegisterThingError yöntemlerine abone olun.