MQTT.js, JavaScript için en yaygın kullanılan MQTT client’ıdır. Aynı paket Node.js’te (TCP, TLS veya WebSocket üzerinden) ve tarayıcıda (WebSocket üzerinden) çalışır, MQTT 3.1.1 ve 5’i destekler ve 5. sürümden bu yana TypeScript tipleri ile promise tabanlı metotlarla birlikte gelir. Bu eğitim, v5 API’sini baştan sona ele alır.
MQTT.js’i kurun
npm install mqttÖrnekler ES modüllerini (import) ve herkese açık HiveMQ sandbox’ını kullanır. Bunları .mjs dosyaları olarak kaydedin veya package.json içinde "type": "module" ayarlayın.
Bağlantı URL’leri: hangi protokol nerede
| URL şeması | Taşıma katmanı | Tipik port | Node.js | Tarayıcı |
|---|---|---|---|---|
mqtt:// | Düz TCP | 1883 | Evet | Hayır |
mqtts:// | TLS | 8883 | Evet | Hayır |
ws:// | WebSocket | 8000, 8083, 80 | Evet | Yalnızca http:// sayfalarında |
wss:// | Güvenli WebSocket | 8884, 8084, 443 | Evet | Evet |
Portlar ve WebSocket yolları broker’a göre değişir — HiveMQ veya EMQX sayfalarına bakın ya da MQTT portları rehberini okuyun.
Node.js’te abone olma ve publish etme
Klasik olay tabanlı API: mqtt.connect() hemen bir client döndürür ve bağlantı ilerledikçe olaylar yayar.
import mqtt from 'mqtt';
const topic = 'testmqtt/js-demo/hello';
const client = mqtt.connect('mqtt://broker.hivemq.com:1883', {
clientId: `js-demo-${Math.random().toString(16).slice(2, 10)}`,
clean: true,
keepalive: 60,
reconnectPeriod: 2000, // ms between reconnect attempts; 0 disables
connectTimeout: 10_000,
});
client.on('connect', () => {
console.log('connected');
client.subscribe('testmqtt/js-demo/#', { qos: 1 }, (err) => {
if (err) return console.error('subscribe failed:', err.message);
client.publish(topic, JSON.stringify({ hello: 'world' }), { qos: 1 });
});
});
client.on('message', (topic, payload, packet) => {
console.log(`${topic} (retain=${packet.retain}): ${payload.toString()}`);
});
client.on('reconnect', () => console.log('reconnecting...'));
client.on('offline', () => console.log('offline'));
client.on('error', (err) => console.error('error:', err.message));payload bir Buffer’dır — metin için toString(), JSON için JSON.parse(payload.toString()) çağırın. connect olayı her yeniden bağlanmadan sonra tekrar tetiklenir; clean: true ile broker aboneliklerinizi unutur, bu yüzden handler içinde abone olmak güvenli yöntemdir. MQTT.js ayrıca varsayılan olarak yeniden bağlandığında aboneliklerini yeniler (resubscribe: true).
connectAsync ile async/await
Script’ler, testler ve serverless fonksiyonlar için MQTT.js v5’teki promise API’si çok daha doğal okunur:
import mqtt from 'mqtt';
const client = await mqtt.connectAsync('mqtts://broker.hivemq.com:8883', {
protocolVersion: 5,
});
client.on('message', (topic, payload) => {
console.log(topic, payload.toString());
});
try {
const granted = await client.subscribeAsync('testmqtt/js-demo/#', { qos: 1 });
console.log('granted:', granted.map((g) => `${g.topic} QoS ${g.qos}`).join(', '));
await client.publishAsync('testmqtt/js-demo/async', 'sent with publishAsync', {
qos: 1,
retain: false,
});
await new Promise((resolve) => setTimeout(resolve, 2000));
} finally {
await client.endAsync();
}connectAsync(), client bağlanmadan önce bir error yaydığında — örneğin broker kimlik bilgilerinizi reddettiğinde — reject eder; böylece bunu normal bir try/catch ile ele alabilirsiniz. Erişilemeyen bir host için varsayılan olarak denemeye devam eder; bunun yerine hızlıca hata vermesi için üçüncü argüman olarak false geçin. publishAsync(), broker QoS 1 veya 2 mesajını onayladığında resolve olur. Her seviyenin neyi garanti ettiğini öğrenmek için MQTT QoS seviyeleri yazısına bakın.
MQTT.js mesajlarınızı canlı izleyin
Node.js’te TLS, kimlik bilgileri ve MQTT 5 seçenekleri
Production broker’ları TLS ve kimlik doğrulama gerektirir. Kimlik bilgileri bağlantı seçeneklerine girer; herkesçe güvenilen bir sertifikaya sahip broker için mqtts:// yeterlidir. Özel bir CA için CA sertifikasını (ve karşılıklı TLS için bir client sertifikası ile anahtarını) geçin:
import { readFileSync } from 'node:fs';
import mqtt from 'mqtt';
const client = await mqtt.connectAsync('mqtts://broker.example.com:8883', {
clientId: 'billing-service-01',
username: process.env.MQTT_USERNAME,
password: process.env.MQTT_PASSWORD,
protocolVersion: 5,
clean: false,
properties: { sessionExpiryInterval: 3600 },
// Only for a private CA / mutual TLS:
// ca: readFileSync('ca.crt'),
// cert: readFileSync('client.crt'),
// key: readFileSync('client.key'),
will: {
topic: 'services/billing/status',
payload: Buffer.from('offline'),
qos: 1,
retain: true,
},
});
await client.publishAsync('services/billing/status', 'online', { qos: 1, retain: true });
await client.publishAsync('orders/created', JSON.stringify({ id: 42 }), {
qos: 1,
properties: {
contentType: 'application/json',
messageExpiryInterval: 60,
userProperties: { source: 'billing' },
},
});Yerel testler dışında asla rejectUnauthorized: false ayarlamayın — sertifika doğrulamasını kapatır. Kimlik bilgilerini kaynak kodda değil, ortam değişkenlerinde tutun. will seçeneği, servis bağlantıyı kesmeden çökerse broker’ın publish edeceği bir Last Will kaydeder; retain: true ise en son durumu yeni abonelere açık tutar (bkz. retained mesajlar). MQTT 5 özelliklerine gerçekten ihtiyacınız olup olmadığı MQTT 5 ile 3.1.1 karşılaştırması yazısında ele alınıyor.
Temiz bir şekilde kapatma
Uzun süre çalışan bir Node.js servisi bağlantıyı düzgün biçimde kesmelidir; böylece işlemdeki QoS 1/2 mesajları tamamlanır ve broker normal bir yeniden başlatmada Last Will’inizi tetiklemez:
process.on('SIGTERM', async () => {
await client.publishAsync('services/billing/status', 'offline', { qos: 1, retain: true });
await client.endAsync();
process.exit(0);
});Tarayıcıda MQTT.js
Tarayıcıda yalnızca WebSocket URL’leri çalışır. HTTPS bir sayfada wss:// kullanmanız gerekir; aksi hâlde tarayıcı bağlantıyı mixed content (karışık içerik) olarak engeller:
import mqtt from 'mqtt';
const client = mqtt.connect('wss://broker.hivemq.com:8884/mqtt', {
clientId: `web-${crypto.randomUUID().slice(0, 8)}`,
});
client.on('connect', () => client.subscribe('testmqtt/js-demo/#'));
client.on('message', (topic, payload) => {
const li = document.createElement('li');
li.textContent = `${topic}: ${payload.toString()}`;
document.querySelector('#messages').append(li);
});Vite, webpack 5 ve Next.js derleyicisi gibi modern bundler’lar, import mqtt from 'mqtt' yazdığınızda tarayıcı build’ini otomatik seçer. Bir bundler Node yerleşik modülleri hakkında hata verirse, bunun yerine hazır paketi mqtt/dist/mqtt.min.js üzerinden import edin. Bundler olmadan aynı dosyayı bir CDN’den <script> etiketiyle yükleyip global mqtt nesnesini kullanın. WebSocket üzerinden MQTT rehberi yolları ve portları ayrıntılı olarak ele alır.
React’te MQTT.js kullanımı
En yaygın hata, her render’da yeni bir client oluşturmaktır. Client’ı useEffect içinde bir kez oluşturun ve cleanup’ta mutlaka sonlandırın — React StrictMode geliştirme ortamında effect’leri iki kez mount eder; cleanup olmadan yinelenen bağlantılar ve yinelenen mesajlar alırsınız:
import { useEffect, useState } from 'react';
import mqtt from 'mqtt';
export function useMqttMessages(url: string, topic: string) {
const [messages, setMessages] = useState<string[]>([]);
useEffect(() => {
const client = mqtt.connect(url);
client.on('connect', () => client.subscribe(topic));
client.on('message', (_t, payload) => {
setMessages((prev) => [...prev.slice(-99), payload.toString()]);
});
return () => {
client.end();
};
}, [url, topic]);
return messages;
}Next.js’te MQTT.js tarayıcı API’lerini kullandığı için onu yalnızca Client Component’lerden ('use client') veya mqtt:// ya da mqtts:// kullanan sunucu tarafı route handler’lardan çağırın. Daha büyük uygulamalarda tek bir client’ı bir context provider’a koyup paylaşın.
Hata yönetimi
- Her zaman bir
errorlistener’ı ekleyin. Node.js’te işlenmemiş birerrorolayı process’i çökertir. - Hatalı kimlik bilgileri yeniden denemeye devam eder. Olay API’sinde reddedilen bir CONNECT
erroryayar ve MQTT.js yeniden bağlanmaya devam eder.err.codedeğerini inceleyin ve yeniden denemek anlamsızsaclient.end()çağırın. Kodları MQTT reason code aracı ile sorgulayın. - Hemen ardından bağlantı kopmasıyla gelen sonsuz yeniden bağlanma döngüleri genellikle yinelenen bir client ID’si veya aboneliğinizi reddeden bir ACL anlamına gelir. MQTT bağlantı hataları rehberine bakın.
- Çevrimdışı tamponlama. Bağlantı yokken MQTT.js publish’leri bellekte kuyruğa alır ve yeniden bağlandığında gönderir. Eskimiş QoS 0 verisinin bunun yerine atılmasını istiyorsanız
queueQoSZero: falseayarlayın.
Kendi broker’ınız için bir başlangıç noktası mı arıyorsunuz? MQTT kod üreteci bu kodu host’unuz, portunuz, kimlik bilgileriniz ve topic’iniz için oluşturur — ardından online MQTT client’ında canlı olarak test edin.
Sıkça sorulan sorular
MQTT.js tarayıcıdan 1883 portuna bağlanabilir mi?
Hayır. Tarayıcılar ham TCP soketi açamaz; bu nedenle tarayıcıdaki MQTT.js, broker’ın WebSocket listener’ını gösteren bir ws:// veya wss:// URL’si kullanmak zorundadır, örneğin wss://broker.hivemq.com:8884/mqtt. Node.js’te mqtt://, mqtts://, ws:// veya wss:// kullanabilirsiniz.
MQTT.js ile async/await nasıl kullanılır?
MQTT.js v5 promise tabanlı metotlar sunar: bağlanmak için mqtt.connectAsync(), dönen client üzerinde ise client.subscribeAsync(), client.publishAsync() ve client.endAsync(). Gelen mesajlar yine message olayı üzerinden iletilir.
React uygulamam neden iki MQTT bağlantısı açıyor?
React StrictMode geliştirme ortamında bileşenleri iki kez mount eder; bu nedenle cleanup içermeyen ve bağlantı kuran bir effect iki client oluşturur. Client’ı useEffect içinde oluşturun ve cleanup fonksiyonunda client.end() çağırın ya da tek bir client’ı bir modülde veya context’te tutun.