Gunakan SDK untuk Python 2.7 guna menghubungkan klien AMQP ke Alibaba Cloud IoT Platform dan menerima pesan melalui server-side subscription.
Prasyarat
Anda telah memperoleh ID consumer group dan berlangganan ke pesan topik yang diperlukan.
Kelola consumer group AMQP: Anda dapat menggunakan consumer group bawaan (DEFAULT_GROUP) di IoT Platform atau membuat consumer group sendiri.
Konfigurasikan server-side subscription AMQP: Berlangganan ke pesan topik yang diperlukan menggunakan consumer group.
Lingkungan pengembangan
Contoh ini menggunakan Python 2.7.
Unduh SDK
Kami merekomendasikan pustaka Apache Qpid Proton 0.29.0, yang mengenkapsulasi API Python. Untuk mengunduh pustaka dan melihat petunjuknya, kunjungi Qpid Proton 0.29.0.
Instal Qpid Proton. Untuk informasi selengkapnya, lihat Installing Qpid Proton.
Setelah menginstal Qpid Proton, jalankan perintah Python berikut untuk memverifikasi bahwa pustaka SSL tersedia:
import proton;print('%s' % 'SSL present' if proton.SSL.present() else 'SSL NOT AVAILABLE')
Kode contoh
# encoding=utf-8
import sys
import logging
import time
from proton.handlers import MessagingHandler
from proton.reactor import Container
import hashlib
import hmac
import base64
import os
reload(sys)
sys.setdefaultencoding('utf-8')
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
console_handler = logging.StreamHandler(sys.stdout)
def current_time_millis():
return str(int(round(time.time() * 1000)))
def do_sign(secret, sign_content):
m = hmac.new(secret, sign_content, digestmod=hashlib.sha1)
return base64.b64encode(m.digest())
class AmqpClient(MessagingHandler):
def __init__(self):
super(AmqpClient, self).__init__()
def on_start(self, event):
# Titik akhir yang digunakan untuk terhubung ke IoT Platform. Untuk detailnya, lihat panduan koneksi AMQP.
url = "amqps://${YourHost}:5671"
# Menyimpan AccessKey pair secara langsung dalam kode proyek menimbulkan risiko keamanan. Jika kode bocor, AccessKey pair Anda akan terpapar, sehingga membahayakan semua sumber daya dalam akun Anda. Kode berikut mengambil AccessKey pair dari variabel lingkungan sebagai praktik terbaik. Ini hanya sebagai referensi.
accessKey = os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID']
accessSecret = os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']
consumerGroupId = "${YourConsumerGroupId}"
clientId = "${YourClientId}"
# iotInstanceId: ID instans IoT Platform.
iotInstanceId = "${YourIotInstanceId}"
# Algoritma signature. Nilai yang valid: hmacmd5, hmacsha1, dan hmacsha256.
signMethod = "hmacsha1"
timestamp = current_time_millis()
# Untuk petunjuk cara menyusun parameter userName, lihat panduan koneksi AMQP.
userName = clientId + "|authMode=aksign" + ",signMethod=" + signMethod \
+ ",timestamp=" + timestamp + ",authId=" + accessKey \
+ ",iotInstanceId=" + iotInstanceId + ",consumerGroupId=" + consumerGroupId + "|"
signContent = "authId=" + accessKey + "×tamp=" + timestamp
# Hitung signature. Untuk petunjuk cara menyusun password, lihat panduan koneksi AMQP.
passWord = do_sign(accessSecret.encode("utf-8"), signContent.encode("utf-8"))
conn = event.container.connect(url, user=userName, password=passWord, heartbeat=60)
self.receiver = event.container.create_receiver(conn)
# Dipanggil saat koneksi berhasil dibuat.
def on_connection_opened(self, event):
logger.info("Koneksi berhasil dibuat, remoteUrl: %s", event.connection.hostname)
# Dipanggil saat koneksi ditutup.
def on_connection_closed(self, event):
logger.info("Koneksi ditutup: %s", self)
# Dipanggil saat peer jarak jauh menutup koneksi karena error.
def on_connection_error(self, event):
logger.info("Error koneksi")
# Dipanggil saat terjadi error koneksi AMQP, seperti error otentikasi atau soket.
def on_transport_error(self, event):
if event.transport.condition:
if event.transport.condition.info:
logger.error("%s: %s: %s" % (
event.transport.condition.name, event.transport.condition.description,
event.transport.condition.info))
else:
logger.error("%s: %s" % (event.transport.condition.name, event.transport.condition.description))
else:
logging.error("Error transport tidak dispesifikasikan")
# Dipanggil saat pesan diterima.
def on_message(self, event):
message = event.message
content = message.body.decode('utf-8')
topic = message.properties.get("topic")
message_id = message.properties.get("messageId")
print("menerima pesan: message_id=%s, topic=%s, content=%s" % (message_id, topic, content))
event.receiver.flow(1)
Container(AmqpClient()).run()
Konfigurasikan parameter dalam kode di atas sesuai dengan penjelasan pada tabel berikut. Untuk informasi selengkapnya, lihat Hubungkan klien AMQP ke IoT Platform.
Tentukan nilai parameter yang valid. Jika tidak, klien AMQP gagal terhubung ke IoT Platform.
|
Parameter |
Deskripsi |
|
url |
Titik akhir yang digunakan klien AMQP untuk terhubung ke IoT Platform. Format: Untuk informasi lebih lanjut tentang titik akhir yang dapat Anda tentukan untuk variabel |
|
accessKey |
Login ke konsol IoT Platform, arahkan kursor ke foto profil di pojok kanan atas, lalu klik AccessKey Management untuk memperoleh ID AccessKey dan Rahasia AccessKey. Catatan
Jika Anda menggunakan Pengguna Resource Access Management (RAM), Anda harus menyambungkan kebijakan AliyunIOTFullAccess ke Pengguna RAM tersebut untuk memberikan izin mengelola sumber daya IoT Platform. Jika tidak, koneksi akan gagal. Untuk informasi selengkapnya, lihat Akses IoT Platform sebagai Pengguna RAM. |
|
accessSecret |
|
|
consumerGroupId |
ID consumer group dalam instans IoT Platform. Login ke konsol IoT Platform. Di instans yang sesuai, buka untuk melihat ID consumer group Anda. |
|
iotInstanceId |
ID instans IoT Platform. Anda dapat melihat ID instans pada tab Overview di konsol IoT Platform.
|
|
clientId |
ID klien. Anda harus menentukan ID ini sendiri. Panjang ID maksimal 64 karakter. Kami menyarankan Anda menggunakan pengenal unik, seperti UUID, alamat MAC, atau alamat IP server tempat klien AMQP Anda berada. Setelah klien AMQP terhubung dan mulai berjalan, login ke konsol IoT Platform. Pada tab Consumer Groups di halaman untuk instans tersebut, klik View di sebelah consumer group. Halaman Consumer Group Details akan menampilkan parameter ini. Hal ini membantu Anda membedakan klien yang berbeda. |
Hasil contoh
-
Berhasil: Pesan log berikut menunjukkan bahwa klien AMQP telah terhubung ke IoT Platform dan sedang menerima pesan.
202x-xx-xx xx:xx:xx,490 - __main__ - INFO - Connection established, remoteUrl: xxx.amqp.iothub.aliyuncs.com receive message: message_id=13xxx, topic=/xxx/thing/event/property/post, content={"deviceType":"CustomCategory","iotId":"xxx","requestId":"1xxx"} receive message: message_id=13xxx, topic=/xxx/thing/event/property/post, content={"deviceType":"CustomCategory","iotId":"xxx","requestId":"1xxx"}Parameter
Contoh
Deskripsi
message_id
2**************7
ID pesan.
topic
/***********/******/thing/event/property/post
Topik yang digunakan untuk mengirim properti perangkat.
content
{"deviceType":"CustomCategory","iotId":"qPi*","requestId":"161*","checkFailedData":{},"productKey":"g4*","gmtCreate":1613635594038,"deviceName":"de*","items":{"Temperature":{"value":24,"time":1613635594036},"Humidity":{"value":26,"time":1613635594036}}}
Isi pesan.
-
Jika muncul informasi serupa output berikut, klien AMQP gagal terhubung ke IoT Platform.
Gunakan log error untuk memeriksa kode dan pengaturan jaringan Anda. Perbaiki masalah tersebut, lalu jalankan kembali kode.
2021-02-18 16:19:40,993 - proton - ERROR - Couldn't connect: 10053 2021-02-18 16:19:40,996 - __main__ - ERROR - proton.pythonio: Connection error: 10053 2021-02-18 16:19:40,996 - proton - INFO - Disconnected, reconnecting... Traceback (most recent call last): File "xxx", line 87, in <module> Container(AmqpClient()).run() File "xxx", line 181, in run while self.process(): pass File "xxx", line 240, in process event.dispatch(self._global_handler) File "xxx", line 135, in dispatch _dispatch(handler, type.method, self) File "xxx", line 117, in _dispatch handler.on_unhandled(method, *args) File "xxx", line 665, in on_unhandled event.dispatch(self.base) File "xxx", line 135, in dispatch _dispatch(handler, type.method, self) File "xxx", line 115, in _dispatch m(*args) File "xxx", line 892, in on_connection_bound addrs = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM) socket.gaierror: [Errno 11001] getaddrinfo failed
Referensi
Untuk informasi selengkapnya tentang kode kesalahan pesan server-side subscription, lihat Kode kesalahan terkait pesan.